]>
Commit | Line | Data |
---|---|---|
93285df8 DM |
1 | #!/usr/bin/perl |
2 | ||
3 | use strict; | |
4 | use warnings; | |
4ed2b825 | 5 | |
d6811d3f | 6 | exit 0 if $ENV{LXC_NAME} && $ENV{LXC_NAME} !~ /^\d+$/; |
4ed2b825 | 7 | |
93285df8 DM |
8 | use POSIX; |
9 | use File::Path; | |
10 | ||
11 | use PVE::SafeSyslog; | |
12 | use PVE::Tools; | |
13 | use PVE::Cluster; | |
93285df8 DM |
14 | use PVE::RPCEnvironment; |
15 | use PVE::JSONSchema qw(get_standard_option); | |
16 | use PVE::CLIHandler; | |
17 | use PVE::Storage; | |
18 | use PVE::LXC; | |
7af97ad5 | 19 | use PVE::LXC::Setup; |
93285df8 DM |
20 | use Data::Dumper; |
21 | ||
22 | use base qw(PVE::CLIHandler); | |
23 | ||
24 | $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin'; | |
25 | ||
26 | initlog ('lxc-pve-mount-hook'); | |
27 | ||
28 | die "please run as root\n" if $> != 0; | |
29 | ||
93285df8 DM |
30 | my $rpcenv = PVE::RPCEnvironment->init('cli'); |
31 | $rpcenv->set_language($ENV{LANG}); | |
32 | $rpcenv->set_user('root@pam'); | |
33 | ||
34 | # we cannot use cfs_read here (permission problem) | |
f04c2ae2 DM |
35 | # $rpcenv->init_request(); |
36 | # PVE::INotify::nodename() also returns wrong value! | |
93285df8 DM |
37 | |
38 | __PACKAGE__->register_method ({ | |
39 | name => 'lxc-pve-mount-hook', | |
40 | path => 'lxc-pve-mount-hook', | |
41 | method => 'GET', | |
42 | description => "Create a new container root directory.", | |
43 | parameters => { | |
44 | additionalProperties => 0, | |
45 | properties => { | |
4fc1b360 | 46 | name => { |
c0c77476 | 47 | description => "The container name. This hook is only active for containers using numeric IDs, where configuration is stored on /etc/pve/lxc/<name>.conf (else it is just a NOP).", |
4fc1b360 DM |
48 | type => 'string', |
49 | pattern => '\S+', | |
50 | maxLength => 64, | |
51 | }, | |
93285df8 DM |
52 | path => { |
53 | description => "The path to the container configuration directory (LXC internal argument - do not pass manually!).", | |
54 | type => 'string', | |
55 | }, | |
56 | rootfs => { | |
57 | description => "The path to the container's rootfs (LXC internal argument - do not pass manually!)", | |
58 | type => 'string', | |
59 | }, | |
60 | }, | |
61 | }, | |
62 | returns => { type => 'null' }, | |
63 | ||
64 | code => sub { | |
65 | my ($param) = @_; | |
66 | ||
67 | my $private = $param->{rootfs}; | |
68 | ||
4fc1b360 | 69 | return undef if $param->{name} !~ m/^\d+$/; |
93285df8 | 70 | |
f04c2ae2 DM |
71 | my $vmid = $param->{name}; |
72 | ||
27916659 DM |
73 | # Note: PVE::INotify::nodename() returns wrong value when run |
74 | # inside container mount hook, so we cannot simply | |
75 | # use PVE::LXC::load_conf(). | |
93285df8 | 76 | |
27916659 DM |
77 | my $config_filename = "/etc/pve/lxc/$param->{name}.conf"; |
78 | ||
79 | return undef if ! -f $config_filename; | |
80 | ||
81 | my $raw = PVE::Tools::file_get_contents($config_filename); | |
82 | my $conf = PVE::LXC::parse_pct_config($config_filename, $raw); | |
83 | ||
f04c2ae2 DM |
84 | my $rootdir = $ENV{LXC_ROOTFS_MOUNT}; |
85 | ||
86 | # Note: PVE::Storage::config() does not work here | |
87 | my $fn = "/etc/pve/storage.cfg"; | |
88 | $raw = -f $fn ? PVE::Tools::file_get_contents($fn) : ''; | |
89 | my $storage_cfg = PVE::Storage::Plugin->parse_config($fn, $raw); | |
90 | ||
91 | my $bdevs = PVE::LXC::blockdevices_list(); | |
92 | my $loopdevs = PVE::LXC::loopdevices_list(); | |
93 | ||
94 | my $setup_mountpoint = sub { | |
95 | my ($ms, $mountpoint) = @_; | |
96 | ||
cc6b0307 | 97 | return if $ms eq 'rootfs'; |
1e8f01be | 98 | PVE::LXC::mountpoint_mount($mountpoint, $rootdir, $storage_cfg, $loopdevs); |
892e1d03 | 99 | }; |
f04c2ae2 | 100 | |
892e1d03 AD |
101 | my $setup_cgroup_device = sub { |
102 | my ($ms, $mountpoint) = @_; | |
f04c2ae2 | 103 | |
892e1d03 AD |
104 | my $volid = $mountpoint->{volume}; |
105 | return if !$volid || $volid =~ m|^/dev/.+|; | |
106 | ||
b15c75fc | 107 | my $path = PVE::LXC::mountpoint_mount_path($mountpoint, $storage_cfg, $loopdevs); |
f04c2ae2 DM |
108 | |
109 | if (-l $path) { | |
110 | $path = readlink($path); | |
111 | $path =~ s/\.\.\/\.\.\//\/dev\//; | |
112 | } | |
113 | ||
114 | if ($bdevs->{$path}) { | |
115 | PVE::Tools::run_command(['mknod', '-m', '666', "$rootdir$path", 'b', $bdevs->{$path}->{major}, $bdevs->{$path}->{minor}]); | |
116 | PVE::LXC::write_cgroup_value("devices", $vmid, "devices.allow", "b $bdevs->{$path}->{major}:$bdevs->{$path}->{minor} rwm"); | |
117 | } | |
f04c2ae2 | 118 | }; |
5b4657d0 | 119 | |
f04c2ae2 | 120 | PVE::LXC::foreach_mountpoint($conf, $setup_mountpoint); |
f5635601 | 121 | |
892e1d03 AD |
122 | PVE::LXC::foreach_mountpoint($conf, $setup_cgroup_device); |
123 | ||
7af97ad5 | 124 | my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir); |
d66768a2 | 125 | $lxc_setup->pre_start_hook(); |
27916659 | 126 | |
93285df8 DM |
127 | return undef; |
128 | }}); | |
129 | ||
130 | ||
131 | push @ARGV, 'help' if !scalar(@ARGV); | |
132 | ||
133 | my $param = {}; | |
134 | ||
135 | if ((scalar(@ARGV) == 1) && ($ARGV[0] eq 'printmanpod') || | |
136 | ($ARGV[0] eq 'verifyapi')) { | |
137 | # OK | |
138 | } elsif ((scalar(@ARGV) == 3) && ($ARGV[1] eq 'lxc') && ($ARGV[2] eq 'mount')) { | |
139 | $param->{name} = $ENV{'LXC_NAME'}; | |
140 | die "got wrong name" if $param->{name} ne $ARGV[0]; | |
5b4657d0 | 141 | |
93285df8 DM |
142 | $param->{path} = $ENV{'LXC_CONFIG_FILE'}; |
143 | $param->{rootfs} = $ENV{'LXC_ROOTFS_PATH'}; | |
144 | @ARGV = (); | |
145 | } else { | |
146 | @ARGV = ('help'); | |
147 | } | |
148 | ||
149 | my $cmddef = [ __PACKAGE__, 'lxc-pve-mount-hook', [], $param]; | |
150 | ||
151 | PVE::CLIHandler::handle_simple_cmd($cmddef, \@ARGV, undef, $0); | |
152 | ||
153 | exit 0; | |
154 | ||
155 | __END__ | |
156 | ||
157 | =head1 NAME | |
158 | ||
159 | lxc-pve - LXC mount hook for Proxmox VE | |
160 | ||
161 | =head1 SYNOPSIS | |
162 | ||
163 | =include synopsis | |
164 | ||
165 | =head1 DESCRIPTION | |
166 | ||
4fc1b360 | 167 | This mount hook sets the network and hostname for pve container. |
93285df8 DM |
168 | |
169 | =head1 SEE ALSO | |
170 | ||
171 | lct(1) | |
172 | ||
173 | =include pve_copyright |