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