CloudStackでバージョンを１つ飛ばしたバージョンアップを行う時の注意点

本エントリは[CloudStack Advent Calendar 2015](http://www.adventar.org/calendars/970)の12/2担当分のエントリです。

本エントリでは、4.4.1から4.6などメジャーバージョンを１つ以上飛ばしたバージョンアップを行う際の注意点について記述します。

##CloudStackのバージョンアップ方法##
バージョンやハイパーバイザ等によってこれら以外の手順が必要になることもありますが、
概ね以下の手順となります。
1.新しいバージョンのSystemVMテンプレートをダウンロードする。
2.Management Serverを停止する
3.DBのバックアップを取得する
4.パッケージをアップデートする
5.Management Serverを起動する
6.SystemVM・仮想ルータを再作成する

詳細な手順については[リリースノート](http://docs.cloudstack.apache.org/projects/cloudstack-release-notes/en/4.6.0/)を参照してください。
特に「3.DBのバックアップを取得する」は必ず実施しておきましょう。
バージョンアップに失敗した際には、多くの場合DBのリストアが行うことになります。
バックアップを取得していないと、環境全体の初期化が必要になることもあります。

##4.4.2以前から4.6以降へのバージョンアップ##
バージョンを１つ飛ばす際に気を付けなければいけないのは、「1.新しいバージョンのSystemVMテンプレートをダウンロードする。」を行う際に
最新のバージョンのSystemVM Templateだけではなく中間のバージョンのSystemVMテンプレートもダウンロードする必要がある点です。[(参照元)](http://docs.cloudstack.apache.org/projects/cloudstack-release-notes/en/4.6.0/upgrade/upgrade-4.4.html#update-system-vm-templates)

これは、Apache CloudStack 4.5からバージョンアップの際にSystemVM Templateが存在するかどうかをチェックする仕組みが入ったことに影響されています。

##なぜこうなるのか##
Apache CloudStackではバージョンの情報をDBに格納しています。

```
mysql> select * from version;
+----+---------+---------------------+----------+
| id | version | updated             | step     |
+----+---------+---------------------+----------+
|  1 | 4.0.0   | 2015-04-09 17:39:14 | Complete |
|  2 | 4.1.0   | 2015-04-09 08:41:48 | Complete |
|  3 | 4.2.0   | 2015-04-09 08:41:48 | Complete |
|  4 | 4.2.1   | 2015-04-09 08:41:48 | Complete |
|  5 | 4.3.0   | 2015-04-15 12:10:28 | Complete |
|  6 | 4.3.1   | 2015-04-15 12:10:28 | Complete |
|  7 | 4.4.0   | 2015-11-20 05:16:44 | Complete |
|  8 | 4.4.1   | 2015-11-20 05:16:44 | Complete |
|  9 | 4.4.2   | 2015-11-20 05:16:44 | Complete |
| 10 | 4.5.0   | 2015-11-20 05:16:44 | Complete |
| 11 | 4.5.1   | 2015-11-20 05:16:44 | Complete |
| 12 | 4.5.2   | 2015-11-20 05:16:44 | Complete |
| 13 | 4.6.0   | 2015-11-20 05:16:44 | Complete |
+----+---------+---------------------+----------+
13 rows in set (0.00 sec)
```

Management Serverを起動した際にこの情報を参照しバージョンアップのシーケンスが開始されますが、
内部的には4.4.0から4.4.1などのマイナーバージョンも含めて一つ一つ行われています。
このため、4.5のSystemVMテンプレートを用意していない=4.5のバージョンアップに失敗、となってしまい、
以降のバージョンアップシーケンスが行われず、失敗となってしまいます。

ちなみに中間のバージョンのSystemVMテンプレートをダウンロードしていない場合、バージョンアップに失敗し、DBのリストアが必要になります。
この時、management-server.logには以下のようなログが出力されます。

```
2015-11-20 13:36:43,735 ERROR [c.c.u.DatabaseUpgradeChecker] (main:null) Unable to upgrade the database
com.cloud.utils.exception.CloudRuntimeException: 4.5.0 XenServer SystemVm template not found. Cannot upgrade system Vms
        at com.cloud.upgrade.dao.Upgrade442to450.updateSystemVmTemplates(Upgrade442to450.java:274)
        at com.cloud.upgrade.dao.Upgrade442to450.performDataMigration(Upgrade442to450.java:71)
        at com.cloud.upgrade.DatabaseUpgradeChecker.upgrade(DatabaseUpgradeChecker.java:345)
        at com.cloud.upgrade.DatabaseUpgradeChecker.check(DatabaseUpgradeChecker.java:468)
        at org.apache.cloudstack.spring.lifecycle.CloudStackExtendedLifeCycle.checkIntegrity(CloudStackExtendedLifeCycle.java:65)
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:143)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet.loadContext(DefaultModuleDefinitionSet.java:145)
        at org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet$2.with(DefaultModuleDefinitionSet.java:122)
        at org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet.withModule(DefaultModuleDefinitionSet.java:245)
        at org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet.withModule(DefaultModuleDefinitionSet.java:250)
        at org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet.withModule(DefaultModuleDefinitionSet.java:233)
        at org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet.loadContexts(DefaultModuleDefinitionSet.java:117)
        at org.apache.cloudstack.spring.module.model.impl.DefaultModuleDefinitionSet.load(DefaultModuleDefinitionSet.java:79)
        at org.apache.cloudstack.spring.module.factory.ModuleBasedContextFactory.loadModules(ModuleBasedContextFactory.java:37)
        at org.apache.cloudstack.spring.module.factory.CloudStackSpringContext.init(CloudStackSpringContext.java:70)
        at org.apache.cloudstack.spring.module.factory.CloudStackSpringContext.<init>(CloudStackSpringContext.java:57)
        at org.apache.cloudstack.spring.module.factory.CloudStackSpringContext.<init>(CloudStackSpringContext.java:61)
        at org.apache.cloudstack.spring.module.web.CloudStackContextLoaderListener.contextInitialized(CloudStackContextLoaderListener.java:52)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4210)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4709)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:526)
        at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1041)
        at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:964)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:502)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1277)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:321)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:722)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
        at org.apache.catalina.core.StandardService.start(StandardService.java:516)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:593)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
```

##まとめ##
- DBのバックアップは必ず取得しておこう
- リリースノートは必ずチェックしておこう

最後までご覧頂きありがとうございました。
明日のエントリは@smzkstsさんになります。 
[CloudStack Advent Calendar 2015](http://www.adventar.org/calendars/970)