ようへいの日々精進XP

よかろうもん

2021 年 01 月 06 日 (水)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

[ランニング 2021-01-06-朝] 走れる喜びを噛み締めて (5) 〜 久しぶりの朝ラン 〜 / かっぱさんの活動データ | YAMAP / ヤマップ

読書

残念ながら、今日は本を読む時間を作れなかった。

夕飯

WordPress のプラグインバージョン番号の付け方に翻弄された 〜 そして、shellspec を使ってみた 〜

tl;dr

inokara.hateblo.jp

これの続きです。

やっぱり、WordPress プラグインバージョン

当初は...

WordPressプラグインバージョンをパースする処理を以下のように書いていました。

echo ${plugin_name} | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+)?" | sed 's/.//'

これは、プラグインのバージョン番号が以下のような状態を想定した処理でした。

  • plugin-name.1.2.3.zip
  • plugin-name.12345678.zip
  • plugin-name-7.1.2.3.zip

実際に実行すると、以下のように、意図した通りにバージョン番号 (1.2.3 とか 12345678 等) が取得出来ます。

$ echo plugin-name.1.2.3.zip | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+)?" | sed 's/.//'
1.2.3
$ echo plugin-name.12345678.zip | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+)?" | sed 's/.//'
12345678
$ echo plugin-name-7.1.2.3.zip | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+)?" | sed 's/.//'
1.2.3

とーころが...

新手が登場しました。

  • plugin-name.1.2.3.4.zip

これを従来のパース処理で処理しようとすると...

$ echo plugin-name.1.2.3.4.zip | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+)?" | sed 's/.//'
1.2.3

冒頭の 3 桁のみがパースされる状態となりました...

改修、そして shellspec

正規表現の試行錯誤

正規表現検定 8 級なので、とりあえず試行錯誤。試行錯誤の結果、以下のように書くことで、なんとか意図したような結果を得ることが出来ました。

$ echo ${plugin_name} | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+|\.[0-9]+\.[0-9]+)?" | sed 's/.//'

先程の 4 桁バージョン番号を処理してみます。

$ echo plugin-name.1.2.3.4.zip | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+|\.[0-9]+\.[0-9]+)?" | sed 's/.//'
1.2.3.4
$ echo plugin-name-100.1.2.3.4.zip | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+|\.[0-9]+\.[0-9]+)?" | sed 's/.//'
1.2.3.4

意図した通りに解析されていることを確認しました。

そして shellspec (1)

今後も同じような変異種が現れる可能性もあり、試行錯誤している間にデグレしてしまう可能性もあったので、この処理を関数化してユニットテストを書くようにしました。

そこで、テストフレームワークとして shellspec を選びました。

github.com

選んだ理由としては、特に強いこだわりがあったわけではありませんが、Rspec っぽく書けるという触れ込みだったので、お試し程度に使ってみようと思った次第です。

インストールの手順等は割愛しますが、今回は macOS に homebrew でインストールして利用しました。

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.7
BuildVersion:   19H114
$ brew tap shellspec/shellspec
$ brew install shellspec

以下のように実行して、shellspec を初期化します。

$ mkdir project
$ cd project
$ shellspec --init

project ディレクトリ直下に .shellspec ファイルと spec ディレクトリ、spec ディレクトリ以下に spec_helper.sh ファイルが作成されます。

そして shellspec (2)

以下のようにテスト対象の関数を用意しました。

$ cd project
$ vim lib/version-number-parse
function version_number_parse {
  echo $1 | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+|\.[0-9]+\.[0-9]+)?" | sed 's/.//'
}

そして、テストは以下のように用意しました。

$ vim spec/version-number-parse_spec.sh
Describe "Check for version-number-parse script"
  Include lib/version-number-parse
  Describe "Call version_number_parse"
    It "plugin-name.3.1.21.11.zip"
      When call version_number_parse plugin-name.3.1.21.11.zip
      The output should eq "3.1.21.11"
    End

    It "plugin-name.3.10.2.zip"
      When call version_number_parse plugin-name.3.10.2.zip
      The output should eq "3.10.2"
    End

    It "plugin-name.3.9.2.zip"
      When call version_number_parse plugin-name.3.9.2.zip
      The output should eq "3.9.2"
    End

    It "plugin-name.1.2.zip"
      When call version_number_parse plugin-name.1.2.zip
      The output should eq "1.2"
    End

    It "plugin-name-7.1.2.3.zip"
      When call version_number_parse plugin-name-7.1.2.3.zip
      The output should eq "1.2.3"
    End

    It "plugin-name.12345678.zip"
      When call version_number_parse plugin-name.12345678.zip
      The output should eq "12345678"
    End
  End
End

後は、以下のように実行します。

$ shellspec --format document -s bash

以下のように出力されました。

$ cd project
$ shellspec --format document -s bash
Running: /bin/bash [bash 3.2.57(1)-release]

Check for version-number-parse script
  Call version_number_parse
    plugin-name.3.1.21.11.zip
    plugin-name.3.10.2.zip
    plugin-name.3.9.2.zip
    plugin-name.1.2.zip
    plugin-name-7.1.2.3.zip
    plugin-name.12345678.zip

Finished in 0.37 seconds (user 0.31 seconds, sys 0.07 seconds)
6 examples, 0 failures

Fail させてみると、以下のように出力されました。

$ shellspec --format document -s bash
Running: /bin/bash [bash 3.2.57(1)-release]

Check for version-number-parse script
  Call version_number_parse
    plugin-name.3.1.21.11.zip
    plugin-name.3.10.2.zip
    plugin-name.3.9.2.zip (FAILED - 1)
    plugin-name.1.2.zip
    plugin-name-7.1.2.3.zip
    plugin-name.12345678.zip

Examples:
  1) Check for version-number-parse script Call version_number_parse plugin-name.3.9.2.zip
     When call version_number_parse plugin-name.3.9.2.zip

     1.1) The output should eq 3.9.1

            expected: "3.9.1"
                 got: "3.9.2"

          # spec/ver-check_spec.sh:16

Finished in 0.33 seconds (user 0.31 seconds, sys 0.07 seconds)
6 examples, 1 failure


Failure examples / Errors: (Listed here affect your suite's status)

shellspec spec/ver-check_spec.sh:14 # 1) Check for ver-check script Call get_current_version plugin-name.3.9.2.zip FAILED

いい感じ!shellspec

テスト結果の出力

以下のように --format オプションで指定可能です。

# --format を指定しない場合
$ shellspec -s bash
Running: /bin/bash [bash 3.2.57(1)-release]
......

Finished in 0.32 seconds (user 0.31 seconds, sys 0.07 seconds)
6 examples, 0 failures

# junit フォーマットで取得
$ shellspec --format junit -s bash
<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="6" time="0.32" errors="0" failures="0" name="ver-check">
  <testsuite id="0" tests="6" errors="0" failures="0" skipped="0" name="spec/version-number-parse_spec.sh" hostname="oreno-mac" timestamp="2021-01-05T15:22:57">
    <testcase time="0" classname="spec/version-number-parse_spec.sh" name="Check for version-number-parse script Call version_number_parse plugin-name.3.1.21.11.zip"></testcase>
    <testcase time="0" classname="spec/version-number-parse_spec.sh" name="Check for version-number-parse script Call version_number_parse plugin-name.3.10.2.zip"></testcase>
    <testcase time="0" classname="spec/version-number-parse_spec.sh" name="Check for version-number-parse script Call version_number_parse plugin-name.3.9.2.zip"></testcase>
    <testcase time="0" classname="spec/version-number-parse_spec.sh" name="Check for version-number-parse script Call version_number_parse plugin-name.1.2.zip"></testcase>
    <testcase time="0" classname="spec/version-number-parse_spec.sh" name="Check for version-number-parse script Call version_number_parse plugin-name-7.1.2.3.zip"></testcase>
    <testcase time="0" classname="spec/version-number-parse_spec.sh" name="Check for version-number-parse script Call version_number_parse plugin-name.12345678.zip"></testcase>
  </testsuite>
</testsuites>

テストを実行するシェルを指定する

デフォルトでは、/bin/sh が使われるとのことですが、--shell 又は -s オプションでシェルを指定することが出来ます。

$ shellspec -s bash

上記の例では、その名の通り、bash を利用することになります。

CircleCI のオフィシャル Docker イメージである、cimg/python:3.6 上で shellspec を利用しようとした際に、このイメージのデフォルトシェルは /bin/sh で、その実体は dash となっており、function がサポートしていないことでエラーとなりテストが実行されずに焦りました。

circleci@0c366a26ccfd:~/project$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Apr  3  2020 /bin/sh -> dash

circleci@0c366a26ccfd:/project$ cat lib/version-number-parse
function version_number_parse {
  echo $1 | grep -o -E "(\.[0-9]+|\.[0-9]+\.){1}[0-9]+(\.[0-9]+|\.[0-9]+\.[0-9]+)?" | sed 's/.//'
}

# dash だと function がサポートされていない
circleci@0c366a26ccfd:/project$ shellspec
/bin/sh: 1: lib/version-number-parse: function: not found

Unexpected output to stderr occurred at line 1-2 in 'spec/version-number-parse_spec.sh'
Running: /bin/sh [sh]


Finished in 0.16 seconds (user 0.04 seconds, sys 0.01 seconds)
0 examples, 0 failures, aborted by an unexpected error

Aborted with status code [executor: 127] [reporter: 1] [error handler: 102]
Fatal error occurred, terminated with exit status 102.

circleci@0c366a26ccfd:/project$ shellspec --shell bash
Running: /bin/bash [bash 4.4.20(1)-release]
......

Finished in 0.27 seconds (user 0.23 seconds, sys 0.06 seconds)
6 examples, 0 failures

上記のように --shell bash を追加して実行することで、テストが正常に実行されました。

以上

WordPressプラグインバージョンの付け方に翻弄されてしまいましたが、シェルスクリプトでもテストを書くと良いということと、shellspec に出会うことが出来て良かったというお話でした。

参考

github.com

qiita.com

qiita.com

2021 年 01 月 05 日 (🔥)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

読書

引き続き、「エラーメッセージから学ぶ Rack」を 53 ページまで読み進めた。Rack の欠落版 Lack のコードを示しながら Rack の挙動を解説している。

melborne.github.io

昨日も書いたけど、素の Rack を使ったことがなく、ピンとはこないけど、実際にコードを示しながら解説するのって良いよなあ。

もうすぐ、読み終わりそう。

夕飯

2021 年 01 月 04 日 (月)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

仕事初め

正月、ほぼパソコンの前にいたので、特に何が変わるわけでもなく、8 時間縛りが発生しただけなので、あまり疲れとかも感じることは無かった。

スロースタートで頑張っていこう。

読書

積読になっていた、「エラーメッセージから学ぶ Rack」を 50 ページまで読んだ。

melborne.github.io

エラーを発生させつつ Rack について紐解いていくスタイルで読みやすい。Rack について、名前しか聞いたことがなかったけど、面白くてサクサク読み進められている。

あと、同じく積読になっていた、「Software Design 2020 年 4 月号」の「コンテナマイクロサービスの監視アプローチ」を読んだ。

gihyo.jp

Kubernetes の話に収束してしまうのは、世の中の流れなんだろうなあという思い。「Observability」が重要ということが書かれていたけど、いまいち、なぜ、それが重要なのかを読み取ることが出来なかった。

夕飯

2021 年 01 月 03 日 (日)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

[ランニング 2021-01-03-夕] 走れる喜びを噛み締めて (5) 〜 2021 走り初め 〜 / かっぱさんの活動データ | YAMAP / ヤマップ

箱根駅伝復路

駒澤大学の 10 区大逆転に興奮したし、長丁場なレース、何が起きるか判らないなあと思った。人生も一緒、何が起きるか判らないので、最後まで諦めない気持ちが大切だなと痛感。明日からの糧にしたい。

二日目のおでん

具材を追加して、更に煮詰まった状態で更に美味しくなって、ハフハフしながらいただいた。美味しゅうございました。

2021 年の目標 〜 2021 年にやりたいこと等 〜

tl;dr

2021 年の目標を書いておきます。

仕事・エンジニアリング

引き続き、最強の登山地図アプリサービス YAMAP を支えるインフラの運用を頑張っていきたいと思います。

そして、エンジニアとして、非常に力不足を感じているので、エンジニアとしてのインプットとアウトプットを頑張っていきたいと思います。

具体的には、以下のような内容に取り組みます。

  • 技術ブログを月に 1 記事以上
  • 雑でも良いので、OSS ツールを 1 つ以上リリースする
  • 今まで作った OSS ツールのメンテナンスを継続する
  • AWSGCP の資格を 1 つ以上取得する

読書

昨年は、殆ど本を読み切ることがありませんでした。本を読んでいないので語彙力が無さ過ぎて、このブログを書く時、会社でミーティングをする時等で、その語彙力の無さを痛感しました。そして、インプットが減るとアウトプットも減る傾向があり、日記以外のブログ記事を書くことも減ってしまいました。

ということで、2021 年は、「本を月に 1 冊 (雑誌も可) 以上読む」ことを目標にしたい...のですが、もう少し、小さく区切って、「出来るだけ毎日、10 〜 15 分本を読む」ことを目標にしたいと思います。そして、日記の中で、「今日の読書」というコーナーを設けて、読んだ内容をまとめるようにしたいと思います。

まずは、iPad mini の中に積読となっている書籍から読んでいこう。

英会話

昨年から、会社の福利厚生でレアジョブを利用した英会話レッスンを受けています。

自分の英語力は中一レベルで止まっている為、レアジョブのレッスンはかなりレベルが高いので苦労していますが、今年も引き続き、頑張っていこうと思います。

TOEIC や英検等、客観的に英語力を評価出来る試験等を受験出来るくらいになりたいところですが、まずは、「英会話を楽しむ」ことを継続出来ればいいなあと考えています。

ラン

昨年は、骨粗鬆症からの、胸椎の圧迫骨折、11 月からは左足先を痛めてしまいました。ということで、故障しかしていない一年でした。

2021 年も左足先の痛みを抱えたままのスタートなりましたが、毎日エアロバイクを漕いで出来るだけ、心肺機能を落とさないように心がけています。

ということで、左足先の痛みが無くなったら、以下のような目標を持って、怪我が再発しないように注意しながら走っていこうと思います。

  • 故障はしたくない! (準備運動、整理運動、日頃のストレッチを念入りに)
  • 走る前に必ず補強をする
  • 出来るだけ毎日、5 キロ以上走る (年間 1,800 キロ以上)
  • 5000m (5Km) を 18 分を切る
  • 10000m (10Km) を 36 分台で走る
  • 20 キロを 80 分台で走る
  • ハーフマラソンでは、84 分台で走る
  • フルマラソンでは、サブスリーを目指す!
  • トレイルランニングも機会があれば取り組む

家族

今年の元旦で、結婚 10 年目に突入しました。

10 年、振り返るとあっと言う間でした。些細な理由でケンカも沢山しましたが、毎日、何かしら笑いが起きている 10 年だったと思います。自分勝手でワガママな自分をいつも優しく見守ってくれる奥さんには本当に感謝しかありません。また、昨年は骨粗鬆症を患ってしまったことで、食生活にもより一層気を使ってくれて本当に有り難かったです。

これからも奥さんと二人、手を取り合い、笑いの絶えない毎日を送りたいと思います。コロナが落ち着いたら、10 年目を祝うイベント企画しようと思います。

そして、今年は、そのコロナの影響で帰省することが出来ず、鹿児島の両親の実際に顔を見る機会が激減してしまいました。しかし、テクノロジーの力でテレビ電話を通して会話をする機会がとても増えました。そのおかげで、LINE の使い方を覚えてくれたりして、実際に帰省するよりもコミュニケーションを取る機会が増えたような気がします。

テレビ電話に映る両親は、元気そうではありますが、年相応に老いが進んだことを感じます。いつまで、こんな風に元気でいてくれるのか心配は尽きませんが、出来るだけ、元気に長生きしてもらえるように支えられたらいいなあと考えています。

以上

2021 年の目標的なものをダラリと書いてみました。

やっぱ、自分の語彙力の無さに悲しくなりましたが、今年の振り返りを書く頃には、スラスラと気の利いたポエムが書けるようになりたいものです。

ということで、本年も宜しくお願い致します。

2021 年 01 月 02 日 (土)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

  • 補強 (なんちゃって体幹レーニング 3 セット、30 分エアロバイク (負荷 8)) + (35 秒ダッシュ漕ぎ x 5 Rest: 35 秒)
  • エアロバイク二日目、いつもと同じメニューなのにめっちゃキツかった。。。

箱根駅伝往路

青山学院が思わぬ順位で箱根駅伝ってドラマティックだなあという印象。そして、母校 (日体大) は往路 15 位、明日の復路で巻き返しを祈る。

おでん

夕飯はおでんをメインに。手羽中を入れたり、プチトマトを入れたりして、とても美味しゅうございました。

Dockerfile 内で条件に応じて処理を変えたかったので試行錯誤したメモ

tl;dr

Docker イメージをビルドする際に、--build-arg に指定した条件に応じて、処理を変えたかったので試行錯誤してみました。

Dockerfile 例

以下のような Dockerfile があったとする。

FROM alpine

# 条件 A の時
ADD scripts/test1.sh /tmp/test.sh

# 条件 B の時
ADD scripts/test2.sh /tmp/test.sh

# /tmp/test.sh を実行
RUN /tmp/test.sh
  • 条件 test1 の時 (--build-arg TEST_ARG=test1) には、test1.sh/tmp/test.shADD したい
  • 条件 test2 の時 (--build-arg TEST_ARG=test2) には、test2.sh/tmp/test.shADD したい
  • 最後に /tmp/test.sh を実行する

スクリプトは以下のような内容。

$ cat scripts/test1.sh
#!/bin/sh

echo "test1"

$ cat scripts/test2.sh
#!/bin/sh

echo "test2"

先述の Dockerfile をそのまま実行すると、以下のように出力される。

$ docker build --no-cache=true --tag test-build .
Sending build context to Docker daemon  5.632kB
Step 1/4 : FROM alpine
 ---> a24bb4013296
Step 2/4 : ADD scripts/test1.sh /tmp/test.sh
 ---> 0a4e47647476
Step 3/4 : ADD scripts/test2.sh /tmp/test.sh
 ---> 7cac3bdbf5f7
Step 4/4 : RUN /tmp/test.sh
 ---> Running in d2b82c5d3aef
test2
Removing intermediate container d2b82c5d3aef
 ---> 3ebafdf8e1ec
Successfully built 3ebafdf8e1ec
Successfully tagged test-build:latest

さて、どうしようか。

試行錯誤 (1) シェルスクリプトに手をいれる

それぞれのシェルスクリプトを結合して、以下のような内容に修正。

$ vim scripts/tests.sh
#!/bin/sh

if [ "${TEST_ARG}" = "test1" ];then
  echo "test1"
else
  echo "test2"
fi

Dockerfile を以下のように修正。

FROM alpine

ARG TEST_ARG 

ADD scripts/tests.sh /tmp/test.sh

RUN /tmp/test.sh

実行してみる。

# TEST_ARG=test1
$ docker build --build-arg TEST_ARG=test1 --no-cache=true --tag test-build .
Sending build context to Docker daemon  5.632kB
Step 1/4 : FROM alpine
 ---> a24bb4013296
Step 2/4 : ARG TEST_ARG
 ---> Running in 6bee4b0a77d4
Removing intermediate container 6bee4b0a77d4
 ---> 18791606eb7d
Step 3/4 : ADD scripts/tests.sh /tmp/test.sh
 ---> 2ef0dc18c220
Step 4/4 : RUN /tmp/test.sh
 ---> Running in 1bdcf49a1b3f
test1
Removing intermediate container 1bdcf49a1b3f
 ---> b44ffe9d5479
Successfully built b44ffe9d5479
Successfully tagged test-build:latest

# TEST_ARG=test2
$ docker build --build-arg TEST_ARG=test2 --no-cache=true --tag test-build .
Sending build context to Docker daemon  5.632kB
Step 1/4 : FROM alpine
 ---> a24bb4013296
Step 2/4 : ARG TEST_ARG
 ---> Running in 0dcfd7ce440f
Removing intermediate container 0dcfd7ce440f
 ---> 5383560dc479
Step 3/4 : ADD scripts/tests.sh /tmp/test.sh
 ---> 4827a378a33c
Step 4/4 : RUN /tmp/test.sh
 ---> Running in 061058c84bac
test2
Removing intermediate container 061058c84bac
 ---> cef33b3ef95d
Successfully built cef33b3ef95d
Successfully tagged test-build:latest

一応、意図した挙動になっている。

念の為、docker history で確認する。

$ docker build --build-arg TEST_ARG=test1 --no-cache=true --tag test-build .
$ docker history test-build
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
00b3da2b79ae        3 seconds ago       |1 TEST_ARG=test1 /bin/sh -c /tmp/test.sh       0B
1d612168b8e3        4 seconds ago       /bin/sh -c #(nop) ADD file:802b1103fc27ad8ee…   85B
32af95883761        4 seconds ago       /bin/sh -c #(nop)  ARG TEST_ARG                 0B
a24bb4013296        7 months ago        /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>           7 months ago        /bin/sh -c #(nop) ADD file:c92c248239f8c7b9b…   5.57MB

ただ、このパターンだと、シェルスクリプト (≒アプリケーション) に手を入れる必要があるし、インフラ側の都合をアプリケーション側に押し付けるような感じがする。

試行錯誤 (2) Dockerfile に手をいれる

シェルスクリプトには手を入れずに Dockerfile 内で完結したい場合、以下のように Dockerfile を修正した。

ARG TEST_ARG 

FROM alpine AS build_test1
ONBUILD ADD scripts/test1.sh /tmp/test.sh

FROM alpine AS build_test2
ONBUILD ADD scripts/test2.sh /tmp/test.sh

FROM build_${TEST_ARG}

RUN /tmp/test.sh

マルチステージビルド を使う。

実行してみる。

# TEST_ARG=test1
$ docker build --build-arg TEST_ARG=test1 --no-cache=true --tag test-build .
Sending build context to Docker daemon  5.632kB
Step 1/7 : ARG TEST_ARG
Step 2/7 : FROM alpine AS build_test1
 ---> a24bb4013296
Step 3/7 : ONBUILD ADD scripts/test1.sh /tmp/test.sh
 ---> Running in 533fe2b2f259
Removing intermediate container 533fe2b2f259
 ---> 354bf4f2c5b6
Step 4/7 : FROM alpine AS build_test2
 ---> a24bb4013296
Step 5/7 : ONBUILD ADD scripts/test2.sh /tmp/test.sh
 ---> Running in 5dd2be2f59e8
Removing intermediate container 5dd2be2f59e8
 ---> ef43e969bb08
Step 6/7 : FROM build_${TEST_ARG}
# Executing 1 build trigger
 ---> 3454bad7d13f
Step 7/7 : RUN /tmp/test.sh
 ---> Running in 0387de5f001c
test1
Removing intermediate container 0387de5f001c
 ---> be4d9823b31a
Successfully built be4d9823b31a
Successfully tagged test-build:latest

# TEST_ARG=test2
$ docker build --build-arg TEST_ARG=test2 --no-cache=true --tag test-build .
Sending build context to Docker daemon  5.632kB
Step 1/7 : ARG TEST_ARG
Step 2/7 : FROM alpine AS build_test1
 ---> a24bb4013296
Step 3/7 : ONBUILD ADD scripts/test1.sh /tmp/test.sh
 ---> Running in f481f96b5139
Removing intermediate container f481f96b5139
 ---> 70758139a3f8
Step 4/7 : FROM alpine AS build_test2
 ---> a24bb4013296
Step 5/7 : ONBUILD ADD scripts/test2.sh /tmp/test.sh
 ---> Running in c2f835a5bdfe
Removing intermediate container c2f835a5bdfe
 ---> 6b435562e6b6
Step 6/7 : FROM build_${TEST_ARG}
# Executing 1 build trigger
 ---> 6436710016c2
Step 7/7 : RUN /tmp/test.sh
 ---> Running in 364a63da9c54
test2
Removing intermediate container 364a63da9c54
 ---> 16ab720a3284
Successfully built 16ab720a3284
Successfully tagged test-build:latest

念の為、docker history で確認する。

$ docker build --build-arg TEST_ARG=test1 --no-cache=true --tag test-build .
$ docker history test-build
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
d664199dd041        3 seconds ago       /bin/sh -c /tmp/test.sh                         0B
ecf320aaadc6        3 seconds ago       /bin/sh -c #(nop) ADD file:1ab674a4350c46957…   24B
34b4004c7932        4 seconds ago       /bin/sh -c #(nop)  ONBUILD ADD scripts/test1…   0B
a24bb4013296        7 months ago        /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>           7 months ago        /bin/sh -c #(nop) ADD file:c92c248239f8c7b9b…   5.57MB

なるほど。

TEST_ARG=test1の条件でイメージが生成されていることが判る。

ということで

試行錯誤 (1) と試行錯誤 (2) のどちらが良いのか。

  • 試行錯誤 (1) パターンは、イメージ生成に合わせて、アプリケーション (本記事ではシェルスクリプト) の改修が必要
  • 試行錯誤 (2) パターンは、アプリケーションの改修は不要、ちょっと Dockerfile が長くなる

という理由で、個人的には、(2) が良いかな。

参考

docs.docker.jp

stackoverflow.com

WordPress 及び WordPress プラグインやテーマの自動更新について調べた

自動更新のデフォルト設定

WordPress 5.6 から、以下のような変更が加えられていました。

make.wordpress.org

make.wordpress.org

管理画面に WordPress コアバージョンのメジャーバージョン自動更新をオプトインできるようにする為の新しい UI が導入されました。尚、デフォルトでは、メジャーバージョンの自動更新がオプトインされています (放っておくと、勝手にメジャーバージョンがあがる。。。 :cold_sweat: )

f:id:inokara:20210102141807p:plain

そして、実は、WordPress 5.5 からは、上記と同様に、プラグインやテーマの自動更新をオプトイン出来るようにする UI が導入されていました。

f:id:inokara:20210102141820p:plain

プラグインやテーマの自動更新については、デフォルトでは無効になっていて、管理者が手動で有効にしてあげる必要があるようです。

自動更新は...ちょっと...

WordPress コアバージョン (メジャーバージョンは流石に怖い) もプラグインやテーマも自動更新してくれるのは、運用上、非常に有り難いので有効にしておきたいところですが、事前の動作確認無しのアップデートは流石に怖いですよね。。。

ということで、WordPress コアのメジャーバージョンやマイナーバージョンの自動更新や、プラグイン、テーマの自動更新について無効にする設定につい確認しました。

自動更新無効にする方法

wp-config.php に設定するパターン

要件に応じて、以下の何れかを wp-config.php に追記します。

// This site will not receive automatic updates for new versions of WordPress.
define( 'AUTOMATIC_UPDATER_DISABLED', true ); // -> WordPress 本体バージョンの自動アップデート及び、プラグインとテーマの自動アップデートを無効

// This site will not receive automatic updates for new versions of WordPress.
define( 'WP_AUTO_UPDATE_CORE', false ); // -> WordPress 本体バージョンの自動アップデートの無効

// This site is automatically kept up to date with maintenance and security releases of WordPress only.
define( 'WP_AUTO_UPDATE_CORE', minor ); // -> WordPress 本体バージョンのマイナーバージョンアップを有効

// This site is automatically kept up to date with each new version of WordPress.
define( 'WP_AUTO_UPDATE_CORE', true ); // -> WordPress 本体バージョンの自動アップデートが有効になる
define( 'WP_AUTO_UPDATE_CORE', beta ); // -> WordPress 本体バージョンの自動アップデートが有効になる
define( 'WP_AUTO_UPDATE_CORE', rc ); // -> WordPress 本体バージョンの自動アップデートが有効になる

wp-includes/functions.php に設定するするパターン

要件に応じて、以下の何れかを wp-includes/functions.php に追記します。

// Disable major version auto-update
// This site is automatically kept up to date with maintenance and security releases of WordPress only.
add_filter( 'allow_major_auto_core_updates', '__return_false' ); // -> メジャーバージョンの自動アップデートを無効

// Disable plugins auto-update UI elements.
add_filter( 'plugins_auto_update_enabled', '__return_false' ); // -> プラグインの自動アップデートを無効
 
// Disable themes auto-update UI elements.
add_filter( 'themes_auto_update_enabled', '__return_false' ); // -> テーマの自動アップデートを無効

で、どうするか

以下のようなシェルスクリプトを用意してコンテナイメージをビルドする際に、wp-config.php を更新するようにしました。

#!/bin/bash

cp -v /usr/src/wordpress/wp-config-sample.php /usr/src/wordpress/wp-config-sample.php.1
awk '
  /^\/\*.*stop editing.*/ && c == 0 {
    c = 1
    print "/* Disable Auto Update */"
    print "define( \047AUTOMATIC_UPDATER_DISABLED\047, true );"
    print ""
  }
  { print }
' /usr/src/wordpress/wp-config-sample.php.1 > /usr/src/wordpress/wp-config-sample.php
if [ "$?" == "0" ];then
  rm -f /usr/src/wordpress/wp-config-sample.php.1
fi

尚、WordPress オフィシャルの Docker イメージを利用している場合、このシェルスクリプトを up-date-wp-config.sh というファイル名で追加して、Dockerfile には以下のように追加しました。

()
ADD bin/update-wp-config.sh /usr/local/bin/update-wp-config.sh
RUN /usr/local/bin/update-wp-config.sh
()

コンテナを起動すると、wp-config.php は以下のような状態となります。

/* Disable Auto Update */
define( 'AUTOMATIC_UPDATER_DISABLED', true );

// If we're behind a proxy server and using HTTPS, we need to alert WordPress of that fact
// see also http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        $_SERVER['HTTPS'] = 'on';
}

/* That's all, stop editing! Happy publishing. */

ちゃんと、define( 'AUTOMATIC_UPDATER_DISABLED', true ); が挿入されています。ちなみに、If we're behind a proxy server and using HTTPS から始まる行については、WordPress コンテナが起動する際に実行される docker-entrypoint.sh によって挿入されています。

以上

WordPress 三昧な冬休みになりそうです。

参考

make.wordpress.org

make.wordpress.org

hub.docker.com

2021 年 01 月 01 日 (金)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

  • 補強 (なんちゃって体幹レーニング 3 セット、30 分エアロバイク (負荷 8)) + (35 秒ダッシュ漕ぎ x 5 Rest: 35 秒)
  • 今年最初のエアロバイクだった

お雑煮やらおせちやら

お雑煮は自分が作った。一応、昆布で出汁を取って、焼いたお持ちを放り込むだけ。シンプルだけど我ながら美味しゅうございました。そして、待ちに待った「しらゆき」のおせちは、流石プロの味!で、お酒と共にあっという間に食べきってしまった。

ニューイヤー駅伝

おせちを食べながら、ダラダラとニューイヤー駅伝をテレビで観戦。贔屓にしていた、GMO インターネットは 9 位ということで、入賞を逃したけど、優勝候補と言われているチーム達のレースをかき回すような活躍はしていたと思う。皆さん、寒い中、大変お疲れ様でした。

そして、明日は箱根駅伝。自分が走るわけではないのに緊張してきたぞ...

リモート飲み会

夕飯は、鹿児島の 父、母、弟と LINE 電話のビデオ通話を使ったリモート飲み会。父も母も喜んでいたので本当に良い年始になったと思う。