1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-10-05 19:30:59 +00:00

fix: make the creation of LXC templates atomic so they cannot be interrupted while building (#1049)

cascading-pr from https://code.forgejo.org/forgejo/lxc-helpers/pulls/49

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1049): <!--number 1049 --><!--line 0 --><!--description Y2FzY2FkaW5nLXByIGZyb20gaHR0cHM6Ly9jb2RlLmZvcmdlam8ub3JnL2Zvcmdlam8vbHhjLWhlbHBlcnMgcmVmcy9wdWxsLzQ5L2hlYWQgdG8gZm9yZ2Vqby9seGMtaGVscGVycy00OQ==-->cascading-pr from https://code.forgejo.org/forgejo/lxc-helpers refs/pull/49/head to forgejo/lxc-helpers-49<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: cascading-pr <cascading-pr@example.com>
Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1049
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: cascading-pr <cascading-pr@noreply.code.forgejo.org>
Co-committed-by: cascading-pr <cascading-pr@noreply.code.forgejo.org>
This commit is contained in:
cascading-pr 2025-10-03 09:09:29 +00:00 committed by earl-warren
parent 1fa156c7e4
commit a980acd936
No known key found for this signature in database
GPG key ID: F128CBE6AB3A7201

View file

@ -11,6 +11,8 @@ LXC_IPV6_PREFIX_DEFAULT="fd15"
LXC_DOCKER_PREFIX_DEFAULT="172.17" LXC_DOCKER_PREFIX_DEFAULT="172.17"
LXC_IPV6_DOCKER_PREFIX_DEFAULT="fd00:d0ca" LXC_IPV6_DOCKER_PREFIX_DEFAULT="fd00:d0ca"
LXC_APT_TOO_OLD='1 week ago' LXC_APT_TOO_OLD='1 week ago'
: ${LXC_TRANSACTION_TIMEOUT:=600}
LXC_TRANSACTION_LOCK_FILE=/tmp/lxc-helper.lock
: ${LXC_SUDO:=} : ${LXC_SUDO:=}
: ${LXC_CONTAINER_RELEASE:=bookworm} : ${LXC_CONTAINER_RELEASE:=bookworm}
@ -28,16 +30,22 @@ function lxc_template_release() {
echo lxc-helpers-$LXC_CONTAINER_RELEASE echo lxc-helpers-$LXC_CONTAINER_RELEASE
} }
function lxc_directory() {
local name="$1"
echo /var/lib/lxc/$name
}
function lxc_root() { function lxc_root() {
local name="$1" local name="$1"
echo /var/lib/lxc/$name/rootfs echo $(lxc_directory $name)/rootfs
} }
function lxc_config() { function lxc_config() {
local name="$1" local name="$1"
echo /var/lib/lxc/$name/config echo $(lxc_directory $name)/config
} }
function lxc_container_run() { function lxc_container_run() {
@ -47,6 +55,44 @@ function lxc_container_run() {
$LXC_SUDO lxc-attach --clear-env --name $name -- "$@" $LXC_SUDO lxc-attach --clear-env --name $name -- "$@"
} }
function lxc_transaction_lock() {
exec 7>$LXC_TRANSACTION_LOCK_FILE
flock --timeout $LXC_TRANSACTION_TIMEOUT 7
}
function lxc_transaction_unlock() {
exec 7>&-
}
function lxc_transaction_draft_name() {
echo "lxc-helper-draft"
}
function lxc_transaction_begin() {
local name=$1 # not actually used but it helps when reading in the caller
local draft=$(lxc_transaction_draft_name)
lxc_transaction_lock
lxc_container_destroy $draft
echo $draft
}
function lxc_transaction_commit() {
local name=$1
local draft=$(lxc_transaction_draft_name)
# do not use lxc-copy because it is not atomic if lxc-copy is
# interrupted it may leave the $name container half populated
$LXC_SUDO sed -i -e "s/$draft/$name/g" \
$(lxc_config $draft) \
$(lxc_root $draft)/etc/hosts \
$(lxc_root $draft)/etc/hostname
$LXC_SUDO rm -f $(lxc_root $draft)/var/lib/dhcp/dhclient.*
$LXC_SUDO mv $(lxc_directory $draft) $(lxc_directory $name)
lxc_transaction_unlock
}
function lxc_container_run_script_as() { function lxc_container_run_script_as() {
local name="$1" local name="$1"
local user="$2" local user="$2"
@ -242,7 +288,7 @@ function lxc_container_configure() {
function lxc_container_install_lxc_helpers() { function lxc_container_install_lxc_helpers() {
local name="$1" local name="$1"
$LXC_SUDO cp -a $LXC_SELF_DIR/lxc-helpers*.sh $root/$LXC_BIN $LXC_SUDO cp -a $LXC_SELF_DIR/lxc-helpers*.sh $(lxc_root $name)/$LXC_BIN
# #
# Wait for the network to come up # Wait for the network to come up
# #
@ -304,10 +350,9 @@ function lxc_container_stop() {
function lxc_container_destroy() { function lxc_container_destroy() {
local name="$1" local name="$1"
local root="$2"
if lxc_exists "$name"; then if lxc_exists "$name"; then
lxc_container_stop $name $root lxc_container_stop $name
$LXC_SUDO lxc-destroy --force --name="$name" $LXC_SUDO lxc-destroy --force --name="$name"
fi fi
} }
@ -346,14 +391,15 @@ function lxc_build_template_release() {
return return
fi fi
local root=$(lxc_root $name) local draft=$(lxc_transaction_begin $name)
$LXC_SUDO lxc-create --name $name --template debian -- --release=$LXC_CONTAINER_RELEASE $LXC_SUDO lxc-create --name $draft --template debian -- --release=$LXC_CONTAINER_RELEASE
echo 'lxc.apparmor.profile = unconfined' | $LXC_SUDO tee -a $(lxc_config $name) echo 'lxc.apparmor.profile = unconfined' | $LXC_SUDO tee -a $(lxc_config $draft)
lxc_container_install_lxc_helpers $name lxc_container_install_lxc_helpers $draft
lxc_container_start $name lxc_container_start $draft
lxc_container_run $name apt-get update -qq lxc_container_run $draft apt-get update -qq
lxc_apt_install $name sudo git python3 lxc_apt_install $draft sudo git python3
lxc_container_stop $name lxc_container_stop $draft
lxc_transaction_commit $name
} }
function lxc_build_template() { function lxc_build_template() {
@ -368,10 +414,12 @@ function lxc_build_template() {
lxc_build_template_release lxc_build_template_release
fi fi
if ! $LXC_SUDO lxc-copy --name=$name --newname=$newname; then local draft=$(lxc_transaction_begin $newname)
echo lxc-copy --name=$name --newname=$newname failed if ! $LXC_SUDO lxc-copy --name=$name --newname=$draft; then
echo lxc-copy --name=$name --newname=$draft failed
return 1 return 1
fi fi
lxc_transaction_commit $newname
lxc_container_configure $newname lxc_container_configure $newname
} }