]> git.proxmox.com Git - pve-container.git/blob - src/PVE/LXC/Tools.pm
add PVE::LXC::Tools
[pve-container.git] / src / PVE / LXC / Tools.pm
1 # Module for lxc related functionality used mostly by our hooks.
2
3 package PVE::LXC::Tools;
4
5 use PVE::SafeSyslog;
6
7 # LXC introduced an `lxc.hook.version` property which allows hooks to be executed in different
8 # manners. The old way passes a lot of stuff as command line parameter, the new way passes
9 # environment variables.
10 #
11 # This is supposed to be a common entry point for hooks, consuming the parameters passed by lxc and
12 # passing them on to a subroutine in a defined way.
13 sub lxc_hook($$&) {
14 my ($expected_type, $expected_section, $code) = @_;
15
16 my ($ct_name, $section, $type);
17 my $namespaces = {};
18 my $args;
19
20 my $version = $ENV{LXC_HOOK_VERSION} // '0';
21 if ($version eq '0') {
22 # Old style hook:
23 $ct_name = shift @ARGV;
24 $section = shift @ARGV;
25 $type = shift @ARGV;
26
27 if (!defined($ct_name) || !defined($section) || !defined($type)) {
28 die "missing hook parameters, expected to be called by lxc as hook\n";
29 }
30
31 if ($ct_name !~ /^\d+$/ || $section ne $expected_section || $type ne $expected_type) {
32 return;
33 }
34
35 if ($type eq 'stop') {
36 foreach my $ns (@ARGV) {
37 if ($ns =~ /^([^:]+):(.+)$/) {
38 $namespaces->{$1} = $2;
39 } else {
40 die "unrecognized 'stop' hook parameter: $ns\n";
41 }
42 }
43 } elsif ($type eq 'clone') {
44 $args = [@ARGV];
45 }
46 } elsif ($version eq '1') {
47 $ct_name = $ENV{LXC_NAME}
48 or die "missing LXC_NAME environment variable\n";
49 $section = $ENV{LXC_HOOK_SECTION}
50 or die "missing LXC_HOOK_SECTION environment variable\n";
51 $type = $ENV{LXC_HOOK_TYPE}
52 or die "missing LXC_HOOK_TYPE environment variable\n";
53
54 if ($ct_name !~ /^\d+$/ || $section ne $expected_section || $type ne $expected_type) {
55 return;
56 }
57
58 foreach my $var (keys %$ENV) {
59 if ($var =~ /^LXC_([A-Z]+)_NS$/) {
60 $namespaces->{lc($1)} = $ENV{$1};
61 }
62 }
63 } else {
64 die "lxc.hook.version $version not supported!\n";
65 }
66
67 my $logid = $ENV{PVE_LOG_ID} || "pve-lxc-hook-$section-$type";
68 initlog($logid);
69
70 my $common_vars = {
71 ROOTFS_MOUNT => ($ENV{LXC_ROOTFS_MOUNT} or die "missing LXC_ROOTFS_MOUNT env var\n"),
72 ROOTFS_PATH => ($ENV{LXC_ROOTFS_PATH} or die "missing LXC_ROOTFS_PATH env var\n"),
73 CONFIG_FILE => ($ENV{LXC_CONFIG_FILE} or die "missing LXC_CONFIG_FILE env var\n"),
74 };
75 if (defined(my $target = $ENV{LXC_TARGET})) {
76 $common_vars->{TARGET} = $target;
77 }
78
79 $code->($ct_name, $common_vars, $namespaces, $args);
80 }
81
82 1;