AWS Cloud9をsshでインストールする場合に必要なパッケージです。
$ apt-get install nodejs-legacy
下記のコードを$HOME/.bashrcに追加するとコマンドが失敗した場合に、一定時間待って、指定した回数リトライするretry関数を追加できます。
オリジナルは、ここのソースを参考に改良しました。(コメントしようと思いましたが、50以上の評価がないとコメントできませんでした。)
aws cliでリソースを作成した場合、awsコマンドは、リソース作成の終了を待たずに終わってしまいます。リソース作成が終わってから後続の処理をしたい場合に、適切なタイムアウトを設けてリトライするのに便利です。
function retry() { if [ $# -lt 3 ]; then echo 'usage: retry <num retries> <wait retry secs> "<command>"' return 1 fi retries=$1 wait_retry=$2 shift 2 command=$@ for i in `seq 1 $retries`; do echo "$command" $command ret_value=$? [ $ret_value -eq 0 ] && break echo "> failed with $ret_value, $wait_retry sec waiting to retry..." sleep $wait_retry done return $ret_value }
成功する場合
$ retry 5 1 test 0 -eq 0 test 0 -eq 0 $ echo $? 0 $
失敗する場合
$ retry 5 1 test 0 -eq 1 test 0 -eq 1 > failed with 1, 1 sec waiting to retry... test 0 -eq 1 > failed with 1, 1 sec waiting to retry... test 0 -eq 1 > failed with 1, 1 sec waiting to retry... test 0 -eq 1 > failed with 1, 1 sec waiting to retry... test 0 -eq 1 > failed with 1, 1 sec waiting to retry... $ echo $? 1 $
concourse.ioは、日本語情報とても少ないです。 とてもクールなCIツールです。
パイプライン、ジョブ、リソース、タスクといった考え方があり、CI/CDのパイプラインを構築できますが、実装しようと思うと意外と手が止まります。 パイプラインの起点は、S3やgitなどで、Jenkinsのようにとりあえず実行といったことができないからです。
とりあえず実行をするには、タスクを作るのがお勧めです。文書だけでは、うまく伝わらないと思いますが、日常の開発でも地味に便利です。
Javaの開発をしていたとします。対応する必要のあるJDKのバージョンはたくさんあるとします。
従来のビルド環境であれば、複数のバージョンをインストールして環境変数で切り替えるといったことが考えられますが、以外と面倒なことになります。
concourseは、タスクはdockerコンテナで実行されます。 下記のようなタスクを準備してJDK1.6の環境を準備できます。
DockerHubのjavaオフシャルコンテナを使っています。tagの指定を変えれば、好みのバージョンを使うことができます。
$ cat sample.yml --- platform: linux image_resource: type: docker-image source: {repository: java, tag: 6} run: path: sh args: - -exc - | java -version $ fly -t test execute -c sample.yml executing build 41 at http://172.17.0.1:8080/builds/41 initializing running sh -exc java -version + java -version openjdk version "1.8.0_111" OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2~bpo8+1-b14) OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode) succeeded $
任意のパラメータを環境変数で渡すことができます。コンパイルオプションの指定に便利です。
$ cat sample.yml --- platform: linux image_resource: type: docker-image source: {repository: java, tag: 6} params: JAVA_OPTS: -version run: path: sh args: - -exc - | java $JAVA_OPTS $ JAVA_OPTS=-fullversion fly -t test execute -c sample.yml executing build 43 at http://172.17.0.1:8080/builds/43 initializing running sh -exc java $JAVA_OPTS + java -fullversion java full version "1.6.0_38-b38" succeeded $
下記のようなプログラムをコンパイルする場合、ソースコードを渡して、コンパイル結果を受け取る必要があります。
$ cat Hello.java public class Hello { public static void main(String[] args) { System.out.println("Hello, world."); } } $
タスクにファイルを渡すためのinputsとファイルを受け取るためのoutputsを定義します。
$ cat sample.yml --- platform: linux image_resource: type: docker-image source: {repository: java, tag: 6} params: JAVA_OPTS: -version inputs: - name: src outputs: - name: obj run: path: sh args: - -exc - | java $JAVA_OPTS javac src/Hello.java java -cp src Hello cp -p src/Hello.class obj
下記のように実行するとカレントディレクトリのファイルがsrcディレクトリにコピーされてタスク内で使用できるようになります。また、タスク内でobjディレクトリにコピーしたファイルは、/tmp/objで受け取ることができます。
$ fly -t test execute -c sample.yml -i src=. -o obj=/tmp/obj executing build 44 at http://172.17.0.1:8080/builds/44 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1337 0 1337 0 0 1337 0 --:--:-- --:--:-- --:--:-- 435k initializing running sh -exc java $JAVA_OPTS javac src/Hello.java java -cp src Hello cp -p src/Hello.class obj + java -version java version "1.6.0_38" OpenJDK Runtime Environment (IcedTea6 1.13.10) (6b38-1.13.10-1~deb7u1) OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode) + javac src/Hello.java + java -cp src Hello Hello, world. + cp -p src/Hello.class obj % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 455 0 0 0 455 0 455 --:--:-- --:--:-- --:--:-- 45500 succeeded $ ls /tmp/obj Hello.class $
パイプラインは、タスクに定義されたinputsとoutputsをつなぎ合わせることで成果物の受け渡しを行います。非常によく考えられていて便利です。
MacBook ProにmacOS High Sierraのアップグレード通知がきたのでアップグレードしたところ、見事に失敗しました。 1時間ほどアップグレード処理が続いた後にWi-Fiを選択する画面が表示されました。Wi-Fiを選択したところ、しばらくして画面がブラックアウトしたまま、1時間ほど経過...
強制的に再起動すると、ログイン画面が表示されます。 ログインするとプログレスバーが表示されて、また、Wi-Fiの選択画面...
有線LANのアダプタを買ってきてリトライするしかないかな。 クリーンインストールになるかも...
優先LANのアダプターを購入してリトライしたら、15分くらいであっさり終わりました。 有線LAN接続して、起動して、ログインするとプログレスバーが進みます。 その後、iCloudのパスワード入力を求められ、Apple Payを設定(スキップ)したら無事立ち上がりました。
Jenkinsをコマンドラインから操作することでコード化することができます。 Jenkinsをコマンドで操作するには、Jenkins-cliに付属しているjenkins-cli.jarを使います。
最初にjenkins-cli.jarファイルのダウンロードとAPIトークンを作成する必要があります。
Jenkinsの管理-Jenkins CLIメニューを選択します。 jenkins-cli.jarのリンクからjenkins-cli.jarファイルがダウンロードできます。
[
Jenkinsのアカウントから設定メニューを開きます。 APIトークンが作成されていなければ作成します。
下記のようにジョブ一覧を取得できます。 Jenkinsの設定もコードで自動化できます。
e03b5811fd88:/$ export JENKINS_URL=http://localhost:8080 e03b5811fd88:/$ cd e03b5811fd88:~$ java -jar `find . -name jenkins-cli.jar` -http -auth admin:APIトークン list-jobs debug test2 test3 e03b5811fd88:~$
Jenkinsfileをメンテナンスし続ける自信がないので、Jenkinsfileをパイプラインの定義のみで使うようにしました。 定義したパイプラインの各ステップは、Makefileのターゲットに対応させるとメンテナンスし易くなります。
パイプラインは、下記のように定義します。
ステージと同じ名前のターゲットをMakefile
に定義すると、開発するときにmakeコマンドで実行した処理がJenkinsのビルドでも同じように利用されます。
makeコマンドをantやmavenなどに入れ替えれば、他かの開発でも応用が利きます。
ステージ | 処理 |
---|---|
setup | ビルドに必要な環境をセットアップ |
build | ビルド |
test | テストは、単体テストと結合テストを並列で実行 |
deploy | デプロイ |
Jenkinsのパイプラインジョブで実行するとこんな感じになります。
pipeline { agent any environment { branch = 'master' scmUrl = 'git@bitbucket.org:***/***.git' } stages { stage('setup') { steps { sh: 'make setup' } } stage('checkout git') { steps { print "checkout" git credentialsId: credentialId, url: scmUrl } } stage('build') { steps { sh 'make' } } stage ('test') { steps { parallel ( "unit tests": { sh 'make test' }, "integration tests": { sh 'make integration-test' } ) } } stage('deploy'){ steps { sh 'make deploy' } } } }
all: build build: echo build test: echo test integration-test: echo integration-test deploy: echo deploy setup: echo setup
I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOSTに書かれているdocker.for.mac.localhost
で、下記のようにコンテナの中からMacのIPアドレスを引くことができます。
$ nmap -Pn -p 8080 docker.for.mac.localhost Starting Nmap 7.40 ( https://nmap.org ) at 2017-10-15 00:37 JST Nmap scan report for docker.for.mac.localhost (192.168.5.1) Host is up (0.00038s latency). Other addresses for docker.for.mac.localhost (not scanned): PORT STATE SERVICE 8080/tcp open http-proxy Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds $