シェルスクリプトも進化する

23時に寝て2時に起きて6時に起きた。

シェルスクリプト再考

久しぶりにシュルスクリプトを書いていて、ユーティリティ関数をうまいこと実装できないかを調べていたら nameref という仕組みが bash 4.3 以降で使えるらしい。私の bash 環境は 5.0.17 なので、bash 5 以上という制約にしてしまってもよいだろうと思う。例えば、こんなことができる。シェルスクリプトで split を実装するの面倒よね。

function split() {
    local -n arr="$1"
    local values="$2"
    local sep="${3:-,}"
    IFS="${sep}"
    read -a arr <<< $(echo "$values" | tr -d '[:space:]')
}

function test() {
    split mylist "a, b, c"
    echo "'${mylist[0]}'"
    echo "'${mylist[1]}'"
    echo "'${mylist[2]}'"
}

実行結果。ちょっと感動した。

$ test
'a'
'b'
'c'

bizpy 勉強会

Python で機械学習の前処理をやってみる勉強会 を開催した。今回も講師をわたなべさんにお願いした。私が余裕なくて全くなにもできていない。運営が2人いるとすごく助かる。今回は機械学習の前処理に着目して pandas や scikit-learn を使って実際にどういったプログラミングをするかを解説してもらった。Colab を使ってデモするのがいまどきのやり方なのかな?私は全く触ったことがないけど、そういうやり方の違いも含めて関心をもてた。Colab 上で普通に git コマンドも使えるのでリポジトリのクローンなんかもできる。次回は私もなにかしら発表をしたいなとは思う。いまのお仕事が一段落ついたら。

github apps を調べた

23時に寝て5時半に起きた。何度か夜中にも起きた。起きてからドラクエタクトやってた。

oauth apps と github apps

いまお仕事で ci/cd の改善をやっていて、その一環としてリポジトリをまたがったパイプライン処理を検討している。 ci/cd で使うような認可の仕組みとして github には oauth apps と github apps の2種類がある。

私はどちらも全く関わったことがなかったので、仕組みがイメージできる oauth apps を使えばよいのだろうと調べ始めた。しかし、一通り調べてみて会社の開発における ci/cd に使うなら github apps の方が適していることがわかった。両者がどう違うのかもドキュメントに記載されている。最初にこのドキュメントを読めば oauth apps を調査する必要はなかった。

具体的には、oauth apps は user の権限を認可する仕組みで、github apps は organization の権限を認可する仕組みと言える。github apps も oauth によるユーザー認証もできる上にアプリ自身の認証もできる。さらにアクセスできるリポジトリも制限できることから github actions などで、特定のリポジトリに対してのみアクセス可能なトークンを取得するには github apps の方が向くというわけだ。oauth でユーザーが認可するときに scope を指定するが、その scope を organization が設定できるといったところが github apps と oauth との違いにみえる。取得できる token の有効期限にもその考え方の違いが出ている。

  • oauth apps
    • ユーザー/デバイス認証
      • 認可コード: 15分
      • アクセストークン: 無期限
  • github apps
    • installation 認証
      • 認可jwt: 10分
      • installation トークン: 1時間
    • ユーザー/デバイス認証
      • 認可コード: 15分
      • アクセストークン: 8時間

kustomize の動的な設定

23時に寝て2時に起きてそこから断続的に寝たり起きたりを繰り返して6時に半に起きた。ウクライナ情勢のニュースや記事ばかり読んでてあてられた。

kustomize の動的な設定

kustomize で管理している image のタグをデプロイ処理の中で動的に変更したい。パラメーター渡しなり環境変数なり、なにかしらあるだろうとは予測している。Demo: change image names and tags のサンプルによると、次のように実行すればよいみたい。

$ kustomize edit set image busybox=alpine:3.6

次のような kustomization.yaml をセットしてくれるみたい。

images:
- name: busybox
  newName: alpine
  newTag: 3.6

タグのところをリビジョン指定できればいいだけなのでとくに SECRET を使う必要もない。このやり方で書き換えた newTag が POD のデプロイ対象になってくれればよいはず。

ウクライナ情勢

0時に寝て7時に起きた。アニメみたりドラクエタクトしたりして11時ぐらいまでだらだらしてた。

保険料率の変更

毎年、社会保険の保険料率が変更されるのでその保険料の計算をして反映しないといけない。多くの会社は3月度の保険料は翌月払いとなるので4月からの反映となるが、うちの会社は当月締めの当月払いなので3月から反映させないといけない。

  • 健康保険料率: 10.24% → 10.13%
  • 介護保険料率: 1.80% → 1.64%

協会けんぽの来期の保険料率は下がるみたい。毎年少しずつ上がっていく一方だと思っていたのでそういうこともあるんだなという印象。

ウクライナ情勢

タイムラインを眺めていると、否応でもウクライナ情勢のニュースやコメントが流れてきてなんとなくみてしまって作業の手がつかなくなってしまった。早めに帰って仕切り直そうとしたけど、精神的に疲れてしまって休んでいた。sns の功罪はいろいろあるけど、ネガティブな情報にたくさん触れるのはなかなかしんどいな。何だったかもう忘れたけど、前にもこんなことがあった気がする。そういうときは sns を見ない方がよいのだろうけど、何もしないでいると気になってついつい見てしまう。情報があり過ぎることも問題なんだなとつくづく実感する。

github deployments の調査

22時に寝て23時半に起きて1時に寝て6時に起きた。

ストレッチ

先週に引き続き、右太もも後ろの張り感が強い。もしかしたらここ2-3週間、長時間机に向かっていることが増えて負担がかかっているのかもしれない。2月は寒いから帰って散歩やジョギングすることもなくて余計に筋肉をほぐすこともできていない。今日の開脚幅は開始前164cmで、ストレッチ後160cmで先週と変わらないぐらいだった。調子がよくなかったのか、ストレッチ後にあまり開脚できなかった。たまにこういうときもある。

github deployments の調査

github actions を実行するにはなんらかのトリガーが必要なことから、デプロイのためのトリガーに使えそうなものはないかを Events that trigger workflows で調べていたら deploymentdeployment_status というイベントがあることに気付いた。

わりと最近できた仕組みで github deployments という api 群が提供されている。一度ベーダとして出したものの、アルファレベルだったせいか、gh cli でも専用コマンドとして機能追加されていないし、github の slack インテグレーションでも一度提供した deploy サブコマンドを削除するみたいなことが発生している。まだ設計やインタフェースが使いやすいものではないから作り直すみたいな状況にみえる。とはいえ、rest api は提供されているので現状の機能のまま github actions のトリガーとして使う分には問題なさそう。

ビルドとデプロイを分離するにあたって、デプロイのためのトリガーが github 上のサービスとしてみつかったのはよかったと言える。github deployments は現状では中途半端なサービスという位置づけにみえる。

主作用による副作用

0時に寝て4時半に起きた。6時から金朝ツメトギを聞きながら途中で寝てしまって7時過ぎに起きた。

コミュニケーションについての記事を書く

以前 コミュニケーションコストに考えたこと をベースに、3ヶ月フィードバック の一節としてお手伝い先の社内 wiki に書いた。コミュニケーション一般の話なので私の考えを伝えられるよう、社外秘の部分を削除してブログにまとめておくことにした。ちょっと書き始めたところ、また週末にでも時間があるときに少しずつ推敲したり、洗練させて自身の考えを整理していく。現状でも悪い内容ではないけれど、まだしっくり来ていないところもあって、そのもやもやも見直していきたい。

課題管理の特性

課題管理システムにチケットを作成すると fix しない限り、そのチケットは永遠に残り続ける。未着手の状態でずっと放置することもできるが、それは対応を先送りしているだけで完了するわけでもない。チケットの対応方法として wontfix という選択肢が非常に重要になる。問題があることはわかっていたとしても様々な理由で対応しないという判断はありえる。誰がどういう理由でその判断を下したかという背景や意図さえわかれば、仮に将来的にその問題が看過できない状態になったとしても、過去の判断から新たな対応方法を検討したり、その判断の是非をふりかえることができる。これはチケットを作らずに見てみぬふりをして将来同じことが起きるのとは全く異なる知見が積み重なるので非常に重要な意思決定であると私は考えている。

閑話休題。話しがズレた。ここで fix せずにずっと放置するメンバーもいたりする。様々な理由で課題管理に非協力的な姿勢をとるメンバーがいる。少なからずいる。そういう人を放置すると、真面目に課題管理をやっている人たちが腐ってしまうので、課題管理の専門家を自称する私としては看過できない状況と言える。最初のうちは非協力的なメンバーにお願いしてやってもらうわけだけど、やってくれない人はずっとやってくれない。それを言い続けるのも嫌になるので別の対応方法が求められる。私の経験則では若い人に非協力的なメンバーはほぼいない。いまの若い人は優秀なので上司や先輩のやり方をみて勝手にやる人もいるし、ちゃんと教えれば教えた通りにやってくれる。非協力的なメンバーは往々にしてそれなりの経験をもっている中堅以上の社会人に多い。実はお仕事をさぼっていてあまり作業していないとか、課題管理に馴染みがなければ、それまでの自分の仕事のやり方をアンラーニングできないという人もいるかもしれない。理由はともかく、お願いしてもやってくれない人のチケットが課題管理プロセスの中で浮いてみえてくる。他のメンバーが腐る前に対応しないといけない。私の経験則ではこれはすごく難しい問題であるし、非協力的なメンバーそれぞれの理由にあわせて対応する必要があるので工数もかかる。

課題管理をしたくないというメンバーの中には何らかの理由で自律的に働きたくないという人もいる。課題管理というプロセスにおいては、そういった人たちをあぶり出してしまうため、状況によってはとても難しい人間関係の問題へと発展してしまう。

継続的デリバリーへの第一歩

0時に寝て6時に起きた。

docker object labels と git リビジョン

継続的デリバリーのために snapshot jar のマニフェストから取得した git のリビジョンを docker イメージの labels に追加するサンプルコードを jib-sample に実装してみた。jib の gradle プラグインを作って簡略化すれば便利かもしれない。

java アプリケーションの継続的デリバリー

0時に寝て3時に起きて6時ぐらいまでだらだらして寝て7時に起きた。

snapshot jar と継続的デリバリー

昨日 jar に git のリビジョン番号を含める ことについて書いた。jar から git のリビジョン番号を取得できれば、docker イメージを生成するときに labels に jar の artifact id と git のリビジョン番号のラベルを追加して、docker イメージからもソースコードの追跡ができるようになる。いまデプロイは docker イメージのみで運用しているため、maven のバージョン管理ができなくても docker イメージの追跡可能性さえあれば現実の運用で問題にならないのではないかと考えた。つまり、snapshot jar で開発したものをそのまま本番環境にデプロイするということを意味する。こうすれば特定のバージョン番号を付けるだけのビルドとデプロイが不要になって、テスト環境にデプロイされた docker イメージのテストを完了すれば、そのイメージをいつでも本番環境にデプロイできるようになる。デプロイするタイミングでビルドする必要がなくなるので継続的デリバリーに近づくのではないかと考えた。

今日、開発の偉い人やインフラ担当者も含めて、みんなでわいわい打ち合わせして、現状の開発では、インターフェースや互換性の変更にあわせてバージョン番号を付けていないし、古いバージョンに戻すことも現実にはなく、保守は常に最新のリビジョンを更新していくから maven でバージョン管理できなくなっても snapshot jar の運用でがんがん開発していけばいいんちゃうという合意を得られた。

実際にこのやり方がうまくいくかどうか、私も初めての試みなのでやってみないとわからないが、この運用によるワークフローの効率化のメリットも大きいので、引き続き、イニシアティブをもって取り組んでいきたい。

jar のマニフェストファイル

0時に寝て3時に起きて5時に起きて6時半に起きた。

jar ファイルと git のリビジョン

java パッケージのフォーマットとして jar ファイルがある。開発中の jar ファイルは snapshot という特別なバージョンで管理したりするが、この snapshot と git のリビジョンが対応していないので snapshot jar だけではどのリビジョンのソースからビルドされたかがわからない。jar には JAR File Specification で定義された META-INF/MANIFEST.MF に任意のメタデータを保持できる。maven なら maven git commit id pluginApache Maven JAR Plugin を組み合わせれば、ビルド設定だけで git のリポジトリ情報を任意のメタデータとして jar に含めることができる。試しにプラグインの検証も兼ねてやってみた。例えば、次のようなマニフェストを作れる。

Manifest-Version: 1.0
Created-By: Apache Maven 3.6.3
Built-By: t2y
Build-Jdk: 11.0.13
Specification-Title: My Nice Product
Specification-Version: 1.0
Artifact-Id: my-product
Build-Time: 2022-02-21T11:39:07Z
Git-Branch: main
Git-Commit-Id: 81a4642
Git-Commit-Time: 2022-02-21T19:39:30+0900
Git-Commit-User: Tetsuya Morimoto

java のコードからマニフェストを取得するサンプルコードはこんな感じ。ググるといくつかやり方があるようなので他の実装もある。但し、このコードだと複数の jar のマニフェストを取得してしまうので、あとで自分がみたい jar のマニフェストをフィルターする処理が必要になる。

private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF";

public static Map<String, Manifest> getManifests() throws IOException, URISyntaxException {
    var map = new HashMap<String, Manifest>();
    var resources = MyUtil.class.getClassLoader().getResources(MANIFEST_PATH);
    while (resources.hasMoreElements()) {
        var elem = resources.nextElement();
        var part = elem.toURI().getSchemeSpecificPart();
        if (part != null) {
            try (var stream = elem.openStream()) {
                map.put(part, new Manifest(stream));
            }
        }
    }
    return map;
}

祝日の勤怠

1時に寝て6時半に起きた。昨日は夕方に一旦帰ってきて仮眠したらまた作業しようと思っていたけど、なんかバテてそのままだらだらしてた。

カレンダー共有と祝日

お手伝い先の社員さんと開発メンバーとのお休みがあわない問題が気になるようになってきた。というのは、お手伝い先は基本的に祝日は営業日として扱われている。おそらくは祝日に働いたら手当がつくのか、代休を別の日にとっているようにみえる。祝日に働かずに休む社員もいる。祝日に休むという表現もおかしいが。業務委託の開発メンバーは原則として祝日は休んで普通の日に働く。ここで社員さんが祝日に働いて普通の日に代休をとると、休みが異なるのでコミュニケーションコストが高くなる。お互いが働いている時間が減ることでその時間に対する価値が高くなってしまうという話し。国が違わない限り、あまりそういう状況は発生しないので、休日をあわせることの重要性を再認識した。

さらに働き始めた頃から気になっている カレンダー共有の問題 がある。休みが異なる可能性が高いのにメンバーのカレンダーはばらばらなので、お休みするという報告をもらっていても日が経つと忘れてしまっていて、slack でメンションをしてしまう場合がある。金曜日に月曜日はお休みすると聞いていたけど、月曜日になったら忘れてたみたいな。お休みしている社員さんに普通にメンションして、普通にやり取りしていて、あとでお休みだったと気付いて申し訳なく思った。カレンダーを確認してお休みだとわかっていれば slack でメンションはしなかった。

2021年度の確定申告

0時に寝て6時に起きた。

確定申告

本当は9時から受け付けなんだけど、昨年早めに行ったら受け付けしてくれたので今年も8時半ぐらいから出掛けていった。家から徒歩5分のところに特設の申告会場があって、行ったらすでに100人ぐらいは並んでいた。整理券を配るために行列を誘導している係員に「書類は作成済みで提出だけです」と伝えると「どうぞ、こちらへ」と行列をショートカットして、書類の作成会場の横にある提出会場へ案内される。朝一なので誰も提出してなくてすぐに応対してくれた。書類チェックして提出完了。会場についてから提出するまでに5分。あわせて10分もあれば確定申告できる。電子申告してもよいのだけど、寄付金の領収書の電子化が面倒なのでまだ紙で申告している。寄付金の領収書が電子化されて添付できるような手軽さになったら電子申告してもよいかもしれない。

github container action の検証

jib という java アプリケーション向けの docker イメージをビルドするためのツールがある。お仕事で使い始めたので雰囲気を理解するために私もサンプルアプリケーションを jib-sample として作ってみた。簡単に設定して java アプリケーションを docker 化できるので感触はよさそう。基本的に java アプリケーションと docker は相性が悪くて、たぶん go で開発するような用途と比較するとサイズがめちゃくちゃでかい。それでも jib を使うと作成された docker イメージのサイズも自分でビルドして作るよりは小さくしてくれる。さすが google という感じ。

この jib-sample の docker イメージを使って github actions のカスタム container action を作ってみたのが gh-actions-container-sample になる。Creating a Docker container action のドキュメントには Dockerfile を使ったサンプルしか紹介されていないけど、docker イメージを直接参照して利用することもできる。

検証作業をしているときに jib-sample リポジトリの github packages が private 設定になっていることに気付かなくて少しはまった。リポジトリの visibility 設定と github packages の visibility 設定は連動していないのでそれぞれで別に管理しないといけない。

また jib で作った docker イメージはデフォルトでは manifest を作ってくれない。

$ docker manifest inspect --verbose ghcr.io/t2y/jib-sample:latest
no such manifest: ghcr.io/t2y/jib-sample:latest

How do I specify a platform in the manifest list (or OCI index) of a base image? のドキュメントによると、manifest に platform 情報を追加するのは incubating feature らしくて、なんか条件付きで設定すれば使えそうにもみえたんだけど、私がやってみた感じだとうまくいかなかった。また必要ならもう一度調べてみる。