Synology DiskStation の DSM 7.x に Entwareをインストールする

# Synology NASへのインストール手順

**公式ページの[GitHubのEntware/Entware](https://github.com/Entware/Entware/wiki/Install-on-Synology-NAS)を直訳して一部を加筆した
注意：最新情報および正確な情報は公式ページを要参照すること**

## イントロダクション
ARMおよびIntelベースのデバイスがサポートされています。DSMのバージョンは3.2以上である必要があります。Marvell Kirkwood mv6282 CPUの場合は`armv5`インストーラを使用し、より新しいARM CPUには`armv7`インストーラを使用してください。`armv7`リポジトリは`cortex-a9`向けの最適化がされていますが、Marvell Armada XPベースのNASでも正常に動作します。Realtek RTD129x CPU（64ビットARM）には`aarch64`インストーラを使用してください。

- Synology DS1618+（DSM 6.2-23739 Update 1）でガイドをテスト済み
- Synology DS920+（DSM 7.0-41890）でガイドをテスト済み 

## 前提条件

- DiskstationにSSHログインできること
- Admin権限を持つユーザーでログインすること
- ファームウェア更新時に `/opt` フォルダが消される可能性あり。その対策として、Entwareの内容を失わないように、rootファイルシステム外にディレクトリを配置し、そのディレクトリに対して `/opt` へのシンボリックリンク作成か、`mount -o bind` を使用してボリュームをマウントすること


## Entwareの構築作業
1. **DiskstationにSSHログインする**

    - 一般ユーザーのインストール作業は失敗する
    - `Admin` 権限を持つユーザーで作業すること
    - 参考資料：[Synology DiskStation で SSH 接続を公開鍵認証方式にする](https://qiita.com/shimizumasaru/items/56474d98e723ea1b5ae3)

1. **rootファイルシステム以外にフォルダを作成する**

   ```bash:
   mkdir -p /volume1/@Entware/opt
   ```

2. **/optを削除し、optwareフォルダをマウントする**

   - `/opt`フォルダが空であることを確認してください（Optwareがインストールされていない状態）。
   - このステップで`/opt`フォルダをその内容ごと削除します。

   ```bash:
   rm -rf /opt
   mkdir /opt
   mount -o bind "/volume1/@Entware/opt" /opt
   ```

   ※`bind`コマンドが動作しない場合、リンクを作成してみてください：

   ```bash:
   ln -s /volume1/@Entware/opt/ /opt
   ```

3. **プロセッサに応じてインストールスクリプトを実行する**  
   （`uname -m`コマンドでプロセッサを確認）

   - **armv8（aarch64） - Realtek RTD129xの場合**

     ```bash:
     wget -O - https://bin.entware.net/aarch64-k3.10/installer/generic.sh | /bin/sh
     ```

   - **armv5の場合**

     ```bash:
     wget -O - https://bin.entware.net/armv5sf-k3.2/installer/generic.sh | /bin/sh
     ```

   - **armv7の場合**

     ```bash:
     wget -O - https://bin.entware.net/armv7sf-k3.2/installer/generic.sh | /bin/sh
     ```

   - **x64の場合**

     ```bash:
     wget -O - https://bin.entware.net/x64-k3.2/installer/generic.sh | /bin/sh
     ```

4. **自動起動タスクを作成する**

   - タスクスケジューラにトリガーされたユーザー定義タスクを作成します。

   **手順：DSM > コントロールパネル > タスクスケジューラ**  
   **新規作成 > トリガーされたタスク > ユーザー定義スクリプト**

   **設定内容：**  
   - **全般**
     - **タスク：** Entware（任意の内容）
     - **ユーザー：** root
     - **イベント：** ブートアップ
     - **プリタスク：** なし
    - **タスク設定**  
      - **コマンドを実行**
        - **ユーザー指定のスクリプト** に以下の内容をコピペ
            ```bash
             #!/bin/sh
    
             # Entwareのマウントと起動
             mkdir -p /opt
             mount -o bind "/volume1/@Entware/opt" /opt
             /opt/etc/init.d/rc.unslung start

             # グローバルプロファイルにEntwareのプロファイルを追加
             if grep  -qF  '/opt/etc/profile' /etc/profile; then
                 echo "確認済み：Entwareプロファイルがグローバルプロファイルに含まれています"
             else
                 echo "追加：Entwareプロファイルをグローバルプロファイルに追加します"
                 cat >> /etc/profile <<"EOF"

                 # Entwareプロファイルの読み込み
                 [ -r "/opt/etc/profile" ] && . /opt/etc/profile
                 EOF
             fi

             # Entwareリストの更新
             /opt/bin/opkg update
             ```

5. **NASを再起動する**

## Tips

- Entwareが読み込まれた後に開始するタスクを作成する。この例は、Entwareが読み込まれた後で、GUESTユーザーとしてiperf3コマンドでポート5201のサーバーとクライアント間のネットワーク帯域幅を測定している。

  **作成 > トリガーされたタスク > ユーザー指定のスクリプト**  
  **設定内容：**  
  - **全般**
    - **タスク：** Entware - iperf3 Server（任意の内容）
    - **ユーザー：** root
    - **イベント：** ブートアップ
    - **プリタスク：** Entware（任意のタスク名）
  - **タスク設定**  
    - **コマンドを実行**
        - **ユーザー指定のスクリプト** に以下の内容をコピペ
        ```bash
        # GUESTユーザーとしてiperf3コマンドでポート5201のサーバーとクライアント間のネットワーク帯域幅を測定
        sudo -H -u guest bash -c 'echo "I am $USER, with uid $UID"; /opt/bin/iperf3 -s -D -p 5201'
         ```

## opkg ヘルプ
```
$ opkg --help

opkgにはサブコマンドが必ず一つ必要

使用方法: opkg [オプション...] サブコマンド [引数...]  

サブコマンド：いずれか1つを指定する

パッケージ操作：
        update                                 利用可能なパッケージリストを更新
        upgrade <pkgs>                         パッケージをアップグレード
        install <pkgs>                         パッケージをインストール
        configure <pkgs>                       展開済みのパッケージを設定
        remove <pkgs|regexp>                   パッケージを削除
        flag <flag> <pkgs>                     パッケージにフラグを設定、<flag> = hold|noprune|user|ok|installed|unpacked (各呼び出しにつき1つ)

インフォメーション：
        list                                   利用可能なパッケージを一覧表示
        list-installed                         インストール済みパッケージを一覧表示
        list-upgradable                        アップグレード可能なインストール済みパッケージを一覧表示 
        list-changed-conffiles                 ユーザーが変更した設定ファイルを一覧表示
        files <pkg>                            指定パッケージに属するファイルを一覧表示
        search <file|regexp>                   指定ファイルを提供するパッケージを一覧表示
        find <regexp>                          名前または説明に一致するパッケージを一覧表示
        info [pkg|regexp]                      指定パッケージに関するすべての情報を表示
        status [pkg|regexp]                    指定パッケージの状態を表示
        download <pkg>                         指定パッケージを現在のディレクトリにダウンロード
        compare-versions <v1> <op> <v2>        バージョンを比較（<op>には<=, <, >, >=, =, <<, >>のいずれか）
        print-architecture                     インストール可能なパッケージのアーキテクチャを表示
        depends [-A] [pkgname|pat]+            指定パッケージの依存関係を表示
        whatdepends [-A] [pkgname|pat]+        指定パッケージに依存するものを表示
        whatdependsrec [-A] [pkgname|pat]+     指定パッケージに再帰的に依存するものを表示
        whatrecommends [-A] [pkgname|pat]+     指定パッケージが推奨するものを表示
        whatsuggests [-A] [pkgname|pat]+       指定パッケージが推奨するものを表示
        whatprovides [-A] [pkgname|pat]+       指定パッケージが提供するものを表示
        whatconflicts [-A] [pkgname|pat]+      指定パッケージと競合するものを表示
        whatreplaces [-A] [pkgname|pat]+       指定パッケージを置き換えるものを表示

オプション：
        -A                                     インストール済みパッケージに限らずすべてのパッケージを検索
        -V[<level>]                            詳細レベルを<level>に設定
        --verbosity[=<level>]                  詳細レベルの設定：
                                                  0 エラーのみ
                                                  1 通常メッセージ（デフォルト）
                                                  2 情報メッセージ
                                                  3 デバッグ
                                                  4 デバッグレベル2
        -f <conf_file>                         <conf_file>をopkgの設定ファイルとして使用
        --conf <conf_file>                     設定ファイルを指定
        --cache <directory>                    パッケージキャッシュを使用
        -d <dest_name>                         <dest_name>をルートディレクトリとして使用
        --dest <dest_name>                     パッケージのインストール、削除、アップグレードに使用するルートディレクトリ、<dest_name> は設定ファイルで定義された名前である必要があります（ただしディレクトリ名を直接指定しても可）
        -o <dir>                               <dir>をオフラインインストールのルートディレクトリとして使用
        --offline-root <dir>                   オフラインインストールのためのルートディレクトリとして使用
        --verify-program <path>                指定プログラムでusign署名を検証
        --add-arch <arch>:<prio>               優先度<prio>でアーキテクチャを登録
        --add-dest <name>:<path>               指定パスで目的地を登録

強制オプション：
        --force-depends                        依存関係の問題があってもインストール・削除を実行
        --force-maintainer                     既存の設定ファイルを上書き
        --force-reinstall                      パッケージを再インストール
        --force-overwrite                      他のパッケージのファイルを上書き
        --force-downgrade                      パッケージのダウングレードを許可
        --force-space                          空き容量のチェックを無効化
        --force-postinstall                    オフラインモードでもpostinstallスクリプトを実行
        --force-remove                         prermスクリプトが失敗してもパッケージを削除
        --force-checksum                       チェックサム不一致があっても失敗しない
        --no-check-certificate                 SSL証明書を検証しない
        --noaction                             実行せずにテストのみ行う
        --download-only                        ダウンロードのみ実行
        --nodeps                               依存関係を無視
        --nocase                               大文字小文字を区別しないパターンマッチングを実行
        --size                                 利用可能なパッケージの一覧表示時にパッケージサイズを表示
        --strip-abi                            ABIバージョンを除いたパッケージ名を表示
        --force-removal-of-dependent-packages  パッケージとすべての依存関係を削除
        --autoremove                           依存関係を満たすために自動的にインストールされたパッケージを削除
        -t                                     一時ディレクトリを指定
        --tmp-dir                              一時ディレクトリを指定
        -l                                     リストディレクトリを指定
        --lists-dir                            リストディレクトリを指定

正規表現は「pkgname*」や「*file*」のような形式で記述する
参考例:
        opkg info 'libstd*'
        opkg search '*libop*'
        opkg remove 'libncur*'
        
```


以上