Closed17

devContainer/codespaces時代のdotfiles

inomotoinomoto
  • 各種fish環境の移設
  • コンテナ環境下のshell historyをなんか考える(揮発させたくない) -> fishでは無理
  • secret files
inomotoinomoto

これまでのshell環境ではsecret系のファイルをs3に退避しておいて環境構築時にとってくる&linkするという運用をしていたが、そもそもこれいるのか?という観点。

ssh

githubの認証がhttpsになったので、もう秘密鍵いらんのでは?説。サーバへのsshもほぼ無い&やるとしたらssmだし。

ssh configもaws-ssm用のやつくらいしかなく、これはsecretではないので公開でok。

その他仕事だと色々ありそうだが、その手のは個人管理ではないので範囲外。

aws

awscliで生成可能とはいえちと面倒。特にぼくの場合はログインユーザと実行ロールの分離・MFAをしているので。

とはいえ変更されるものでもないので、aws cloudshellあたりにでも置いとけばいいかも。環境構築の都度そこからコピーしてくる的な。

history

これは難しい...流石になくすのは無理...

しかしこれは現在のhardlink運用が厳しい(fishが時々ファイルを作り直してしまう)ので、何か独立した別の手段にしてもいいかも。

昔と違い、今は複数マシンで同期するということをしていないので、いくらかハードルは低いと思われる。

-> やっぱ諦める。卒業。

inomotoinomoto

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}
inomotoinomoto
  • account_number: aws sts get-caller-identity | jq -r '.Account'
  • login_user_name, admin_role_name: 決め打ち
  • key, secret: 既存のを取得はできなそう。別に都度生成で困らなそうなのでそれで
    • たまーに別PCで使うとかあるかもだが、そのときはcloudshellでやる
inomotoinomoto

またわけのわからない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にでも書いておく。

inomotoinomoto

historyはコンテナ内でも無理だし、一周回って秘伝のhistoryから卒業することに。

inomotoinomoto

そもそもどんなファイルをどんな構成で置くか。

  • コンテナ(各言語の開発環境)に入れるもの
  • 親のshell環境(WSL)に入れるもの
  • その他デスクトップ環境用・自作スクリプトなど

現在のdotfilesはリポジトリ直下にいわゆるdotfilesを置かず、home以下に置いている。
ファイル数少ないので直展開でもよいのだが、まぁinstall.shでカスタムできることだしこのままで。

コンテナに入れるものはいわゆるdotfiles + apt installできるものに留める。コンテナなので。
親shellにはコンテナ用 + ansibleでセットアップするものを入れる。セットアップスクリプトは別になりそう。
コンテナの方は冪等性が確保できないが、それが気になるような処理はしない方針。

inomotoinomoto

なおinstall.shは通常ユーザ(vscodeユーザ)で実行されるもよう。

install.sh
#!/bin/bash

whoami > /tmp/whoami

またコンテナビルドログにstdoutっぽいのは見えなかった。whoamiだけだとちとわからず。

なおコンテナ内のvscodeユーザはパスワードなしsudoができる。

inomotoinomoto

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とすると反映される...が、使わないよね...

これより、bash以外のshellを使いたい・devcontainer.json(リポジトリのコード)にshellの好みを持ち込まないためには、vscodeのsettings.jsonにてterminal.integrated.shell.linuxを設定した上でdevcontainer.jsonの同設定を消すことが必要。

...そんな人がいるのかいるのか知らんが、WSLとコンテナ内で別shellを使う・コンテナ内ではWSL側に無いshellを使う、というのはできない。

inomotoinomoto

fish configが微妙に外部スクリプトに依存していたりするので整理が必要。具体的には以下となった。

  1. tmuxでwindow?名に出す名前を出すスクリプトがリポジトリの別のところに置いてある。普段はPATH通ってるので使えるが、コンテナには入れなかった(tmux使わないので)
  2. そのスクリプトが依存するスクリプトをfishのプロンプトから使っていた
  3. コンテナ内にはないスクリプトなので詰む
inomotoinomoto

コンテナ内のfish historyを残すには

  • 規定のfish historyのディレクトリをホストからマウント
  • なんらかプロジェクトディレクトリにhistoryを置く

あたりが考えられるが、前者をやるにはdevcontainer.jsonを書き換えるしか無い。
後者はfish historyのパスを変更することはできないし、そもそもマウントなのでsymlinkやhardlinkもできないのでダメ。

さらっと諦めると色々スッキリしそうだなということに。
なおbashやzshだとhistory pathを変更できるので問題ない。

inomotoinomoto

コンテナ前提の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初期だと多分無い?気がするし。

inomotoinomoto

WSL用のセットアップ(ansibleなど)は、上記install.shのあとにtest -z "$WSLENV" && exitを書いたあとにそのまま書くことに。

コンテナ開発を前提にするとansibleの中身はかなりスッキリするのだが、会社マシンの兼ね合いがあるので一旦そのまま。

inomotoinomoto

コンテナ用のinstall.shはdotfilesリポジトリが既にcloneされている前提なのでこれではダメだった。
wsl用のスクリプトを呼び出し、その途中でこれを呼ぶ感じか。

inomotoinomoto

ところで普段とコンテナのshell設定を完全に一緒にすると、今wsl側なのかコンテナなのか見分けがつかない(プロンプト一緒なので)。

環境変数を見てアイコンとか付けてもよいかもと思ったが、そもそもプロンプトに出すべき情報が普段のとコンテナのとで違うので、根本的に内容を変えるのがよさそう。
(gitリポジトリ名を出しているけどコンテナの場合はそれはわかりきっているなど)

このスクラップは2021/01/02にクローズされました