Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions clean_inventory.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#! /usr/bin/env bash
set -u

lockfile=/opt/ccc-manager/commit.lock
inventory_dir=${CCC_INVENTORY_DIR:-/opt/ccc-inventory}

function cleanup() {
rm -f "$lockfile"
}

function error() {
echo "$1"
cleanup
exit 1
}

if [[ -e "$lockfile" ]]; then
error 'Could not acquire lock. Try again.'
fi
touch "$lockfile"
trap cleanup EXIT
Comment on lines +4 to +21

cd "$inventory_dir" || error "Inventory directory not found: $inventory_dir"

git rebase --abort >/dev/null 2>&1 || true
git merge --abort >/dev/null 2>&1 || true

upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)
if [[ -z "$upstream" ]]; then
branch=${CCC_INVENTORY_BRANCH:-$(git branch --show-current)}
if [[ -z "$branch" ]]; then
error 'Could not determine inventory branch to reset'
fi
upstream="origin/$branch"
fi

git fetch --prune || error 'Could not fetch remote changes'
git reset --hard "$upstream" || error "Could not reset inventory to $upstream"
git clean -fd || error 'Could not remove untracked inventory files'

echo "Inventory reset to $upstream"
cleanup
trap - EXIT
42 changes: 35 additions & 7 deletions commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,26 @@ def process_diff(original_text, save_fn, filename):
container_diff = process_diff(st.session_state['_container_plaintext'], save_containers, container_filename)

confirm_discard = confirmation('Confirm discard')
confirm_clean_clone = confirmation('Confirm clean inventory reset')

def discard():
load_users(st.session_state)
load_containers(st.session_state)

def clean_inventory():
p = subprocess.run(['bash', 'clean_inventory.sh'], capture_output=True)
if p.returncode == 0:
discard()
st.rerun()

Comment on lines +68 to +72
out = p.stdout.decode().splitlines() + p.stderr.decode().splitlines()
st.write(':red[Could not reset the inventory repository.]')
st.divider()
st.html(f'''
{conv.produce_headers()}
<pre class='ansi2html-content'>{''.join(map(convert, out))}</pre>
''')

@st.dialog('Commit changes', width='large')
def commit():
with st.form('commit-form'):
Expand All @@ -75,16 +91,28 @@ def commit():
# Don't discard if script failed as that would import uncommitted changes and no longer show them
# The changes which we saved will get reverted from the file upon rerun
if p.returncode == 0:
st.session_state.pop('_commit_error_out', None)
discard()
st.rerun()
else:
out = p.stdout.decode().splitlines()
st.write(':red[Could not pull with rebase. Remove any changes causing a merge conflict.]')
st.divider()
st.html(f'''
{conv.produce_headers()}
<pre class='ansi2html-content'>{''.join(map(convert, out))}</pre>
''')
st.session_state['_commit_error_out'] = (
p.stdout.decode().splitlines() + p.stderr.decode().splitlines()
)

if '_commit_error_out' in st.session_state:
out = st.session_state['_commit_error_out']
st.write(':red[Could not save changes because the inventory repository changed in a conflicting way.]')
st.write('The application tried to update the local inventory before applying your changes. If the conflict cannot be resolved automatically, reset the local inventory to a clean copy from the remote and re-enter your changes.')
if st.button('Clean git clone / discard local inventory changes'):
confirm_clean_clone(
'This will discard all local inventory changes and reset the inventory repository to the remote branch. Continue?',
clean_inventory,
)
st.divider()
st.html(f'''
{conv.produce_headers()}
<pre class='ansi2html-content'>{''.join(map(convert, out))}</pre>
''')

if st.session_state.diff_size > 0:
with st.container(horizontal=True):
Expand Down
59 changes: 45 additions & 14 deletions commit.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,38 +1,69 @@
#! /usr/bin/env bash
set -u

lockfile=/opt/ccc-manager/commit.lock
inventory_dir=${CCC_INVENTORY_DIR:-/opt/ccc-inventory}

function cleanup() {
rm -f "$lockfile"
}

function error() {
echo $1
rm -f $lockfile
echo "$1"
cleanup
exit 1
}

if [[ -e $lockfile ]]; then
function reset_worktree() {
git rebase --abort >/dev/null 2>&1 || true
git merge --abort >/dev/null 2>&1 || true
git reset --hard HEAD >/dev/null 2>&1 || true
}
Comment on lines +17 to +21

if [[ -e "$lockfile" ]]; then
error 'Could not acquire lock. Try again.'
fi
touch $lockfile
touch "$lockfile"
trap cleanup EXIT
Comment on lines +23 to +27

patchfile=$1
sed -e 's/\x1b\[[0-9;]*m//g' -i $patchfile
sed -e 's/\x1b\[[0-9;]*m//g' -i "$patchfile"

if [[ -z $2 ]]; then
if [[ -z ${2:-} ]]; then
error 'Commit message not provided'
Comment on lines 29 to 33
fi

cd /opt/ccc-inventory/
cd "$inventory_dir" || error "Inventory directory not found: $inventory_dir"

upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)
if [[ -n "$upstream" ]]; then
git fetch --prune || error 'Could not fetch remote changes'
git rebase "$upstream" || {
reset_worktree
error 'Could not synchronize with remote before applying changes'
}
else
git pull --rebase || error 'Could not pull with rebase'
fi

git apply --3way "$patchfile" || {
git diff --diff-filter=U --color || true
reset_worktree
error 'Patch failed'
}

git apply $patchfile || error 'Patch failed'
git add inventory/group_vars/ccc-cluster/{user-list,user-containers}.yml
git commit -m "$2"
git commit -m "$2" || error 'Commit failed'
Comment on lines 55 to +56

git pull --rebase
STATUS=$?
if [[ $STATUS -ne 0 ]]; then
git diff --diff-filter=U --color
git rebase --abort
git reset --hard HEAD~1
git diff --diff-filter=U --color || true
git rebase --abort >/dev/null 2>&1 || true
git reset --hard HEAD~1 >/dev/null 2>&1 || true
error 'Rebase not successful'
fi

git push
rm $lockfile
git push || error 'Push failed'
cleanup
trap - EXIT