]>
Commit | Line | Data |
---|---|---|
9beee926 DM |
1 | package PVE::CLI::pct; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use PVE::SafeSyslog; | |
7 | use PVE::Tools qw(extract_param); | |
8 | use PVE::Cluster; | |
9 | use PVE::INotify; | |
10 | use PVE::RPCEnvironment; | |
11 | use PVE::JSONSchema qw(get_standard_option); | |
12 | use PVE::CLIHandler; | |
13 | use PVE::API2::LXC; | |
14 | use PVE::API2::LXC::Config; | |
15 | use PVE::API2::LXC::Status; | |
16 | use PVE::API2::LXC::Snapshot; | |
17 | ||
18 | use Data::Dumper; | |
19 | ||
20 | use base qw(PVE::CLIHandler); | |
21 | ||
22 | my $nodename = PVE::INotify::nodename(); | |
23 | ||
24 | my $upid_exit = sub { | |
25 | my $upid = shift; | |
26 | my $status = PVE::Tools::upid_read_status($upid); | |
27 | exit($status eq 'OK' ? 0 : -1); | |
28 | }; | |
29 | ||
c72bd0ba WL |
30 | __PACKAGE__->register_method ({ |
31 | name => 'unlock', | |
32 | path => 'unlock', | |
33 | method => 'PUT', | |
34 | description => "Unlock the VM.", | |
35 | parameters => { | |
36 | additionalProperties => 0, | |
37 | properties => { | |
38 | vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid }), | |
39 | }, | |
40 | }, | |
41 | returns => { type => 'null'}, | |
42 | code => sub { | |
43 | my ($param) = @_; | |
44 | ||
45 | my $vmid = $param->{vmid}; | |
46 | ||
47 | PVE::LXC::lock_container($vmid, 5, sub { | |
48 | my $conf = PVE::LXC::load_config($vmid); | |
49 | delete $conf->{lock}; | |
50 | PVE::LXC::write_config($vmid, $conf); | |
51 | }); | |
52 | ||
53 | return undef; | |
54 | }}); | |
55 | ||
9beee926 DM |
56 | __PACKAGE__->register_method ({ |
57 | name => 'console', | |
58 | path => 'console', | |
59 | method => 'GET', | |
60 | description => "Launch a console for the specified container.", | |
61 | parameters => { | |
62 | additionalProperties => 0, | |
63 | properties => { | |
64 | vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_running }), | |
65 | }, | |
66 | }, | |
67 | returns => { type => 'null' }, | |
68 | ||
69 | code => sub { | |
70 | my ($param) = @_; | |
71 | ||
72 | # test if container exists on this node | |
73 | my $conf = PVE::LXC::load_config($param->{vmid}); | |
74 | ||
75 | my $cmd = PVE::LXC::get_console_command($param->{vmid}, $conf); | |
76 | exec(@$cmd); | |
77 | }}); | |
78 | ||
79 | __PACKAGE__->register_method ({ | |
80 | name => 'enter', | |
81 | path => 'enter', | |
82 | method => 'GET', | |
83 | description => "Launch a shell for the specified container.", | |
84 | parameters => { | |
85 | additionalProperties => 0, | |
86 | properties => { | |
87 | vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_running }), | |
88 | }, | |
89 | }, | |
90 | returns => { type => 'null' }, | |
91 | ||
92 | code => sub { | |
93 | my ($param) = @_; | |
94 | ||
95 | # test if container exists on this node | |
96 | PVE::LXC::load_config($param->{vmid}); | |
97 | ||
98 | exec('lxc-attach', '-n', $param->{vmid}); | |
99 | }}); | |
100 | ||
101 | __PACKAGE__->register_method ({ | |
102 | name => 'exec', | |
103 | path => 'exec', | |
104 | method => 'GET', | |
105 | description => "Launch a command inside the specified container.", | |
106 | parameters => { | |
107 | additionalProperties => 0, | |
108 | properties => { | |
4b09527c | 109 | vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_running }), |
9beee926 DM |
110 | 'extra-args' => get_standard_option('extra-args'), |
111 | }, | |
112 | }, | |
113 | returns => { type => 'null' }, | |
114 | ||
115 | code => sub { | |
116 | my ($param) = @_; | |
117 | ||
118 | # test if container exists on this node | |
119 | PVE::LXC::load_config($param->{vmid}); | |
120 | ||
121 | if (!@{$param->{'extra-args'}}) { | |
122 | die "missing command"; | |
123 | } | |
124 | exec('lxc-attach', '-n', $param->{vmid}, '--', @{$param->{'extra-args'}}); | |
125 | }}); | |
126 | ||
127 | our $cmddef = { | |
128 | list=> [ 'PVE::API2::LXC', 'vmlist', [], { node => $nodename }, sub { | |
129 | my $res = shift; | |
130 | return if !scalar(@$res); | |
131 | my $format = "%-10s %-10s %-20s\n"; | |
132 | printf($format, 'VMID', 'Status', 'Name'); | |
133 | foreach my $d (sort {$a->{vmid} <=> $b->{vmid} } @$res) { | |
134 | printf($format, $d->{vmid}, $d->{status}, $d->{name}); | |
135 | } | |
136 | }], | |
137 | config => [ "PVE::API2::LXC::Config", 'vm_config', ['vmid'], | |
138 | { node => $nodename }, sub { | |
139 | my $config = shift; | |
140 | foreach my $k (sort (keys %$config)) { | |
141 | next if $k eq 'digest'; | |
142 | my $v = $config->{$k}; | |
143 | if ($k eq 'description') { | |
144 | $v = PVE::Tools::encode_text($v); | |
145 | } | |
146 | print "$k: $v\n"; | |
147 | } | |
148 | }], | |
149 | set => [ 'PVE::API2::LXC::Config', 'update_vm', ['vmid'], { node => $nodename }], | |
150 | ||
151 | create => [ 'PVE::API2::LXC', 'create_vm', ['vmid', 'ostemplate'], { node => $nodename }, $upid_exit ], | |
152 | restore => [ 'PVE::API2::LXC', 'create_vm', ['vmid', 'ostemplate'], { node => $nodename, restore => 1 }, $upid_exit ], | |
153 | ||
154 | start => [ 'PVE::API2::LXC::Status', 'vm_start', ['vmid'], { node => $nodename }, $upid_exit], | |
155 | suspend => [ 'PVE::API2::LXC::Status', 'vm_suspend', ['vmid'], { node => $nodename }, $upid_exit], | |
156 | resume => [ 'PVE::API2::LXC::Status', 'vm_resume', ['vmid'], { node => $nodename }, $upid_exit], | |
157 | shutdown => [ 'PVE::API2::LXC::Status', 'vm_shutdown', ['vmid'], { node => $nodename }, $upid_exit], | |
158 | stop => [ 'PVE::API2::LXC::Status', 'vm_stop', ['vmid'], { node => $nodename }, $upid_exit], | |
159 | ||
160 | migrate => [ "PVE::API2::LXC", 'migrate_vm', ['vmid', 'target'], { node => $nodename }, $upid_exit], | |
161 | ||
162 | console => [ __PACKAGE__, 'console', ['vmid']], | |
163 | enter => [ __PACKAGE__, 'enter', ['vmid']], | |
c72bd0ba | 164 | unlock => [ __PACKAGE__, 'unlock', ['vmid']], |
9beee926 DM |
165 | exec => [ __PACKAGE__, 'exec', ['vmid', 'extra-args']], |
166 | ||
167 | destroy => [ 'PVE::API2::LXC', 'destroy_vm', ['vmid'], | |
168 | { node => $nodename }, $upid_exit ], | |
169 | ||
170 | snapshot => [ "PVE::API2::LXC::Snapshot", 'snapshot', ['vmid', 'snapname'], | |
171 | { node => $nodename } , $upid_exit ], | |
172 | ||
173 | delsnapshot => [ "PVE::API2::LXC::Snapshot", 'delsnapshot', ['vmid', 'snapname'], { node => $nodename } , $upid_exit ], | |
174 | ||
175 | listsnapshot => [ "PVE::API2::LXC::Snapshot", 'list', ['vmid'], { node => $nodename }, | |
176 | sub { | |
177 | my $res = shift; | |
178 | foreach my $e (@$res) { | |
179 | my $headline = $e->{description} || 'no-description'; | |
180 | $headline =~ s/\n.*//sg; | |
181 | my $parent = $e->{parent} // 'no-parent'; | |
182 | printf("%-20s %-20s %s\n", $e->{name}, $parent, $headline); | |
183 | } | |
184 | }], | |
185 | ||
186 | rollback => [ "PVE::API2::LXC::Snapshot", 'rollback', ['vmid', 'snapname'], { node => $nodename } , $upid_exit ], | |
187 | ||
188 | template => [ "PVE::API2::LXC", 'template', ['vmid'], { node => $nodename }], | |
189 | }; | |
190 | ||
191 | ||
192 | 1; | |
193 | ||
194 | __END__ | |
195 | ||
196 | =head1 NAME | |
197 | ||
198 | pct - Tool to manage Linux Containers (LXC) on Proxmox VE | |
199 | ||
200 | =head1 SYNOPSIS | |
201 | ||
202 | =include synopsis | |
203 | ||
204 | =head1 DESCRIPTION | |
205 | ||
206 | pct is a tool to manages Linux Containers (LXC). You can create | |
207 | and destroy containers, and control execution | |
208 | (start/stop/suspend/resume). Besides that, you can use pct to set | |
209 | parameters in the associated config file, like network configuration or | |
210 | memory. | |
211 | ||
212 | =head1 EXAMPLES | |
213 | ||
214 | Create a container based on a Debian template | |
215 | (provided you downloaded the template via the webgui before) | |
216 | ||
217 | pct create 100 /var/lib/vz/template/cache/debian-8.0-standard_8.0-1_amd64.tar.gz | |
218 | ||
219 | Start a container | |
220 | ||
221 | pct start 100 | |
222 | ||
223 | Start a login session via getty | |
224 | ||
225 | pct console 100 | |
226 | ||
227 | Enter the lxc namespace and run a shell as root user | |
228 | ||
229 | pct enter 100 | |
230 | ||
231 | Display the configuration | |
232 | ||
233 | pct config 100 | |
234 | ||
235 | Add a network interface called eth0, bridged to the host bridge vmbr0, | |
236 | set the address and gateway, while it's running | |
237 | ||
238 | pct set 100 -net0 name=eth0,bridge=vmbr0,ip=192.168.15.147/24,gw=192.168.15.1 | |
239 | ||
240 | Reduce the memory of the container to 512MB | |
241 | ||
242 | pct set -memory 512 100 | |
243 | ||
244 | =head1 FILES | |
245 | ||
246 | /etc/pve/lxc/<vmid>.conf | |
247 | ||
248 | Configuration file for the container <vmid> | |
249 | ||
250 | =head1 SEE ALSO | |
251 | ||
252 | L<B<qm(1)>>, L<B<pvesh(1)>> | |
253 | ||
254 | =include pve_copyright |