11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TUNA-JPAdvent Calendar 2023

Day 5

Tanzu CLI の Plugin を作成してみる。

Last updated at Posted at 2023-12-04

この記事は、「TUNA-JP Advent Calendar 2023」の5日目のエントリです。

突然ですが、Tanzu CLI の Plugin を作成して Tuna とじゃんけんなどしてみます。

手順は、下記を参考に進めます。

今回の環境

VMware Photon OS 5.0 を利用します。

# cat /etc/photon-release
VMware Photon OS 5.0
PHOTON_BUILD_NUMBER=dde71ec57

1. 開発環境の準備

OS の RPM パッケージを最新化して、再起動しておきます。

# tdnf update -y
# reboot

ビルドで必要になる RPM をインストールしておきます。

# tdnf install tar git make go glibc-devel binutils linux-api-headers -y

Docker のサービスを起動しておきます。これは、プラグインの Publish 処理のあたりで必要になります。

# systemctl start docker
# systemctl enable docker

2. OS ユーザの作成(オプション)

作業用のユーザ(demo)を作成します。ちなみに、root ユーザのまま作業しても問題ありません。

# useradd -m demo
# passwd demo
# usermod -aG docker demo

作成したユーザにスイッチします。

# su - demo
$

vim のエディタ設定を調整しておきます。

$ echo 'set clipboard=unnamed,autoselect' >> ~/.vimrc

3. Tanzu CLIのインストール

Tanzu CLI のバイナリ ファイルをダウンロードします。

$ curl -OL https://github.com/vmware-tanzu/tanzu-cli/releases/download/v1.1.0/tanzu-cli-linux-amd64.tar.gz

ファイルを展開します。

$ tar zxvf tanzu-cli-linux-amd64.tar.gz
v1.1.0/
v1.1.0/tanzu-cli-linux_amd64

ホーム ディレクトリ配下に、コマンドを格納するディレクトリ(~/bin)を作成しておきます。

$ mkdir ~/bin
$ export PATH=~/bin:$PATH

Tanzu CLI をインストールします。

$ install v1.1.0/tanzu-cli-linux_amd64 ~/bin/tanzu

tanzu コマンドが実行できるようになったことを確認します。

$ tanzu version
version: v1.1.0
buildDate: 2023-11-01
sha: d0679f5a
arch: amd64

PATH 環境変数と、tanzu コマンドの Bash 補完機能の設定を、.bash_profile ファイルに追記して永続化します。

$ echo 'export PATH=~/bin:$PATH' >> ~/.bash_profile
$ echo 'source <(tanzu completion bash)' >> ~/.bash_profile

.bash_profile を読み込むために、作業用ユーザで再ログインしておきます。

$ exit
# su - demo

tanzu plugin list コマンドを実行して、まだ Plugin がインストールされていないことを確認しておきます。
初回のみ、下記のように EULA と CEIP の応答(下記の★あたり)を求められます。順に次のように回答しています。

  • VMware General Terms(EULA)の承諾 → Yes
  • CEIP:Customer Experience Improvement Program → No
$ tanzu plugin list
? You must agree to the VMware General Terms in order to download, install, or
use software from this registry via Tanzu CLI. Acceptance of the VMware General
Terms covers all software installed via the Tanzu CLI during any Session.
“Session” means the period from acceptance until any of the following occurs:
(1) a change to VMware General Terms, (2) a new major release of the Tanzu CLI
is installed, (3) software is accessed in a separate software distribution
registry, or (4) re-acceptance of the General Terms is prompted by VMware.

To view the VMware General Terms, please see https://www.vmware.com/vmware-general-terms.html.

If you agree, the essential plugins (required by the tanzu cli) will be automatically installed.

Note: this prompt can be avoided by running "tanzu config eula accept".

Do you agree to the VMware General Terms?
 Yes★

==
? VMware's Customer Experience Improvement Program ("CEIP") provides VMware with
information that enables VMware to improve its products and services and fix
problems. By choosing to participate in CEIP, you agree that VMware may collect
technical information about your use of VMware products and services on a
regular basis. This information does not personally identify you.

For more details about the program, please see https://www.vmware.com/trustvmware/ceip.html.

Note: this prompt can be avoided by setting the environment variable
TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER to "yes" or "no".

Do you agree to participate in the Customer Experience Improvement Program?
 No★

==
Standalone Plugins
  NAME  DESCRIPTION  TARGET  VERSION  STATUS

4. Builder Plugin のインストール

builder Plugin をインストールします。

$ tanzu plugin install builder
[i] The tanzu cli essential plugins have not been installed and are being installed now. The install may take a few seconds.
[i] Installing plugins from plugin group 'vmware-tanzucli/essentials:v1.0.0'
[i] Installing plugin 'telemetry:v1.1.0' with target 'global'

[i] Installing plugin 'builder:v1.1.0' with target 'global'
[ok] successfully installed 'builder' plugin

5. Plugin の作成

まず Plugin の雛形を作成して、Go 言語で Cobra による CLI コマンドを追加します。

5-1. Plugin の雛形の作成

Plugin 開発のための Git リポジトリを作成します。
コマンド実行後、GitHub / GitLab どちらかの形式を選択します。
今回は GitHub を選択しています。(★のところにて)

$ tanzu builder init tanzu-cli-tunajp
[i] The tanzu cli essential plugins have not been installed and are being installed now. The install may take a few seconds.
[i] Installing plugins from plugin group 'vmware-tanzucli/essentials:v1.0.0'
[i] Installing plugin 'telemetry:v1.1.0' with target 'global'

? choose a repository type GitHub★
2023-12-04T10:45:07Z [ok] successfully created repository

作成されたディレクトリに移動します。

$ cd tanzu-cli-tunajp/

下記のようにファイルが作成されています。

$ ls
CODEOWNERS  common.mk  go.mod  Makefile  plugin-tooling.mk  README.md

tuna-jp という Plugin を作成します。tanzu builder cli add-plugin コマンドを実行すると、今回は「tuna-jp plugin.」と入力します。

$ tanzu builder cli add-plugin tuna-jp
? provide a description tuna-jp plugin.
2023-12-04T10:47:49Z [ok] successfully created plugin

下記のように、Plugin のテンプレートになるファイル一式が作成されます。

$ ls cmd/plugin/tuna-jp/
main.go  README.md  test

ここから git commit しながら進めるので、Git のユーザ情報を設定しておきます。

$ git config user.name "ユーザ名"
$ git config user.email "メールアドレス"

初期状態のファイル一式を Commit しておきます。

$ git add -A
$ git commit -m "Initialize plugin repository"

作成する Plugin のバージョンを、git tag で付与します。

$ git tag v0.0.1

make を実行します。

$ export GOPATH=~/go
$ make gomod

make に成功した時点で、また Commit を実行してきます。

$ git add -A
$ git commit -m "Configure go.mod and go.sum"

5-2. CLI コマンドの追加

main.go ファイルを編集します。

$ vi cmd/plugin/tuna-jp/main.go

下記のように Go 言語で Plugin を開発します。

main.go
package main

import (
        "fmt"
        "github.com/spf13/cobra"
        "github.com/vmware-tanzu/tanzu-plugin-runtime/config/types"
        "github.com/vmware-tanzu/tanzu-plugin-runtime/log"
        "github.com/vmware-tanzu/tanzu-plugin-runtime/plugin"
        "github.com/vmware-tanzu/tanzu-plugin-runtime/plugin/buildinfo"
        "math/rand"
        "os"
        "time"
)

var descriptor = plugin.PluginDescriptor{
        Name:        "tuna-jp",
        Description: "tuna-jp plugin.",
        Target:      types.TargetGlobal, // <<<FIXME! set the Target of the plugin to one of {TargetGlobal,TargetK8s,TargetTMC}
        Version:     buildinfo.Version,
        BuildSHA:    buildinfo.SHA,
        Group:       plugin.ManageCmdGroup, // set group
}

func main() {
        p, err := plugin.NewPlugin(&descriptor)
        if err != nil {
                log.Fatal(err, "")
        }

        // 新しいCobraコマンドを作成
        var tunaCmd = &cobra.Command{
                Use:   "get",
                Short: "Prints TUNA-JP Message",
                Long:  `Prints TUNA-JP Message to the standard output.`,
                Run: func(cmd *cobra.Command, args []string) {
                        fmt.Println("TUNA-JP Advent Calendar 2023")
                },
        }

        // janken コマンドの作成
        var jankenCmd = &cobra.Command{
                Use:   "janken",
                Short: "Play janken.",
                Long:  `Play janken. Use --hand with one of 'o', 'v', 'w'.`,
        }

        var hand string
        jankenCmd.Flags().StringVarP(&hand, "hand", "", "", "Your hand (o: rock, v: scissors, w: paper)")

        jankenCmd.Run = func(cmd *cobra.Command, args []string) {
                if hand != "o" && hand != "v" && hand != "w" {
                        fmt.Println("Invalid hand. Please use one of 'o', 'v', 'w'.")
                        return
                }

                // ランダムな手を生成
                rand.Seed(time.Now().UnixNano())
                opponent := []string{"o", "v", "w"}[rand.Intn(3)]

                // 結果を出力
                fmt.Printf("Your hand: %s, Tuna's fin: %s\n", hand, opponent)
        }

        // コマンドをプラグインに追加
        p.AddCommands(
                tunaCmd,
                jankenCmd,
        )
        if err := p.Execute(); err != nil {
                os.Exit(1)
        }
}

5-3. Plugin のローカル ビルド

作成した Plugin をビルドしてみます。ここでは、作業マシンのアーキテクチャ(linux/amd64)のバイナリのみが生成されます。

$ make plugin-build-local
(省略)
2023-12-04T11:08:01Z [i] ========
2023-12-04T11:08:01Z [i] saving plugin manifest...
2023-12-04T11:08:01Z [ok] successfully built local repository

下記のように、Plugin のバイナリ ファイルが作成されます。

$ ls -l artifacts/plugins/linux/amd64/global/tuna-jp/v0.0.1/
total 6132
-rwxr-x--- 1 root root 6271655 Dec  4 11:08 tanzu-tuna-jp-linux_amd64
drwxr-x--- 2 root root    4096 Dec  4 11:08 test

6. Plugin の動作確認

作成した Plugin が利用できるか確認してみます。

6-1. Plugin をインストールしてみます。

$ tanzu plugin install all --local-source ./artifacts/plugins/linux/amd64
[i] Installing plugin 'tuna-jp:v0.0.1' with target 'global'
[ok] successfully installed all plugins

6-2. Plugin に含まれるコマンドの実行

tanzu tuna-jp get コマンドを実行すると、「TUNA-JP」と表示されるはずです。

# tanzu tuna-jp get
TUNA-JP Advent Calendar 2023

help を表示してみます。

# tanzu tuna-jp janken -h
Play janken. Use --hand with one of 'o', 'v', 'w'.

Usage:
  tanzu tuna-jp janken [flags]

Flags:
      --hand string   Your hand (o: rock, v: scissors, w: paper)
  -h, --help          help for janken

TUNA とじゃんけんでもして平和な気持ちになってください。

$ tanzu tuna-jp janken --hand o
Your hand: o, Tuna's fin: w
$ tanzu tuna-jp janken --hand v
Your hand: v, Tuna's fin: w
$ tanzu tuna-jp janken --hand w
Your hand: w, Tuna's fin: o

6-3. Plugin のアンインストール

Plugin は、下記のようにアンインストールできます。

# tanzu plugin uninstall tuna-jp -y
[i] Uninstalling plugin 'tuna-jp' for target 'global'
[ok] successfully uninstalled plugin 'tuna-jp'

7. プラグインのビルドとパブリッシュ

下記のコマンドを実行すると、開発環境のアーキテクチャ以外のパッケージもビルドできて、ローカルの Docker にコンテナとしてプッシュされます。

$ export GOPATH=~/go
$ make plugin-build
$ make plugin-publish-packages

ファイルは下記のように生成されます。

$ ls artifacts/packages/*/*/global/tuna-jp/v0.0.1/*
artifacts/packages/darwin/amd64/global/tuna-jp/v0.0.1/tuna-jp-darwin_amd64.tar
artifacts/packages/darwin/arm64/global/tuna-jp/v0.0.1/tuna-jp-darwin_arm64.tar
artifacts/packages/linux/amd64/global/tuna-jp/v0.0.1/tuna-jp-linux_amd64.tar
artifacts/packages/linux/arm64/global/tuna-jp/v0.0.1/tuna-jp-linux_arm64.tar
artifacts/packages/windows/amd64/global/tuna-jp/v0.0.1/tuna-jp-windows_amd64.tar
$ ls artifacts/plugins/*/*/global/tuna-jp/v0.0.1/*
artifacts/plugins/darwin/amd64/global/tuna-jp/v0.0.1/tanzu-tuna-jp-darwin_amd64
artifacts/plugins/darwin/arm64/global/tuna-jp/v0.0.1/tanzu-tuna-jp-darwin_arm64
artifacts/plugins/linux/amd64/global/tuna-jp/v0.0.1/tanzu-tuna-jp-linux_amd64
artifacts/plugins/linux/arm64/global/tuna-jp/v0.0.1/tanzu-tuna-jp-linux_arm64
artifacts/plugins/windows/amd64/global/tuna-jp/v0.0.1/tanzu-tuna-jp-windows_amd64.exe

artifacts/plugins/darwin/amd64/global/tuna-jp/v0.0.1/test:
tanzu-tuna-jp-test-darwin_amd64

artifacts/plugins/darwin/arm64/global/tuna-jp/v0.0.1/test:
tanzu-tuna-jp-test-darwin_arm64

artifacts/plugins/linux/amd64/global/tuna-jp/v0.0.1/test:
tanzu-tuna-jp-test-linux_amd64

artifacts/plugins/linux/arm64/global/tuna-jp/v0.0.1/test:
tanzu-tuna-jp-test-linux_arm64

artifacts/plugins/windows/amd64/global/tuna-jp/v0.0.1/test:
tanzu-tuna-jp-test-windows_amd64.exe

コンテナ レジストリに登録したリポジトリからのインストールはまだ謎なので、いずれ読み解ければ・・・

おまけ:とりあえず試してみる

$ curl -OL https://github.com/vmware-tanzu/tanzu-cli/releases/download/v1.1.0/tanzu-cli-linux-amd64.tar.gz
$ tar zxf tanzu-cli-linux-amd64.tar.gz
$ mkdir ~/bin
$ export PATH=~/bin:$PATH
$ install v1.1.0/tanzu-cli-linux_amd64 ~/bin/tanzu
$ curl -OL https://github.com/gowatana/tanzu-cli-tunajp/releases/download/v0.0.1/plugin_bundle.tar.gz
$ mkdir tuna-jp
$ tar zxf plugin_bundle.tar.gz -C tuna-jp
$ tanzu config eula accept
$ export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER=no
$ tanzu plugin install all --local-source tuna-jp/linux/amd64
$ tanzu tuna-jp get
$ tanzu tuna-jp janken --hand

以上、Tanzu CLI の Plugin を作成してみる話でした。

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?