From d92d0afd23b5882437bb1cafff23a7034add15d7 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 5 Nov 2019 13:58:01 +0100 Subject: [PATCH] add PVE::LXC::Tools Will contain lxc/container specific tools which should also be accessible within our lxc hook scripts. Signed-off-by: Wolfgang Bumiller --- src/PVE/LXC/Makefile | 7 +++- src/PVE/LXC/Tools.pm | 82 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/PVE/LXC/Tools.pm diff --git a/src/PVE/LXC/Makefile b/src/PVE/LXC/Makefile index 8a0224b..d889204 100644 --- a/src/PVE/LXC/Makefile +++ b/src/PVE/LXC/Makefile @@ -1,4 +1,9 @@ -SOURCES=Setup.pm Create.pm Migrate.pm Config.pm +SOURCES= \ + Config.pm \ + Create.pm \ + Migrate.pm \ + Setup.pm \ + Tools.pm .PHONY: install install: ${SOURCES} diff --git a/src/PVE/LXC/Tools.pm b/src/PVE/LXC/Tools.pm new file mode 100644 index 0000000..18a1a22 --- /dev/null +++ b/src/PVE/LXC/Tools.pm @@ -0,0 +1,82 @@ +# Module for lxc related functionality used mostly by our hooks. + +package PVE::LXC::Tools; + +use PVE::SafeSyslog; + +# LXC introduced an `lxc.hook.version` property which allows hooks to be executed in different +# manners. The old way passes a lot of stuff as command line parameter, the new way passes +# environment variables. +# +# This is supposed to be a common entry point for hooks, consuming the parameters passed by lxc and +# passing them on to a subroutine in a defined way. +sub lxc_hook($$&) { + my ($expected_type, $expected_section, $code) = @_; + + my ($ct_name, $section, $type); + my $namespaces = {}; + my $args; + + my $version = $ENV{LXC_HOOK_VERSION} // '0'; + if ($version eq '0') { + # Old style hook: + $ct_name = shift @ARGV; + $section = shift @ARGV; + $type = shift @ARGV; + + if (!defined($ct_name) || !defined($section) || !defined($type)) { + die "missing hook parameters, expected to be called by lxc as hook\n"; + } + + if ($ct_name !~ /^\d+$/ || $section ne $expected_section || $type ne $expected_type) { + return; + } + + if ($type eq 'stop') { + foreach my $ns (@ARGV) { + if ($ns =~ /^([^:]+):(.+)$/) { + $namespaces->{$1} = $2; + } else { + die "unrecognized 'stop' hook parameter: $ns\n"; + } + } + } elsif ($type eq 'clone') { + $args = [@ARGV]; + } + } elsif ($version eq '1') { + $ct_name = $ENV{LXC_NAME} + or die "missing LXC_NAME environment variable\n"; + $section = $ENV{LXC_HOOK_SECTION} + or die "missing LXC_HOOK_SECTION environment variable\n"; + $type = $ENV{LXC_HOOK_TYPE} + or die "missing LXC_HOOK_TYPE environment variable\n"; + + if ($ct_name !~ /^\d+$/ || $section ne $expected_section || $type ne $expected_type) { + return; + } + + foreach my $var (keys %$ENV) { + if ($var =~ /^LXC_([A-Z]+)_NS$/) { + $namespaces->{lc($1)} = $ENV{$1}; + } + } + } else { + die "lxc.hook.version $version not supported!\n"; + } + + my $logid = $ENV{PVE_LOG_ID} || "pve-lxc-hook-$section-$type"; + initlog($logid); + + my $common_vars = { + ROOTFS_MOUNT => ($ENV{LXC_ROOTFS_MOUNT} or die "missing LXC_ROOTFS_MOUNT env var\n"), + ROOTFS_PATH => ($ENV{LXC_ROOTFS_PATH} or die "missing LXC_ROOTFS_PATH env var\n"), + CONFIG_FILE => ($ENV{LXC_CONFIG_FILE} or die "missing LXC_CONFIG_FILE env var\n"), + }; + if (defined(my $target = $ENV{LXC_TARGET})) { + $common_vars->{TARGET} = $target; + } + + $code->($ct_name, $common_vars, $namespaces, $args); +} + +1; -- 2.39.2