Posts for: #Windows

継続の習慣

1時に寝て4時に起きて2時間ほどだらだらして7時半に起きた。

今日の筋トレは腹筋:15x1,腕立て:15x1,スクワット20x1をした。

雑多な作業

virtualbox に windows server 2022 のインストールと Active Directory ドメインサービスの構築 する方法のドキュメントを書き終えた。年度が変わったら新卒のメンバーがチームに入る可能性もあるし、滅多にやらない作業だし、windows のことを私はよく知らないので整理しておくとよい気がした。その後、メンバーのツール開発やインフラ作業のアドバイスややり取りなどをしていたら時間が経ってしまった。

テックブログを読む会

年を明けて初めての テックブログ一気読み選手権20240122杯 に参加した。次の記事を読んで他の参加者に共有した。

この30分イベントのためにテックブログを読むことを強制されるのがよい。この日記を始めたことで「書くこと」と最近は「筋トレ」も継続できるようになった。短い時間の継続を目的とした仕組みをもっとうまく取り入れて他にも応用していきたいと思う。

ローカルに window server をインストールした

1時過ぎに寝て6時半に起きた。久しぶりによく眠れた。6時半に起きてたのに8時ぐらいまでだらだらしてた。

今日の筋トレは腹筋:20x1,腕立て:15x1,スクワット20x1をした。

windows server 2022 試用版のインストール

Windows Server 2022 の試用版が提供されていると知ったのでローカルの VirtualBox 環境にインストールしてみた。Active Directory の検証に使うのでディレクトサービスや ldaps 接続のための証明書サービスなどを設定する。メンバーがインストールして課題管理システムにメモを残してくれてあったのでそれを見ながらインストールや設定自体はすぐにできた。1つだけうまく接続できないことがあった。

ホスト os から ldapsearch で ldaps で接続しようとすると次のようなエラーになる。

$ ldapsearch -x -H "ldaps://192.168.56.101" -W -b "CN=Users,DC=myad,DC=com" -D "CN=Administrator,CN=Users,DC=myad,DC=com"
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

ldap では接続できるので tls の検証のチェックに失敗していることは自明だったが、メンバーは接続できているようにみえたので私の環境の設定が誤っているのかどうかを調べていた。2時間ぐらいデバッグしたりしながら調べてもよくわからなくて、たまたまチーム勉強会があったので終わったときにメンバーに聞いてみた。すぐに完結した。ldapsearch は LDAPTLS_REQCERT という環境変数で tls のリクエストの振る舞いを制御できる。次のように明示的に指定すると接続できる。

$ LDAPTLS_REQCERT=never ldapsearch -x -H "ldaps://192.168.56.101" ...

この設定はいくつかの方法で設定ファイルに書いておくこともできる。メンバーが使っている環境には ldap.conf でこの設定を有効にしていたので ldaps 接続できていたというオチだった。私が openldap について明るくないのでこういった背景知識をもっていなくてはまっていただけだった。

Thus the following files and variables are read, in order:
    variable     $LDAPNOINIT, and if that is not set:
    system file  /etc/openldap/ldap.conf,
    user files   $HOME/ldaprc,  $HOME/.ldaprc,  ./ldaprc,
    system file  $LDAPCONF,
    user files   $HOME/$LDAPRC, $HOME/.$LDAPRC, ./$LDAPRC,
    variables    $LDAP<uppercase option name>.
Settings late in the list override earlier ones.

明石海峡大橋海上ウォーク

神戸ジャーナルの記事をみかけて、そういうイベントがあるのは知っていた。

開発合宿の翌週だし、わざわざ行くほどでもないかとスルーしていたものの、関東から知人がわざわざ歩きに来るという話しを聞いて、せっかくの機会なので私も参加することにした。土曜日の午前中に明石海峡大橋を歩いてくる。まだ申込みが始まったばかりなので希望の時間帯を選択できると思う。

リリース延期

3時に寝て7時に起きた。昨日は遅くまで確定申告の準備をしてたから寝坊した。その分8時半に申告会場に立ち寄ってからオフィスに出社したので普段よりも朝はゆっくりできた。

windows インストーラー開発

windows のインストーラーを作る方法は2-3種類ほどあるそうだけど、もっとも標準的な visual studio に付属しているツールでインストーラーを作っている。特性の違う2つのアプリケーションを1つのインストーラーで扱っていると、アップデートやアンインストールでいろいろ不都合が生じるように思えたのでインストーラーを2つに分割したらよいのではないか?と先週末に助言をしていた。すると、1つのアプリケーションを2つのインストーラーを使ってセットアップするようなものを作ってしまって、複雑さはなにも解消していなくて、全然意図したものではないと訂正して作り直してもらうことになった。

私の指示が2つに分割すればよいという曖昧な助言だったのもよくないけれど、1つのアプリケーションを2つのインストーラーで操作するという発想が私の中になくて勘違いする余地があったんやと失敗体験となった。

一方でメンバーが「最初からそう言ってくれればよかったのに、、、」とか言い始めて、この姿勢はよくないなとも感じた。この問題の責任は指示が曖昧だった私にあるのは間違いないが、1つのアプリケーションを2つのインストーラーでインストールするという考え方に疑問を抱かないのは怠慢だし、実際にそのやり方で問題は解決していなかった。なんのために設計するかを当事者意識をもって開発していたら、言ってくれなかったから分からなかったという考え方にはならない。勘違いしていたとか、気付きが足りなかったとか、そういう言葉がほしかった。

定例会議で、意図しているのは、特性の違う2つのアプリケーションをそれぞれ独立させて制御すればシンプルになるよと説明して、もう一度作り直してもらって、結果として意図した通りシンプルにインストールを扱えるようになった。

リリース延期

昨日書いた通り、基準となる issue をすべて fix できないことが確認できたのでそれを説明して4月末まで延期とした。これにより、遅れていた機能開発には十分な期間を取れるし、QAテストのための準備にも余裕をもてる。インフラやドキュメントを整備する時間もあるだろう。

今月の私の稼働時間は (契約は160時間だけど) おそらく200時間を余裕で越えるだろうし、記帳していない稼働時間も含めれば230時間ほどはいくのではないかと思う。私の中では納期に間に合わせるためにがんばる意思はあったんだけど、クリティカルパスはすべて私が担当するといった調整をできなかったので仕方ないなといった落とし所で来月への延期を正当化した。

windows のサービス起動を go から制御する

2時に寝て3回ほど起きて7時に起きた。淡々と自分の機能開発をしていた。ある処理が失敗したときにローカルのファイルシステムに暗号化して書き込み、定期的にそのディレクトリを監視してファイルがあれば読み込んで復号化してリトライをするといった仕組みを実装した。とくに難しくなくすぐにできた。

晩ご飯に 大衆酒場 PING (ピン) というお店に行ってみた。1人でも入りやすく値段も安く食べ応えもあっても私のイメージする居酒屋さんの印象にぴったりでよかった。また出張したら行こうと思う。そろそろ出張でバテてきたので今日は夜にお仕事せずに晩ご飯食べてからもテレビをみながらだらだらしてた。

windows のサービス起動

準標準パッケージである golang.org/x/sys パッケージを使ってアプリケーションの起動と停止をサービス管理画面から操作できるようにする。サンプルコードは次の場所にある。

サービスから呼ばれたかどうかを判定をすることでエントリーポイントを切り替えられる。

inService, err := svc.IsWindowsService()
if inService && err == nil {
    if err := runService(serviceName, false); err != nil {
        log.Error("failed to run service", map[string]any{
            "err": err,
        })
        return
    }
}

そして、次のような Execute() メソッドをもつ windows サービスから呼ばれる構造体を定義して、そのメソッド内でサービス管理画面からのステータス変更に対応する状態遷移のコードを実装すればよい。ここではサービス開始してから stop/shutddown で停止するぐらいしか必要ないのでシンプルに実装した。一時停止や再開も必要ならもう少し複雑なコードになる。

type myService struct{}

func (m *myService) Execute(
	args []string, reqCh <-chan svc.ChangeRequest, statusCh chan<- svc.Status,
) (ssec bool, errno uint32) {
	ctx, cancel := context.WithCancel(context.Background())
	ch := startMyService(ctx, getConfig())
	statusCh <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown}
	stop := false
	for {
		select {
		case c := <-reqCh:
			switch c.Cmd {
			case svc.Stop, svc.Shutdown:
				stop = true
				cancel()
				break
			}
		}
		if stop {
			break
		}
	}
	statusCh <- svc.Status{State: svc.StopPending}
	<-ch // wait until MyService would be completed
	return
}

イベントログに書き込む

1時に寝て2時ぐらいから吐き気で3時間ほど苦しんで寝て9時に起きた。バテてきた。10時過ぎからオフィスへ行ってだいたい丸一日お仕事してた。

go のマルチプラットフォーム対応

いま作っているモジュールは windows/linux の両方で動くモジュールにする必要がある。go は標準でそういったモジュールの開発に対応していて Build Constraints にビルドタグの仕様が書いてある。例えば、ログ出力を linux では標準出力に windows ではイベントログに書き込みたいとか。windows のイベントログに書き込むのも準標準パッケージである golang.org/x/sys パッケージを使ってすぐにできた。私がイベントログの仕様をよく知らないのでイベントログそのもののインストール作業をどうするかという課題がある。これは詳しい人に教えてもらおう。ビルドタグには unix という設定が使える。これで linux/macos 対応になる。例えば、log 出力のインターフェースをそれぞれ分けたいときに次のように実装できる。windows は標準ロガーに加えてイベントログにも書き込むようにしてみた。この log パッケージを使う呼び出し側のコードはマルチプラットフォームの違いを意識する必要はない。とても簡単にマルチプラットフォームのコードを管理できる。go のビルドやコンパイラの仕組みを学ぶたびに感心する。

//go:build unix

package log

func Error(msg string, fields map[string]any) error {
	return mylogger.Error(msg, fields)
}

func Warn(msg string, fields map[string]any) error {
	return mylogger.Warn(msg, fields)
}
//go:build windows

package log

import (
	"golang.org/x/sys/windows/svc/eventlog"
)

const (
	// this logName should be installed in advance
	logName = "mylog"
	eventID = 1 // TODO
)

var elog *eventlog.Log

func init() {
	var err error
	elog, err = eventlog.Open(logName)
	if err != nil {
		mylogger.ErrorExit(err)
	}
}

func Remove() {
	eventlog.Remove(logName)
}

func Error(msg string, fields map[string]any) error {
	elog.Error(eventID, getMessage(msg, fields))
	return mylogger.Error(msg, fields)
}

func Warn(msg string, fields map[string]any) error {
	elog.Warning(eventID, getMessage(msg, fields))
	return mylogger.Warn(msg, fields)
}

お土産探し

いつもは東京出張のタイミングにあわせてお店やお菓子探しから時間をかけて、自分でも買って試食してみて選択している。今回は2週間前から土日もずっと開発していて余裕がない。前回は 本髙砂屋の金つば を持って行った。本髙砂屋は金つばの老舗なのだけど、洋菓子も販売していて和菓子のお店の隣に洋菓子のお店も構えている。 今回も本髙砂屋にあやかって洋菓子の エコルセ の季節限定で売っている詰め合わせバージョンを購入してみた。「貧すれば鈍する」とよく言ったものでお土産探しの時間すらかけられなくなってしまっている。15時半頃から出かけて本髙砂屋さんで購入した。今回は試食できていないけど老舗だからあまり心配はいらないとは思う。

windows の調査を開始

1時に寝て7時過ぎに起きた。やや飲み過ぎて、2日酔いではないけど起きたときは気分が悪かった。

go-winio を触ってみた

windows 向けのモジュールを作り直すにあたり、有識者のサポートをお願いしているものの、私も最低限の知識はないとあかんやろと調査を開始した。microsoft/go-winio というライブラリが ms 社のリポジトリで公開されている。公式ならよいのだろうと安易に考えて触ってみたものの、ドキュメントがほとんどなくて、まず使い方がわからん。いまのところ、windows に詳しい人向けのライブラリみたい。ひとまずリポジトリにある pipe_test.go のテストコードを読みながら名前付きパイプを介したプロセス間通信をやってみた。一応は動いたのでここから内部の windows api の仕様や設定などをみていく。その過程で go-winio のチュートリアルがないのであれば、私がテックブログを書いてもよいのかもしれない。

チュートリアル的に書いてみたコードは次の通り。

課題管理勉強会

出張のときに毎月の課題管理勉強会。とくにネタが思いつかなかったので エンジニアリング組織論への招待 を題材にしてみた。資料はすでに作ってあった 。私にとっては課題管理をやる意義や価値の大半がこの書籍の中で解説されている。用語や考え方のところでとても参考になるし、いまメンタリングの技術の章を読み直したりもしている。昔はマネージャーやってなかったからその章は読み飛ばしてた。開発組織向けの組織論を解説した書籍でこれ以上のものは、いまのところ、私が読んだ本の中では知らない。4年前に読んだ本を、今回の勉強会を開く機会でまた読み直すきっかけにもなってよかった。本はコンテキストがきれいに構成されているので他の人の所感や意見を聞いたり雑談したりする題材としてもよさそうに思える。

車で行きたい場所

23時に寝て5時に起きて7時半に起きた。軽く二度寝しようと思ったらちょっと寝坊した。

windows アプリケーション開発に関わる

ある windows モジュールの開発をやり直しことにしたのでその仕切り直しのキックオフに参加する。もう10年以上前の sier にいた頃は windows サーバーで oracle を動かしたり、vb6 のアプリケーション開発をやっていたりしたけれど、その後は windows アプリケーションの開発に関わったことはないのでまったく windows サーバーの知見はない。別チームから有識者に入ってもらって既存のモジュールを開発し直すことになった。私が実装するわけではないけれど、せっかくなので最近の windows の振る舞いを調べて仕組みを再確認する機会としたい。

ニッポンの絶景

たまたま帰ったときにテレビでやっていた 林修のニッポンドリル 学者が選ぶ!春に見るべきニッポンの絶景ベスト24 をみた。 コロナ禍がひと段落したらインバウンドも戻るのかなという話題にあう、日本で観光するとよいところを紹介していた。出てくる風景がすごいのもあって、死後の世界だとか、桃源郷だとか、たしかにこんな場所あるんやなと思えておもしろかった。

この中に 兵庫県朝来市の竹田城跡 が出てくる。本題じゃないけど、このサイトの構成がややおかしいと思う。スマホファーストなのは分かるけど、ちゃんとした業者に作ってもらえばよいのにと思ってしまった。閑話休題。竹田城跡は天空の城とも呼ばれる、知る人ぞ知る名勝であることは間違いなくて、私も1度は行ってみたいと考えている。ちょうど車も入手したところなので今年こそは行ってみたいと思う。それでよかったら会社の開発合宿やコミュニティのイベントなどにも応用していきたいと思う。都会にはない、地元のよいところや観光資源を活かして地域に貢献できるようにしたいという想いは歳を経るごとに感謝の気持ちとセットで実感できるようになってきた気がする。