Я пытаюсь настроить фильтр clean / smudge в git для автоматического шифрования и дешифрования файлов, содержащих секреты, через команду ansible-vault .
Особенность команды ansible-vault в том, что она не идемпотентна (она создает новый двоичный файл каждый раз, когда она вызывается для одних и тех же данных).
Я начал с реализации, предложенной на этой странице блога . К сожалению, это не сработало правильно, так как всякий раз, когда вызывается smudge (будь то проверка git или просто состояние git), секретные файлы выглядят измененными для git, даже если это не так.
Поэтому я подумал, будет ли git сравнивать двоичный файл, который он имеет в индексе, с текущим файлом с чистой фильтрацией, и я попытался построить этот скрипт следующим образом:
#!/bin/sh -x
# clean filter, it is invoked with %f
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
# get the plain text from the binary in the index
tmphead=`mktemp`
git show HEAD:$1 > $tmphead
contenthead=`echo "embedded" | ansible-vault view $tmphead --vault-password-file=$HOME/.vault_password`
export PAGER=cat
echo -n "$contenthead" | tee $tmphead
# if current and index plain text version differ
if [ "`md5sum $tmp | cut -d' ' -f1`" != "`md5sum $tmphead | cut -d' ' -f1`" ]; then
tmpcrypt=`mktemp`
cp $tmp $tmpcrypt
# generate a new crypted blob
echo "embedded" | ansible-vault encrypt $tmpcrypt --vault-password-file=$HOME/.vault_password > /dev/null 2>&1
cat "$tmpcrypt"
else
# just return the HEAD version
cat "$tmphead"
fi
rm $tmp $tmphead $tmpcrypt
Разница здесь в том, что он пытается сравнить текущие и HEAD-версии секретных файлов в виде простого текста (незашифрованные) и только в случае их различия выводит новый двоичный двоичный объект, зашифрованный с помощью ansible-vault.
К сожалению, после этого изменения git продолжает думать, что секретный файл всегда изменяется. Даже после git add
повторного создания файла, чтобы вычислить git blob, git считает, что файл отличается, и позволяет изменениям перейти в фиксацию. Обратите внимание, что git diff
возвращайте пустые изменения, как и должно быть.
Для справки, это пятно:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
tmp=`mktemp`
cat > $tmp
export PAGER='cat'
CONTENT="`echo "embedded" | ansible-vault view "$tmp" --vault-password-file=$HOME/.vault_password 2> /dev/null`"
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
echo "Looks like one file was commited clear text"
echo "Please fix this before continuing !"
exit 1
else
echo -n "$CONTENT"
fi
rm $tmp
и это diff:
#!/bin/sh
if [ ! -r "$HOME/.vault_password" ]; then
exit 1
fi
export PAGER='cat'
CONTENT=`echo "embedded" | ansible-vault view "$1" --vault-password-file=$HOME/.vault_password 2> /dev/null`
if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
cat "$1"
else
echo "$CONTENT"
fi
-n
из эха пятна, но это предположение. Нет скрытого параметра для git diff, говорящего игнорировать окончания одной строки?