yunohost_demo/ynh_lxd

567 lines
14 KiB
Text
Raw Permalink Normal View History

2022-10-15 21:13:40 +02:00
#!/bin/bash
#=================================================
2022-10-21 00:52:40 +02:00
# LXD HELPERS
2022-10-15 21:13:40 +02:00
#=================================================
# Check if a LXC container exists
#
# usage: ynh_lxc_exists --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_exists () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
if ! lxc list --format json | jq -e --arg name $name '.[] | select(.name==$name) | .name' >/dev/null
then
return 1
else
return 0
fi
}
# Return LXC container status
#
# usage: ynh_lxc_status --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_status () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
if ynh_lxc_exists --name=$name
then
lxc list --format json | jq -r --arg name $name '.[] | select(.name==$name) | .state | .status'
fi
}
# Check if an LXC container is running
#
# usage: ynh_lxc_is_started --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_is_started () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
if [ "$(ynh_lxc_status --name=$name)" == Running ]
then
return 0
else
return 1
fi
}
# Check if an LXC container is stopped
#
# usage: ynh_lxc_is_stopped --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_is_stopped () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
if [ "$(ynh_lxc_status --name=$name)" == Stopped ]
then
return 0
else
return 1
fi
}
# Start an LXC container
#
# usage: ynh_lxc_start --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_start () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
# If the container exists
if ynh_lxc_exists --name=$name
then
if ! ynh_lxc_is_started --name=$name
then
lxc start $name
fi
fi
}
# Stopping an LXC container
#
# usage: ynh_lxc_stop --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_stop () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
# If the container exists
if ynh_lxc_exists --name=$name
then
ynh_print_info --message="Stopping LXC $name"
wait_period=0
while ! ynh_lxc_is_stopped --name=$name
do
lxc stop $name
wait_period=$(($wait_period+10))
if [ $wait_period -gt 30 ];then
break
else
sleep 1
fi
done
# If the command times out, then add the option --force
wait_period=0
while ! ynh_lxc_is_stopped --name=$name
do
lxc stop $name --force
wait_period=$(($wait_period+10))
if [ $wait_period -gt 30 ];then
break
else
sleep 5
fi
done
fi
}
# Run a command inside an LXC container
#
# usage: ynh_lxc_run_inside --name=name --command=command
# | arg: -n, --name= - name of the LXC
# | arg: -c, --command= - command to execute
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_run_inside () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=nc
local -A args_array=([n]=name= [c]=command=)
local name
local command
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
lxc exec $name -- /bin/bash -c "$command"
}
# Check an LXC container can start
#
# usage: ynh_lxc_check_container_start --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_check_container_start () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
ynh_print_info --message="Test du conteneur $name"
ynh_lxc_start --name=$name # Démarre le conteneur
wait_period=0
while ! ynh_lxc_is_started --name=$name
do
wait_period=$(($wait_period+10))
if [ $wait_period -gt 20 ];then
break
else
sleep 5
fi
done
ynh_lxc_is_started --name=$name
}
# Restart a container
#
2022-11-05 20:15:50 +01:00
# usage: _ynh_lxc_restart_container --name=name
2022-10-15 21:13:40 +02:00
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
_ynh_lxc_restart_container () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
2022-11-05 20:15:50 +01:00
ynh_lxc_stop --name=$name
ynh_lxc_start --name=$name
2022-10-15 21:13:40 +02:00
}
# Keep sure the LXC is started
#
# usage: _ynh_lxc_start_and_wait --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
_ynh_lxc_start_and_wait () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
# Try to start the container 3 times.
ynh_lxc_start --name=$name
local max_try=3
local i=0
while [ $i -lt $max_try ]
do
i=$(( i +1 ))
local failstart=0
# Wait for container to start, we are using systemd to check this,
# for the sake of brevity.
for j in $(seq 1 10); do
2022-11-05 20:15:50 +01:00
if ynh_lxc_run_inside --name=$name --command="systemctl isolate multi-user.target >/dev/null 2>/dev/null"
then
2022-10-15 21:13:40 +02:00
break
fi
if [ "$j" == "10" ]; then
log_debug 'Failed to start the container ... restarting ...'
failstart=1
2022-11-05 20:15:50 +01:00
_ynh_lxc_restart_container --name="$name"
2022-10-15 21:13:40 +02:00
fi
sleep 1s
done
# Wait for container to access the internet
for j in $(seq 1 10); do
2022-11-05 20:15:50 +01:00
if ynh_lxc_run_inside --name=$name --command="curl -s http://wikipedia.org > /dev/null 2>/dev/null"
then
2022-10-15 21:13:40 +02:00
break
fi
if [ "$j" == "10" ]; then
log_debug 'Failed to access the internet ... restarting'
failstart=1
2022-11-05 20:15:50 +01:00
_ynh_lxc_restart_container --name="$name"
2022-10-15 21:13:40 +02:00
fi
sleep 1s
done
# Has started and has access to the internet
if [ $failstart -eq 0 ]
then
break
fi
# Fail if the container failed to start
if [ $i -eq $max_try ] && [ $failstart -eq 1 ]
then
log_error "The container miserably failed to start or to connect to the internet"
lxc info --show-log $name
return 1
fi
done
LXC_IP=$(ynh_lxc_run_inside --name=$name --command="hostname -I | cut -d' ' -f1 | grep -E -o \"\<[0-9.]{8,}\>\"")
}
2022-11-05 20:15:50 +01:00
# Launch a new LXC from an image
2022-10-15 21:13:40 +02:00
#
2022-11-05 20:15:50 +01:00
# usage: ynh_lxc_launch --image=image --name=name
2022-10-15 21:13:40 +02:00
# | arg: -i, --image= - image to create from
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_launch (){
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=in
local -A args_array=([i]=image= [n]=name=)
local image
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
2022-11-05 20:15:50 +01:00
if lxc remote list | grep -q "yunohost" && lxc image list yunohost:$image | grep -q -w $image; then
lxc launch yunohost:$image $name \
2022-10-15 21:13:40 +02:00
-c security.nesting=true \
-c security.privileged=true \
-c limits.memory=80% \
-c limits.cpu.allowance=80% | tee -a /proc/self/fd/3
# Check if we can launch container from a local image
2022-11-05 20:15:50 +01:00
elif lxc image list $image | grep -q -w $image; then
lxc launch $image $name \
2022-10-15 21:13:40 +02:00
-c security.nesting=true \
-c security.privileged=true \
-c limits.memory=80% \
-c limits.cpu.allowance=80% | tee -a /proc/self/fd/3
else
log_critical "Can't find base image $image"
fi
}
# Delete a lxc container
#
# usage: ynh_lxc_delete --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_delete () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
if ynh_lxc_exists --name=$name
then
lxc delete $name --force
else
return 1
fi
}
# Clean the swapfiles of an LXC container
#
2022-11-05 20:15:50 +01:00
# usage: ynh_lxc_swapfiles_clean --name=name
2022-10-15 21:13:40 +02:00
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_swapfiles_clean () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
2022-11-05 20:15:50 +01:00
_ynh_lxc_start_and_wait --name=$name
2022-10-15 21:13:40 +02:00
ynh_lxc_run_inside --name=$name --command='for swapfile in $(ls /swap_* 2>/dev/null); do swapoff $swapfile; done'
ynh_lxc_run_inside --name=$name --command='for swapfile in $(ls /swap_* 2>/dev/null); do rm -f $swapfile; done'
}
# Check if a snapshot exist for an LXC container
#
# usage: ynh_lxc_snapshot_exists --name=name --snapname=snapname
# | arg: -n, --name= - name of the LXC
# | arg: -s, --snapname= - name of the snapshot
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_snapshot_exists () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=ns
local -A args_array=([n]=name= [s]=snapname=)
local name
local snapname
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
# If the container exists
if ynh_lxc_exists --name=$name
then
if lxc list --format json | jq -e --arg name $name --arg snapname $snapname '.[] | select(.name==$name) | .snapshots' >/dev/null
then
if lxc list --format json | jq -e --arg name $name --arg snapname $snapname '.[] | select(.name==$name) | .snapshots[] | select(.name==$snapname)' >/dev/null
then
return 0
else
return 1
fi
else
return 1
fi
fi
}
# Create a snapshot of an LXC container
#
2022-11-05 20:15:50 +01:00
# usage: ynh_lxc_snapshot_create --name=name --snapname=snapname
2022-10-15 21:13:40 +02:00
# | arg: -n, --name= - name of the LXC
# | arg: -s, --snapname= - name of the snapshot
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_snapshot_create () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=ns
local -A args_array=([n]=name= [s]=snapname=)
local name
local snapname
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
# Remove swap files to avoid killing the CI with huge snapshots.
2022-11-05 20:15:50 +01:00
ynh_lxc_swapfiles_clean --name=$name
2022-10-15 21:13:40 +02:00
2022-11-05 20:15:50 +01:00
ynh_lxc_stop --name=$name
2022-10-15 21:13:40 +02:00
# Check if the snapshot already exist
2022-11-05 20:15:50 +01:00
if ! ynh_lxc_snapshot_exists --name=$name --snapname="$snapname"
2022-10-15 21:13:40 +02:00
then
log_info "(Creating snapshot $snapname ...)"
lxc snapshot $name $snapname
else
log_info "(Recreating snapshot $snapname ...)"
lxc snapshot $name $snapname --reuse
fi
}
# Delete a snapshot of an LXC container
#
2022-11-05 20:15:50 +01:00
# usage: ynh_lxc_snapshot_delete --name=name --snapname=snapname
2022-10-15 21:13:40 +02:00
# | arg: -n, --name= - name of the LXC
# | arg: -s, --snapname= - name of the snapshot
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_snapshot_delete () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=ns
local -A args_array=([n]=name= [s]=snapname=)
local name
local snapname
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
if ynh_lxc_snapshot_exists --name="$name" --snapname="$snapname"
then
lxc delete $name/$snapname
return 0
else
return 1
fi
}
# Load a snapshot of an LXC container
#
2022-11-05 20:15:50 +01:00
# usage: ynh_lxc_snapshot_load --name=name --snapname=snapname
2022-10-15 21:13:40 +02:00
# | arg: -n, --name= - name of the LXC
# | arg: -s, --snapname= - name of the snapshot
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_snapshot_load () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=ns
local -A args_array=([n]=name= [s]=snapname=)
local name
local snapname
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
if ynh_lxc_snapshot_exists --name="$name" --snapname="$snapname"
then
log_debug "Loading snapshot $snapname ..."
# Remove swap files before restoring the snapshot.
2022-11-05 20:15:50 +01:00
ynh_lxc_swapfiles_clean --name=$name
2022-10-15 21:13:40 +02:00
2022-11-05 20:15:50 +01:00
ynh_lxc_stop --name=$name
2022-10-15 21:13:40 +02:00
lxc restore $name $snapname
2022-11-05 20:15:50 +01:00
_ynh_lxc_start_and_wait --name=$name
2022-10-15 21:13:40 +02:00
else
return 1
fi
}
# Clone an LXC container
#
# usage: ynh_lxc_clone --source=source --destination=destination
# | arg: -s, --source= - source LXC
# | arg: -d, --destination= - destination LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_clone () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=sd
local -A args_array=([s]=source= [d]=destination=)
local source
local destination
# Manage arguments with getopts
2022-10-16 00:07:42 +02:00
ynh_handle_getopts_args "$@"
2022-10-15 21:13:40 +02:00
2022-10-16 00:07:42 +02:00
if ynh_lxc_exists --name=$destination
then
ynh_print_info --message="Deleting LXC container $destination"
ynh_secure_remove --file="/var/lib/lxd/snapshots/$destination/snap0.tar.gz"
ynh_lxc_reset --name=$destination
fi
2022-10-15 21:13:40 +02:00
2022-10-16 00:07:42 +02:00
ynh_print_info --message="Cloning LXC container from $source to $destination"
2022-10-15 21:13:40 +02:00
lxc copy "$source" "$destination"
ynh_lxc_check_container_start --name=$destination
STATUS=$?
if [ $STATUS -eq 1 ]; then
2022-10-16 00:07:42 +02:00
ynh_print_info --message="LXC container $destination is broken."
2022-10-15 21:13:40 +02:00
else
2022-10-16 00:07:42 +02:00
ynh_print_info --message=" LXC container $destination is working."
ynh_print_info --message= "Creating snapshot of LXC container $destination"
2022-11-05 20:15:50 +01:00
ynh_lxc_snapshot_create --name="$destination" --snapname="snap0"
2022-10-15 21:13:40 +02:00
fi
return $STATUS
}
# Reset an LXC container
#
# usage: ynh_lxc_reset --name=name
# | arg: -n, --name= - name of the LXC
#
# Requires YunoHost version *.*.* or higher.
2022-11-05 20:15:50 +01:00
ynh_lxc_reset () {
2022-10-15 21:13:40 +02:00
# Declare an array to define the options of this helper.
local legacy_args=n
local -A args_array=([n]=name=)
local name
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
# If the container exists
if ynh_lxc_exists --name=$name
then
2022-11-05 20:15:50 +01:00
# Remove swap files before deleting the container
ynh_lxc_swapfiles_clean --name=$name
ynh_lxc_stop --name=$name
2022-10-15 21:13:40 +02:00
local current_storage=$(lxc list $name --format json --columns b | jq '.[].expanded_devices.root.pool')
swapoff "$(lxc storage get $current_storage source)/containers/$name/rootfs/swap" 2>/dev/null
ynh_lxc_delete --name=$name
fi
}