flyコマンド
ログイン
認証をかけている場合、まずログインしないとfly targets以外の操作ができません。
$ fly -t test login
username: foo
password:
target saved
flyコマンドのバージョンアップ
sync
コマンドで、ターゲットとして指定されているConcourseと同じバージョンの flyコマンドにアップグレードしてくれます。
$ fly -t test sync
targeting http://example-elb-177699448.ap-northeast-1.elb.amazonaws.com
downloading fly from http://example-elb-177699448.ap-northeast-1.elb.amazonaws.com... update successful!
なお、fly login
したときに、ログインしたConcourseとローカルのflyコマンドのバージョンが異なる場合、以下のように警告してくれます。親切。
$ fly -t $TARGET login -c $URL
WARNING:
fly version (1.1.0) is out of sync with the target (1.2.0). to sync up, run the following:
fly -t test sync
ワーカー一覧
ConcourseにはLinux、Mac、Windowsまたその他任意のタグ付をした様々なワーカーを追加することができます。
以下の例だと、platform: linux
なタスクを実行できるワーカーが2ついることになります。
$ fly -t test workers
targeting http://example-elb-177699448.ap-northeast-1.elb.amazonaws.com
name containers platform tags
ip-10-2-3-84 1 linux none
ip-10-2-3-85 1 linux none
一時タスクの実行
Concourse的にはone-offビルドといいます。
ローカルの設定ファイルに定義したタスク(パイプライン→ジョブ→プラン→タスクという親子関係がありますが、その一番最下層にいる「タスク」)をConcourse上で実行します。
ローカルファイルを入力に、リモートのConcourse上でタスクを実行して、出力をローカルにダウンロードする、という一連のタスクを行ってくれます。
なにげにConcourseの特徴的な機能です。
$ cat foo.yml
---
platform: linux
image: docker:///busybox
run:
path: echo
args: [hello world]
run:
path: sh
args:
- -exc
- |
pwd
ls
echo foo > some-files/foo
ls some-files
outputs:
- name: some-files
$ fly -t test execute -c foo.yml
targeting http://example-elb-177699448.ap-northeast-1.elb.amazonaws.com
executing build 84
initializing with docker:///busybox
running sh -exc pwd
ls
echo foo > some-files/foo
ls some-files
+ pwd
/tmp/build/e55deab7
+ ls
some-files
+ echo foo
+ ls some-files
foo
succeeded
タスクの作成
以下の様なyamlファイルを、プロジェクトのci/tasks/タスク名/task.yml
やci/tasks/タスク名.yml
やci/タスク名.yml
(場所は自由です)あたりにつくって、
---
platform: linux
image_resource:
type: docker-image
source:
repository: golang
tag: '1.6'
params:
SOME_PARAM: some-default-value
inputs:
- name: some-input
- name: some-input-with-custom-path
path: some/custom/path
outputs:
- name: some-output
run:
path: sh
args:
- -exc
- |
whoami
env
go version
find .
touch some-output/my-built-artifact
fly execute
を使って実際のCI環境上で実行します。
基本、負荷がめちゃくちゃ高いとかが無い限り、fly execute
で実際のCI環境でテストすることをおすすめします(それでもCI環境を汚すことはないので)。
$ fly -t ターゲット名 execute -c <yamlファイルへの相対パス>
inputは前段のget: リソース名
で指定したリソースと同じ名前のディレクトリ以下にあります。タスクにはinput以外に入力となるファイルは存在しません。なので、基本的にタスクのrun:
中でカレントディレクトリから何かを読むことはないはずです。
タスクで利用するDockerイメージをつくる
$ image=...
$ tag=...
$ docker build -t $image:$tag .
# テスト
$ echo テスト用の入力 | docker run -it --rm -v $(pwd)/input1:/tmp/build/e55deab7/input1 $(pwd)/output1:/tmp/build/e55deab7/output1 $image:tag sh -c "'cd /tmp/build/e55deab7; <run:に指定するコマンド。input1/以下のファイルを入力に、output1/以下にファイルを出力する> || sh'"
# 出力を確認
# テストが通ったらDocker Registryにpush。pushして初めて、Concourseから利用できるようになる
$ docker push $image:tag
ビルド履歴
$ fly -t test builds
targeting http://example-elb-177699448.ap-northeast-1.elb.amazonaws.com
id pipeline/job build status start end duration
82 one-off n/a succeeded 2016-05-10@11:12:18+0900 2016-05-10@11:12:24+0900 6s
81 one-off n/a succeeded 2016-04-21@15:16:07+0900 2016-04-21@15:16:10+0900 3s
...
75 one-off n/a failed 2016-04-21@15:07:11+0900 2016-04-21@15:10:47+0900 3m36s
74 one-off n/a aborted 2016-04-21@15:06:14+0900 2016-04-21@15:06:31+0900 17s
...
66 hello-world/hello-aws-cli 15 succeeded 2016-04-20@16:40:20+0900 2016-04-20@16:48:06+0900 7m46s
65 hello-world/hello-aws-cli 14 errored 2016-04-20@16:40:18+0900 2016-04-20@16:40:18+0900 0
pipeline/job
はパイプライン名/ジョブ名
、build
はビルド番号、status
は成功(succeeded)、失敗(failed)、中断(aborted)、エラー終了(errored)のいずれか。
fly execute
で実行した使い捨てジョブの場合、パイプライン名・ジョブ名どちらもないので、便宜上one-offと表示される。
ブラウザで特定のパイプラインを見る
flyコマンドじゃないけど・・
open', "#{@origin}/pipelines/zap"
パイプラインを作成する
$ fly set-pipeline -t $target --load-vars-from $vars_file -c $config_path -n -p $pipeline_name -v $vame=$value
パイプラインを開始する
Concourseの言葉では「unpause」という。
パイプラインはset-pipelineで作った段階では、定義されているけどまだ動き始めていない状態。unpauseして初めてパイプラインが動き始める。
fly', 'unpause-pipeline',
'-t', @target,
'--pipeline', 'zap'
全ConcourseクラスタのEndpoint URL一覧を出力
$ fly targets
name url expiry
lite http://192.168.59.4:8080 n/a
test http://example-elb-177699448.ap-northeast-1.elb.amazonaws.com Wed, 11 May 2016 02:11:50 UTC
tf http://example-elb-177699448.ap-northeast-1.elb.amazonaws.com Sat, 16 Apr 2016 10:39:42 UTC
fly interceptでビルドのデバッグ
デバッグ対象のタスクを実行したコンテナでshを起動するためには、以下のようにします。
※元になったDockerイメージにshが存在することが前提です。bashがあればbash等でも使える、ということでもあります。
$ fly -t lite intercept sh
interceptには、デバッグ対象のビルドを絞り込むためのフィルタを指定できるのですが、このように省略してもOKです。省略すると、複数候補があった場合に以下のように選択肢を表示してくれます。
targeting http://192.168.100.4:8080
1: build id: 4, step: one-off, type: check
2: build id: 4, step: one-off, type: get
3: build id: 4, step: one-off, type: task
4: build id: 4, step: some-input, type: get
5: build id: 4, step: some-input-with-custom-path, type: get
6: build id: 4, step: some-output, type: put
choose a container: 3
試しに3を選んでみました。
すると、rootユーザでshが起動して、カレントディレクトリがタスクを実行したときのそれになっています。inputやoutputもあります。この状態でデバッグしたい処理を実際に実行したり、結果を確認することができます。
# export
export GOLANG_DOWNLOAD_SHA256='e40c36ae71756198478624ed1bb4ce17597b3c19d243f3f0899bb5740d56212a'
export GOLANG_DOWNLOAD_URL='https://golang.org/dl/go1.6.2.linux-amd64.tar.gz'
export GOLANG_VERSION='1.6.2'
export GOPATH='/go'
export HOME='/root'
export PATH='/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
export PWD='/tmp/build/e55deab7'
export SOME_PARAM='some-default-value'
export TERM='xterm-256color'
export USER='root'
# pwd
/tmp/build/e55deab7
# ls
some some-input some-output
pipeline.yml
まとめ
- Job
-
serial: (true|false)
trueなら必ず順番にジョブを実行する。falseなら前のJobが実行完了する前に次がトリガーされたら、前のJobと平行で実行することを許可する。 参照 -
public: (true|fales)
trueなら、認証していないユーザがビルドログを閲覧できる 参照 -
plan: [...]
- =ビルドプラン=ステップの配列
- ステップ
- get
- リソースを取得する
- get: taskに渡すinput名
- resource: リソース名
- trigger: true
- リソースを取得する
- task
- タスクを実行する
- task: タスク名
- file: 実行したいタスクの定義=相対パス.yml
- attempts: リトライ回数(デフォルト1)
- タスクを実行する
- get
- ステップ
- =ビルドプラン=ステップの配列
-
リソースタイプとリソース
リソースタイプとリソースの例
組み込みリソースタイプgit
gitリソースタイプはConcourse CIに組み込みなので、resource_typeの定義は不要
resources:
- name: myresource
type: git
source:
# gitレポジトリのURLと
uri: https://github.com/18F/concourse-compliance-testing.git
# そのレポジトリ内のブランチ名を指定して
branch: {{script-branch}}
jobs:
- name: myjob
plan:
- get: myresource
- task: mytask1
config:
platform: linux
image_resource:
type: docker-image
source:
repository: busybox
outputs:
- name: project-data
run:
path: echo
args:
- task: mytask2
# gitレポジトリの特定ブランチの内容がリソース名と同じ名前のディレクトリに入っているので
# リソース名/パスでファイルを読み書きできる。
file: myresource/tasks/filter-project-data/task.yml
.jobs[].plan[].get
で指定しているリソース名と、.jobs[].plan[].file
で指定しているファイルパスの先頭(=リソース名)が同じであることに注目。プラン中で予めgetしたものが後続のタスクから利用できる。
非組み込みリソースタイプi18fgsa/http-resource
# 組み込みリソースタイプgitとは違って、リソースだけではなくリソースタイプを定義しておく必要がある
# Concourseに「こんなリソースタイプがあるから、リソースとして使わせてね」と伝えるイメージ
resource_types:
# このpipeline.yml内の`resources`内で、`type:リソースタイプ名`として参照するときに使う名前。自由に決めていいが、あとでリソースを自分で定義するとき、このリソース名を指定する必要がある。
- name: http-resource
# Docker Hubからとってきた18fgsa/http-resourceイメージで作ったコンテナを使ってリソースのin/out/checkを行うリソースタイプを定義する、という意味
type: docker-image
source:
repository: 18fgsa/http-resource
resources:
- name: scripts
type: git
source:
uri: https://github.com/18F/concourse-compliance-testing.git
branch: {{script-branch}}
- name: after-midnight
type: time
source:
interval: 1h
start: 12:00 AM -0500
stop: 12:30 AM -0500
- name: slack
type: slack-notification
source:
url: {{slack-hook}}
<% projects.each do |project| -%>
- name: s3-result-<%= project['name'] %>
type: s3
source:
bucket: {{aws-bucket}}
versioned_file: results/<%= project['name'] %>.json
access_key_id: {{aws-access-key}}
secret_access_key: {{aws-secret-key}}
- name: s3-summary-<%= project['name'] %>
type: s3
source:
bucket: {{aws-bucket}}
versioned_file: summaries/<%= project['name'] %>.json
access_key_id: {{aws-access-key}}
secret_access_key: {{aws-secret-key}}
<% unless project['skip_team_api'] -%>
- name: fetch-project-data-<%= project['name'] %>
type: http-resource
source:
uri: https://team-api.18f.gov/public/api/projects/<%= project['name'] %>/
filename: project.json
index: https://team-api.18f.gov/public/api/projects/<%= project['name'] %>/
etag: true