devContainer/codespaces時代のdotfiles
- 各種fish環境の移設
-
コンテナ環境下のshell historyをなんか考える(揮発させたくない)-> fishでは無理 - secret files
これまでのshell環境ではsecret系のファイルをs3に退避しておいて環境構築時にとってくる&linkするという運用をしていたが、そもそもこれいるのか?という観点。
ssh
githubの認証がhttpsになったので、もう秘密鍵いらんのでは?説。サーバへのsshもほぼ無い&やるとしたらssmだし。
ssh configもaws-ssm用のやつくらいしかなく、これはsecretではないので公開でok。
その他仕事だと色々ありそうだが、その手のは個人管理ではないので範囲外。
aws
awscliで生成可能とはいえちと面倒。特にぼくの場合はログインユーザと実行ロールの分離・MFAをしているので。
とはいえ変更されるものでもないので、aws cloudshellあたりにでも置いとけばいいかも。環境構築の都度そこからコピーしてくる的な。
history
これは難しい...流石になくすのは無理...
しかしこれは現在のhardlink運用が厳しい(fishが時々ファイルを作り直してしまう)ので、何か独立した別の手段にしてもいいかも。
昔と違い、今は複数マシンで同期するということをしていないので、いくらかハードルは低いと思われる。
-> やっぱ諦める。卒業。
awsについて、生成したいconfigが
[default]
region = ap-northeast-1
mfa_serial = arn:aws:iam::{account_number}:mfa/{login_user_name}
role_arn = arn:aws:iam::{account_number}:role/{admin_role_name}
source_profile = login_user
[profile login_user]
region = ap-northeast-1
credentialsが
[login_user]
aws_access_key_id = {key}
aws_secret_access_key = {secret}
- account_number:
aws sts get-caller-identity | jq -r '.Account'
- login_user_name, admin_role_name: 決め打ち
- key, secret: 既存のを取得はできなそう。別に都度生成で困らなそうなのでそれで
- たまーに別PCで使うとかあるかもだが、そのときはcloudshellでやる
またわけのわからないshell scriptを生み出してしまった...
#!/bin/bash
set -eu
# check for env vars exist
echo "generate config for"
echo "login_user: $LOGIN_USER"
echo "admin_role: $ADMIN_ROLE"
ACCOUNT=$(aws sts get-caller-identity | jq -r '.Account')
REGION="ap-northeast-1"
echo "---.aws/config---"
tmpl=$(cat <<EOS
[default]
region = REGION
mfa_serial = arn:aws:iam::ACCOUNT_NUMBER:mfa/LOGIN_USER
role_arn = arn:aws:iam::ACCOUNT_NUMBER:role/ADMIN_ROLE
source_profile = login_user
[profile login_user]
region = REGION
EOS
)
echo "$tmpl" | \
sed s/ACCOUNT_NUMBER/$ACCOUNT/g | \
sed s/REGION/$REGION/g | \
sed s/LOGIN_USER/$LOGIN_USER/g | \
sed s/ADMIN_ROLE/$ADMIN_ROLE/g
echo ''
echo "---.aws/credentials---"
echo '[login_user]'
aws iam create-access-key --user-name $LOGIN_USER | \
jq -r '.AccessKey | .AccessKeyId, .SecretAccessKey' | \
sed '1s/^/aws_access_key_id = /' | \
sed '2s/^/aws_secret_access_key = /'
# delete old access-key
aws iam list-access-keys --user-name $LOGIN_USER | \
jq -r '.AccessKeyMetadata[] | .CreateDate + "\t" + .AccessKeyId' | \
sort | head -n 1 | cut -f 2 | \
xargs aws iam delete-access-key --user-name $LOGIN_USER --access-key-id
aws cloudshellの中で使う想定。LOGIN_USERとADMIN_ROLEはbashrcにでも書いておく。
historyはコンテナ内でも無理だし、一周回って秘伝のhistoryから卒業することに。
そもそもどんなファイルをどんな構成で置くか。
- コンテナ(各言語の開発環境)に入れるもの
- 親のshell環境(WSL)に入れるもの
- その他デスクトップ環境用・自作スクリプトなど
現在のdotfilesはリポジトリ直下にいわゆるdotfilesを置かず、home以下に置いている。
ファイル数少ないので直展開でもよいのだが、まぁinstall.shでカスタムできることだしこのままで。
コンテナに入れるものはいわゆるdotfiles + apt installできるものに留める。コンテナなので。
親shellにはコンテナ用 + ansibleでセットアップするものを入れる。セットアップスクリプトは別になりそう。
コンテナの方は冪等性が確保できないが、それが気になるような処理はしない方針。
なおinstall.shは通常ユーザ(vscodeユーザ)で実行されるもよう。
#!/bin/bash
whoami > /tmp/whoami
またコンテナビルドログにstdoutっぽいのは見えなかった。whoami
だけだとちとわからず。
なおコンテナ内のvscodeユーザはパスワードなしsudoができる。
devContainer内のデフォルトshellは一体どうなるのか。設定できそうなのは
- vscodeのsettings.json,
terminal.integrated.shell.linux
- devcontainer.json,
settings.terminal.integrated.shell.linux
- shellの中のchsh
だが、試してわかったことは
-
terminal.integrated.shell.linux
はvscodeのsettings.jsonよりdevcontainer.jsonのが優先度が高い(わかる) - devcontainer.jsonに設定がなければsettings.jsonのがfallbackされる。それもなければ
/bin/bash
っぽい挙動(デフォルトなのかな) - chshは動かない(意味がない)。vscode内terminalで別タブを開いても変わらないし、dotfilesの初期セットアップのはvscode設定に上書きされる
- vscodeのterminalでchshしたあとに明示的に
sudo su -u vscode
とすると反映される...が、使わないよね...
- vscodeのterminalでchshしたあとに明示的に
これより、bash以外のshellを使いたい・devcontainer.json(リポジトリのコード)にshellの好みを持ち込まないためには、vscodeのsettings.jsonにてterminal.integrated.shell.linux
を設定した上でdevcontainer.jsonの同設定を消すことが必要。
...そんな人がいるのかいるのか知らんが、WSLとコンテナ内で別shellを使う・コンテナ内ではWSL側に無いshellを使う、というのはできない。
fish configが微妙に外部スクリプトに依存していたりするので整理が必要。具体的には以下となった。
- tmuxでwindow?名に出す名前を出すスクリプトがリポジトリの別のところに置いてある。普段はPATH通ってるので使えるが、コンテナには入れなかった(tmux使わないので)
- そのスクリプトが依存するスクリプトをfishのプロンプトから使っていた
- コンテナ内にはないスクリプトなので詰む
コンテナ内のfish historyを残すには
- 規定のfish historyのディレクトリをホストからマウント
- なんらかプロジェクトディレクトリにhistoryを置く
あたりが考えられるが、前者をやるにはdevcontainer.jsonを書き換えるしか無い。
後者はfish historyのパスを変更することはできないし、そもそもマウントなのでsymlinkやhardlinkもできないのでダメ。
さらっと諦めると色々スッキリしそうだなということに。
なおbashやzshだとhistory pathを変更できるので問題ない。
コンテナ前提のinstall.shはパッケージインストールとconfigのsymlinkだけになった。
sudo apt-get update
sudo apt-get install -y colordiff direnv fish git jq neovim peco tig
# devcontainer create .config AFTER this script run.
# So 'ln -s $PWD/home/.config $HOME/.config' doesn't work.
mkdir -p $HOME/.config
CONF_ROOT=$(pwd -P)/home/.config
ls -1 $CONF_ROOT | xargs -ISRC ln -s $CONF_ROOT/SRC $HOME/.config/
gitやjqなど、コンテナにデフォルトで入ってるのもあるが、使うものとして明示的に記述しておく。wsl初期だと多分無い?気がするし。
WSL用のセットアップ(ansibleなど)は、上記install.shのあとにtest -z "$WSLENV" && exit
を書いたあとにそのまま書くことに。
コンテナ開発を前提にするとansibleの中身はかなりスッキリするのだが、会社マシンの兼ね合いがあるので一旦そのまま。
コンテナ用のinstall.shはdotfilesリポジトリが既にcloneされている前提なのでこれではダメだった。
wsl用のスクリプトを呼び出し、その途中でこれを呼ぶ感じか。
ところで普段とコンテナのshell設定を完全に一緒にすると、今wsl側なのかコンテナなのか見分けがつかない(プロンプト一緒なので)。
環境変数を見てアイコンとか付けてもよいかもと思ったが、そもそもプロンプトに出すべき情報が普段のとコンテナのとで違うので、根本的に内容を変えるのがよさそう。
(gitリポジトリ名を出しているけどコンテナの場合はそれはわかりきっているなど)
とりあえずの落ち着きを見た。 https://github.com/cumet04/dotfiles/pull/12
プロンプトはまたそのうち考える。