Chezmoi externals behind a coorporate proxy
Posted in linux on June 17, 2025 by Adrian Wyssmann ‐ 4 min read
As you know I use https://wyssmann.com/blog/2022/08/chezmoi-a-very-cool-tool-to-manage-your-dotfiles/ to manage my dotfiles. One problem I face is using it in corparate environment with proxy that uses kerberos authentication. Just adding the external urls to .chezmoiexternal.toml
will not work ase there is no native kerberos support.
Luckily there is curl
which supports Kerberos authentication with –negotiate. In order to ensure that curl
works by default with --netgotiate
I add the following content into ~/.curlrc
--proxy-negotiate
-u :
The I create a script, that would run at the beginning e.g. run_before_get_packages.sh.tmpl
:
#!/usr/bin/env bash
{{ if eq .chezmoi.os "linux" }}
TARGET_BIN_DIR="{{ .chezmoi.homeDir }}/Downloads/packages"
mkdir -p "$TARGET_BIN_DIR"
chezmoi_version=2.62.6
chezmoi_file=chezmoi_${chezmoi_version}
if [ ! -f $TARGET_BIN_DIR/${chezmoi_file} ]; then
curl https://github.com/twpayne/chezmoi/releases/download/v${chezmoi_version}/chezmoi-linux-amd64 -L -o $TARGET_BIN_DIR/${chezmoi_file}
cp $TARGET_BIN_DIR/${chezmoi_file} $TARGET_BIN_DIR/chezmoi
fi
atuin_version=18.6.1
atuin_file=atuin_${atuin_version}.tar.gz
if [ ! -f $TARGET_BIN_DIR/${atuin_file} ]; then
curl https://github.com/atuinsh/atuin/releases/download/v${atuin_version}/atuin-x86_64-unknown-linux-musl.tar.gz -L -o $TARGET_BIN_DIR/${atuin_file}
cp $TARGET_BIN_DIR/${atuin_file} $TARGET_BIN_DIR/atuin.tar.gz
fi
trivy_version=0.62.1
trivy_file=trivy_${trivy_version}.tar.gz
if [ ! -f $TARGET_BIN_DIR/${trivy_file} ]; then
curl https://github.com/aquasecurity/trivy/releases/download/v${trivy_version}/trivy_${trivy_version}_Linux-64bit.tar.gz -L -o $TARGET_BIN_DIR/${trivy_file}
cp $TARGET_BIN_DIR/${trivy_file} $TARGET_BIN_DIR/trivy.tar.gz
fi
skaffold_version=latest
skaffold_file=skaffold_${skaffold_version}
if [ ! -f $TARGET_BIN_DIR/${skaffold_file} ]; then
curl https://storage.googleapis.com/skaffold/releases/${skaffold_version}/skaffold-linux-amd64 -L -o $TARGET_BIN_DIR/${skaffold_file}
cp $TARGET_BIN_DIR/${skaffold_file} $TARGET_BIN_DIR/skaffold
fi
sonar_version=7.1.0.4889
sonar_file=sonar_${sonar_version}.zip
if [ ! -f $TARGET_BIN_DIR/${sonar_file} ]; then
curl https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${sonar_version}-linux-x64.zip -L -o $TARGET_BIN_DIR/${sonar_file}
cp $TARGET_BIN_DIR/${sonar_file} $TARGET_BIN_DIR/sonar.zip
fi
tflint_version=0.58.0
tflint_file=tflint_${tflint_version}.zip
if [ ! -f $TARGET_BIN_DIR/${tflint_file} ]; then
curl https://github.com/terraform-linters/tflint/releases/download/v${tflint_version}/tflint_linux_amd64.zip -L -o $TARGET_BIN_DIR/${tflint_file}
cp $TARGET_BIN_DIR/${tflint_file} $TARGET_BIN_DIR/tflint.zip
fi
tfupdate_version=0.9.1
tfupdate_file=tfupdate_${tfupdate_version}.tar.gz
if [ ! -f $TARGET_BIN_DIR/${tfupdate_file} ]; then
curl https://github.com/minamijoyo/tfupdate/releases/download/v${tfupdate_version}/tfupdate_${tfupdate_version}_linux_amd64.tar.gz -L -o $TARGET_BIN_DIR/${tfupdate_file}
cp $TARGET_BIN_DIR/${tfupdate_file} $TARGET_BIN_DIR/tfupdate.tar.gz
fi
tfdocs_version=0.20.0
tfdocs_file=tfdocs_${tfdocs_version}.tar.gz
if [ ! -f $TARGET_BIN_DIR/${tfdocs_file} ]; then
curl https://github.com/terraform-docs/terraform-docs/releases/download/v${tfdocs_version}/terraform-docs-v${tfdocs_version}-linux-amd64.tar.gz -L -o $TARGET_BIN_DIR/${tfdocs_file}
cp $TARGET_BIN_DIR/${tfdocs_file} $TARGET_BIN_DIR/tfdocs.tar.gz
fi
posh_version=26.8.0
posh_file=posh_${posh_version}
if [ ! -f $TARGET_BIN_DIR/${posh_file} ]; then
curl https://github.com/JanDeDobbeleer/oh-my-posh/releases/download/v${posh_version}/posh-linux-amd64 -L -o $TARGET_BIN_DIR/${posh_file}
cp $TARGET_BIN_DIR/${posh_file} $TARGET_BIN_DIR/oh-my-posh
fi
{{- end }}
This script will download the packages into {{ .chezmoi.homeDir }}/Downloads/packages
. I currently only download it once - for new versions I have to update the version only here. I also ensure I don’t download it twice. The copy ensures the latest version is always find under the same name, this ensure I don’t have to umpate the .chezmoiexternal.toml
.
Now, once the files are downloaded, I can use .chezmoiexternal.toml
do extract the files into a dedicate place like ~/.local/share/externals/<toolname>
[ ".local/share/externals/trivy/" ]
type = "archive"
url = "file:///home/[email protected]/Downloads/packages/trivy.tar.gz"
exact = true
stripComponents = 1
refreshPeriod = "168h"
executable = true
[ ".local/share/externals/atuin/" ]
type = "archive"
url = "file:///home/[email protected]/Downloads/packages/atuin.tar.gz"
exact = true
stripComponents = 1
refreshPeriod = "168h"
executable = true
[ ".local/share/externals/tflint/" ]
type = "archive"
url = "file:///home/[email protected]/Downloads/packages/tflint.zip"
exact = true
stripComponents = 1
refreshPeriod = "168h"
executable = true
[ ".local/share/externals/tfdocs/" ]
type = "archive"
url = "file:///home/[email protected]/Downloads/packages/terraform-docs.tar.gz"
exact = true
stripComponents = 1
refreshPeriod = "168h"
executable = true
[ ".local/share/externals/skaffold/skaffold" ]
type = "file"
url = "file:///home/[email protected]/Downloads/packages/skaffold"
exact = true
stripComponents = 1
refreshPeriod = "168h"
executable = true
[ ".local/share/externals/oh-my-posh/oh-my-posh" ]
type = "file"
url = "file:///home/[email protected]/Downloads/packages/oh-my-posh"
exact = true
stripComponents = 1
refreshPeriod = "168h"
executable = true
Now I have all (extracted) files in the same folder. At last, I will iterate over the folders and create a symlink to {{ .chezmoi.homeDir }}/.local/bin
so I only have to add this folder to the PATH
envioronment variable, so even adding a packed does not require updating the PATH
#!/usr/bin/env bash
{{ if eq .chezmoi.os "linux" }}
TARGET_BIN_DIR="{{ .chezmoi.homeDir }}/.local/bin"
SOURCE_BIN_DIR="{{ .chezmoi.homeDir }}/.local/externals"
mkdir -p "$TARGET_BIN_DIR"
for d in $SOURCE_BIN_DIR/*/ ; do
echo "Executables in $d"
for f in $d/* ; do
echo "files $f"
if [[ $f =~ "*" ]]; then
echo "no binaries"
else
base_name=$(basename ${f})
ln -sf $f "$TARGET_BIN_DIR/$base_name"
fi
done
done
{{- end }}
So now when I run chezmoi apply
the script will run and download the files
...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 131 100 131 0 0 401 0 --:--:-- --:--:-- --:--:-- 400
...
At last, the sym link is created
...
gpg: encrypted with 1 passphrase
Executables in /home/[email protected]/.local/externals/atuin/
files /home/[email protected]/.local/externals/atuin//atuin
Executables in /home/[email protected]/.local/externals/oh-my-posh/
files /home/[email protected]/.local/externals/oh-my-posh//oh-my-posh
Executables in /home/[email protected]/.local/externals/trivy/
files /home/[email protected]/.local/externals/trivy//trivy
Executables in /home/[email protected]/.local/externals/zellij/
files /home/[email protected]/.local/externals/zellij//zellij
Executables in /home/[email protected]/.local/externals/zoxide/
files /home/[email protected]/.local/externals/zoxide//zoxide
...
Unfoortunatley it does not work as expected - see Github Discussion as apply fails with
chezmoi apply
chezmoi: open /home/[email protected]/Downloads/packages/atuin_8.6.2.tar.gz: no such file or directory
So currently I have to
- Comment out the relevant section in
.chezmoiexternal.toml.tmpl
- Run
chezmoi apply
- Ucomment the relevant section in
.chezmoiexternal.toml.tmpl
- Run
chezmoi apply
Hope I find a better solution soon. Luckily at home I use NixOS so I have my packages at hand. But sometimes you have to use the distro your company offers you which may lack of desired packages, so these quirks are necessary.