作業用Bashスクリプトのテンプレート
よく自分で書く作業用Bashスクリプトのテンプレートを残す。
気にかけていることは、
- -e オプションで、エラー時点で処理終了
- エラー時は、$LINENOで、該当行数出力
- -x オプションで、デバッグ
あたりは、必ずできるようにしてる。
余裕がある時は、
- 出力を着色
テンプレート
#!/usr/bin/env bash # template.bash set -e [ -n "$DEBUG" ] && set -x help() { echo "$0 some args" echo "some help" exit 1 } if [ -t 1 ]; then green_color="\e[1;32m" red_color="\e[1;31m" reset="\e[0m" else color="" reset="" fi indent_output() { while read -r data; do printf " ${green_color} | ${reset} %s\n" "$data" done } print_colored() { printf "${green_color}%s${reset}\n" "$1" } err_exit() { printf "${red_color}[ERROR] %s${reset} at line ${LINENO}\n" "$@" exit 1 } for arg; do case "$arg" in --help) help ;; * ) esac done print_colored "Updating some software..." echo -e "hoge\nbar\nfoo" | indent_output err_exit "failed zannen" exit 0
出力は、
デバッグ時は、
DEBUG=1 bash template.bash
とかで、叩くとデバッグできる。
JenkinsをDocker環境にリプレイスする
JenkinsサーバをDockerコンテナとしてリプレイスする手順を示す。
前提
- Jenkinsのバックアップは、ThinBackUpプラグインを使用して取得
- Jenkinsのプラグインは、ThinBackupではバックアップされないので、手動で取得
- Dockerホストは、ローカルのMacOSで、docker-machineを使い稼働
Dockerコンテナとして、Jenkinsを稼働
docker-machine を使いDockerホストを立ち上げる。
ドライバーはVirtualBoxを使う。
$ brew install docker-machine $ docker-machine create --driver virtualbox dev $ docker-machine ssh dev
IPは、後々使うので、メモしておく。
docker@dev:~$ ifconfig eth1 | grep 'inet addr' inet addr:192.168.99.100 Bcast:192.168.99.255 Mask:255.255.255.0
Jenkinsサーバをコンテナとして、起動させる。
この記事が参考になった。
Jenkinsのデータを永続させるためのディレクトリをDockerホストに作成して、起動させる。
$ mkdir /var/lib/jenkins $ docker run -p 8080:8080 -v /var/lib/jenkins/:/var/jenkins_home jenkins
起動できると、http://192.168.99.100:8080 でブラウザからアクセスできる。
確認したら、Ctrl+Cで、抜ける。
Jenkinsのバックアップデータ移行
${JENKINS_HOME} は、jenkinsのホームディレクトリのパスを示す。
コンテナにはいる。
$ docker run -v /var/lib/jenkins/:/var/jenkins_home -it jenkins bash
Jenkinsサーバのバックアップデータの移動手順は、割愛する。
Dockerコンテナにリプレイスする際に、以下のバックアップデータが必要なので、Dockerコンテナの /tmp に配置する。
- ThinBackupプラグインで、作成する FULL-${yyyy}-${mm}-${dd}_${HH}-${MM}のディレクトリ
- ${JENKINS_HOME}/plugins ディレクトリ
データをDockerコンテナ内の ${JENKINS_HOME} に展開する。
$ cp -pr /tmp/FULL-2016-03-08_12-00/* /var/jenkins_home/ $ cp -pr /tmp/plugins /var/jenkins_home/
以上で、データ移行が完了。
ただし、過去のビルド履歴が残っている場合、ビルド時にエラーが出る。
SEVERE: Unexpected executor death java.lang.IllegalStateException: /var/jenkins_home/jobs/test_job/builds/2 already existed;
この場合は、ビルド履歴は削除しておく必要がある。
$ rm -rf /var/jenkins_home/jobs/test_job/builds $ echo '1' > /var/jenkins_home/jobs/test_job/nextBuildNumber
コンテナをCtrl+Cで抜けてから、デーモンとして、Jenkinsを起動させる。
$ docker run -d -p 8080:8080 -v /var/lib/jenkins/:/var/jenkins_home jenkins
以上で、リプレイス完了。
参考
2分でWordPressをセットアップする(Docker編)
Dockerで、WordPressのセットアップが2分でできた。
Apache、MySQL、PHP等のミドルウェアも、Docker コンテナで完結する。
コンテナは、Docker Hub にある、WordPressとMySQLの公式版を使う。
準備
$ docker-machine ssh dev $ cat setup_wp.sh #!/bin/sh docker pull wordpress & docker pull mysql & wait docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d -p 3306:3306 mysql docker run --name my-wordpress --link mysql:mysql -p 80:80 -d wordpress $ chmod 755 setup_wp.sh
スタート
$ time ./setup_wp.sh Using default tag: latest Using default tag: latest latest: Pulling from library/mysql Digest: sha256:7665507aea0785e89e51c193381ec33ec8662d02cd5c995b9f31e432fcaaa541 Status: Downloaded newer image for mysql:latest latest: Pulling from library/wordpress (省略) real 1m 55.88s user 0m 0.35s sys 0m 0.26s
これで、Dockerホストをブラウザで、叩くとWordPress画面が表示される。
2分でおわるとか、すごい。。
ちなみに、wifiモバイルルータで、下りは6Mbpsくらいのときに実施した。
Ansibleで、クライアントPCのファイルの存在チェック
Ansibleを使うとき、クライアント側の実行結果をトリガーにして何かする場合、 local_actionとregisterモジュールを組み合わせれば良い。
クライアントPC側で、あるファイルの存在を確認するためには、statモジュールを使う。
使用例
一般的なAnsibleのディレクトリ構造が以下のようにあり、commonは、
config.ymlをリモートマシンに送るrolesである。
tree . . ├── inventory │ └── hosts ├── roles │ └── common │ ├── files │ │ └── config.yml │ └── tasks │ └── main.yml └── site.yml
roles/common/tasks/main.yml の中身は次のように書いた。
ここでは、config.ymlが存在していれば、ファイルをリモートに転送して、
無ければ、ファイルの転送をスキップするように振り分ける。
# roles/common/tasks/main.yml - name: check config.yml exists in local local_action: stat path="roles/common/files/config.yml" register: file ignore_errors: True - name: copy config.yml to remote copy: src=config.yml dest=~/config.yml when: file.stat.exists
config.ymlがある場合
ansible-playbook -i inventory/hosts site.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [***.***.***.***] TASK [common : check config.yml exists in local] ******************************* ok: [***.***.***.***] TASK [common : copy config.yml to remote] ************************************** changed: [***.***.***.***] PLAY RECAP ********************************************************************* ***.***.***.*** : ok=3 changed=1 unreachable=0 failed=0
config.ymlがない場合
ansible-playbook -i inventory/hosts site.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [***.***.***.***] TASK [common : check config.yml exists in local] ******************************* ok: [***.***.***.***] TASK [common : copy config.yml to remote] ************************************** skipping: [***.***.***.***] PLAY RECAP ********************************************************************* ***.***.***.*** : ok=2 changed=0 unreachable=0 failed=0
Designate の413エラーの対処
OpenStack Designate で、ゾーン登録時に、エラーが出たので対応方法を残しておく。
下記の作業は、designateが置いてあるホストで、行う。
事象
ゾーン登録時に、下記のエラーが出た。
413 Request Entity Too Large
ソースコードを調べると、どうやら、Designateで持っているゾーン登録の閾値に達しているらしい。
ゾーンの上限値は、10。
$ curl http://localhost:9001/v1/quotas/noauth-project { "api_export_size": 1000, "recordset_records": 20, "zone_records": 500, "zone_recordsets": 500, "zones": 10 }
対応
ゾーン登録の上限値を更新する。
designate.confのapiのquotasを有効にしていることを確認する。
$ grep 'quotas' /var/lib/designate/etc/designate/designate.conf enabled_extensions_v1 = diagnostics, quotas, reports, sync, touch enabled_extensions_v2 = quotas, reports
API経由で、上限値を更新する。
$ curl -X PUT -H 'Accept: application/json' -H 'Content-Type: application/json' -d '{"zones": 100}' http://localhost:9001/v1/quotas/noauth-project { "api_export_size": 1000, "recordset_records": 20, "zone_records": 500, "zone_recordsets": 500, "zones": 100 }