AWS IoT GreengrassのOTA更新をやってみた

いきなりですがまとめです。

* OTA更新は`/greengrass/ggc/core/greengrassd`ではなく`/greengrass/ota/ota_agent/ggc-ota`が起動している必要がある
* 更新モジュールはS3からとってきている
* マネジメントコンソールで`Greengrass Core 更新ジョブ`を作成する（APIも存在する）
* `Greengrass Core ソフトウェア`だけでなく`Greengrass Core OTA エージェント`の更新も可能（別々に実施する必要がある）
* ジョブ作成後、即座に反映される
* 更新の前後に自前のスクリプトを実施させることが可能。  
更新前に`systemctl stop`して、更新後に`systemctl start`するんだと思う。  
ただし、OTAエージェントの更新前にstopすると、OTAエージェントの更新が途中で止まってしまったので、こっちは何もしなくて良さそう。
* 2020/6/6に試したところ、OTA エージェントのバージョンを更新すると、ダウングレードする気がする

# 検証内容

## 環境

Docker上で検証（Docker Desktop 2.2.0.4 on Mac）

Greengrass（更新前）　v1.10.0
OTAエージェント　v1.2.0

## Docker関連

```:Docerfile
FROM amazon/aws-iot-greengrass:1.10.0-amazonlinux

RUN yum install -y procps sysvinit-tools wget
```

OTA更新時に必要なものがあるので、追加インストールします。

```yaml:docker-compose.yml
version: '3'
services: 
  greengrass:
    build:
      context: .
      dockerfile: Dockerfile
    volumes: 
      - ./greengrass/certs:/greengrass/certs
      - ./greengrass/config:/greengrass/config
      - ./greengrass/deployment:/greengrass/ggc/deployment
      - ./greengrass/log:/greengrass/ggc/var/log
      - ./greengrass/usr:/greengrass/usr
      - ./greengrass/var/log/greengrass:/var/log/greengrass
      - ./workspace:/workspace
    restart: always
    privileged: true
    command: /sbin/init
    environment: 
      TZ: Asia/Tokyo
    tty: true
```

volumesで`certs`と`config`をマウント。その他はログを見たりするためにマウントしました。

OTAエージェントのログは、Greengrass Coreのログとは別に`/var/log/greengrass`に出力されます。（Greengrass Coreのログは`/greengrass/ggc/var/log`）

systemdを使用したいので`privileged: true`と`command: /sbin/init`を追加しました。

## systemd関連

```:greengrass.service
[Unit]
Description=Greengrass Daemon

[Service]
Type=forking
PIDFile=/var/run/greengrassd.pid
Restart=on-failure
ExecStart=/greengrass/ggc/core/greengrassd start
ExecReload=/greengrass/ggc/core/greengrassd restart
ExecStop=/greengrass/ggc/core/greengrassd stop

[Install]
WantedBy=multi-user.target
```

```:greengrass_ota.service
[Unit]
Description=Greengrass OTA Agent

[Service]
Type=forking
PIDFile=/var/run/ggc-ota.pid
Restart=on-failure
KillMode=mixed
ExecStart=/greengrass/ota/ota_agent/ggc-ota
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
[Install]
WantedBy=multi-user.target
```

```bash
bash-4.2# systemctl enable greengrass.service
bash-4.2# systemctl enable greengrass_ota.service

bash-4.2# systemctl start greengrass.service
bash-4.2# systemctl start greengrass_ota.service
```

## Greengrass設定

```json:config.json
{

   "coreThing": {                                                     
       …
   },
   "runtime": {                                                       
        …
   },
   "managedRespawn": true                                            

}
```

```shell:/greengrass/usr/scripts/ggc_pre_update.sh
systemctl stop greengrass.service
```

```/greengrass/usr/scripts/ggc_post_update.sh
systemctl start greengrass.service
```

`ota_pre_update.sh`と`ota_post_update.sh`も配置できるので、同様にstopしてみたのですが、OTAエージェントの更新が途中で止まってしまいました。OTAエージェントは事前のstopも事後のstartも不要な感じです。


## 検証

### OTA更新前の状態

```console
bash-4.2# ls -l /greengrass/ggc/packages/
total 4
drwxr-xr-x 1 root root 4096 Jun  6 21:13 1.10.0

bash-4.2# ls -l /greengrass/ota/
total 4
lrwxrwxrwx 1 root root   16 Nov 26  2019 ota_agent -> ota_agent_v1.2.0
drwxr-xr-x 1 root root 4096 Jun  6 21:13 ota_agent_v1.2.0

bash-4.2# 
```

### OTA更新後の状態

```console
bash-4.2# ls -l /greengrass/ggc/packages/
total 4
drwxr-xr-x 8 root root 4096 Jun  6 21:57 1.10.1_1

bash-4.2# ls -l /greengrass/ota/
total 4
lrwxrwxrwx 1 root root   21 Jun  6 21:55 ota_agent -> ./ota_agent_v1.0.0_1/
drwxr-xr-x 4 root root 4096 Jun  6 21:55 ota_agent_v1.0.0_1

bash-4.2# 
```

OTAエージェントがバージョンダウンしてるよね？


## 参考にしたサイト
　https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/core-ota-update.html
　https://qiita.com/mikene_koko/items/4c71c969f55e3fe24190
　https://qiita.com/snaka/items/48c0998ffa1e34975a6f
　https://qiita.com/a_yasui/items/f2d8b57aa616e523ede4