]>
git.proxmox.com Git - dab.git/blob - dab
14 'bootstrap' => '[--exim] [--include <a[,b..]]>] --exclude [<a[,b..]]>] [--minimal]',
15 'finalize' => '[--keepmycnf] [--compressor <gz[ip] (default)|zst[d]|zstd-max>]',
19 'list' => '[--verbose]',
20 'task' => '<postgres|mysql|php> [--version] [--password] [--memlimit]',
21 'install' => '<package or *.pkglist file> ...',
22 'exec' => '<cmd> ...',
30 print STDERR
"USAGE: dab <command> [parameters]\n\n";
32 for my $cmd (sort keys %$commands) {
33 if (my $opts = $commands->{$cmd}) {
34 print STDERR
" dab $cmd $opts\n";
36 print STDERR
" dab $cmd\n";
44 print STDERR
"\nERROR: $msg\n\n" if $msg;
50 if (scalar (@ARGV) == 0) {
51 fatal_usage
("no command specified");
54 my $cmdline = join (' ', @ARGV);
55 my $cmd = shift @ARGV;
58 fatal_usage
("no command specified");
59 } elsif (!exists $commands->{$cmd}) {
60 fatal_usage
("unknown command '$cmd'");
61 } elsif ($cmd eq 'help') {
68 $dab = PVE
::DAB-
>new() if !$dab;
72 dab-
>writelog ("dab: $cmdline\n");
74 $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
75 die "interrupted by signal\n";
80 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
84 } elsif ($cmd eq 'bootstrap') {
86 if (!GetOptions
($opts, 'exim', 'minimal', 'include=s', 'exclude=s')) {
89 die "command 'bootstrap' expects no arguments.\n" if scalar (@ARGV) != 0;
92 $dab->bootstrap ($opts);
94 } elsif ($cmd eq 'finalize') {
96 if (!GetOptions
($opts, 'keepmycnf', 'compressor=s')) {
99 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
101 $dab->finalize($opts);
103 } elsif ($cmd eq 'veid') {
104 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
106 print $dab->{veid
} . "\n";
108 } elsif ($cmd eq 'basedir') {
109 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
111 print $dab->{rootfs
} . "\n";
113 } elsif ($cmd eq 'packagefile') {
114 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
116 print "$dab->{targetname}.tar.gz\n";
118 } elsif ($cmd eq 'list') {
120 if (!GetOptions
('verbose' =>\
$verbose)) {
123 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
125 my $instpkgs = $dab->read_installed ();
127 foreach my $pkg (sort keys %$instpkgs) {
129 my $version = $instpkgs->{$pkg}->{version
};
130 print "$pkg $version\n";
136 } elsif ($cmd eq 'task') {
137 my $task = shift @ARGV;
139 fatal_usage
("no task specified");
143 if ($task eq 'mysql') {
144 if (!GetOptions
($opts, 'password=s', 'start')) {
147 die "task '$task' expects no arguments.\n" if scalar (@ARGV) != 0;
149 $dab->task_mysql ($opts);
151 } elsif ($task eq 'postgres') {
152 if (!GetOptions
($opts, 'version=s', 'start')) {
155 die "task '$task' expects no arguments.\n" if scalar (@ARGV) != 0;
157 $dab->task_postgres ($opts);
159 } elsif ($task eq 'php') {
160 if (!GetOptions
($opts, 'memlimit=i')) {
163 die "task '$task' expects no arguments.\n" if scalar (@ARGV) != 0;
165 $dab->task_php ($opts);
168 fatal_usage
("unknown task '$task'");
171 } elsif ($cmd eq 'install' || $cmd eq 'unpack') {
173 foreach my $arg (@ARGV) {
174 if ($arg =~ m/\.pkglist$/) {
176 die "cant open package list '$arg' - $!";
177 while (defined (my $line = <TMP
>)) {
179 next if $line =~ m/^\s*$/;
180 next if $line =~ m/\#/;
181 if ($line =~ m/^\s*(\S+)\s*$/) {
184 die "invalid package name in '$arg' - $line\n";
188 push @$required, $arg;
194 $dab->install ($required, $cmd eq 'unpack');
196 } elsif ($cmd eq 'exec') {
198 $dab->ve_exec (@ARGV);
200 } elsif ($cmd eq 'enter') {
201 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
205 } elsif ($cmd eq 'clean') {
206 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
210 } elsif ($cmd eq 'dist-clean') {
211 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
216 fatal_usage
("invalid command '$cmd'");
231 dab - Debian LXC Appliance Builder
237 =item B<dab> I<command> I<[OPTIONS]>
241 Downloads the package descriptions form the repository. Also truncates the
244 =item B<dab bootstrap>
246 Bootstrap a debian system and allocate a temporary container (we use IDs 90000
253 Use exim as MTA (dab selects postfix by default)
257 Do not auto-select packages with standard priority for installation.
259 =item I<--include <a[,b..]]>
261 A comma-separated list of packages to always include in bootstrap. Note that no
262 transitive dependency resolution is done, you may need to specify those
265 =item I<--exclude <a[,b..]]>
267 A comma-separated list of packages to exlcude in bootstrap. Note that no
268 transitive dependency resolution is done for others to get excluded, you may
269 need to specify those yourself.
275 Print used container ID.
279 Print container private directory.
281 =item B<dab packagefile>
283 Print the appliance file name.
285 =item B<dab install I<pkg ...>>
287 Install one or more packages. I<pkg> can also refer to a file named
288 C<xyz.pkglist> which contains a list of packages. All dependencies are
289 automatically installed.
291 =item B<dab unpack I<pkg ...>>
293 Unpack one or more packages. I<pkg> can also refer to a file named
294 C<xyz.pkglist> which contains a list of packages. All dependencies are
295 automatically unpacked.
297 =item B<dab exec I<CMD> I<ARGS>>
299 Executes command CMD inside the container.
303 Calls C<lxc-attach> - this is for debugging only.
305 =item B<dab task mysql>
307 Install a mysql database server. During appliance generation we use C<admin> as
308 mysql root password (also stored in /root/.my.cnf).
312 =item I<--password=XXX>
314 Specify the mysql root password. The special value C<random> can be use to
315 generate a random root password when the appliance is started first time
316 (stored in /root/.my.cnf)
320 Start the mysql server (if you want to execute sql commands during
321 appliance generation).
325 =item B<dab task postgres>
327 Install a postgres database server.
331 =item I<--version=XXX>
333 Select Postgres version. Posible values are for example C<9.6>, C<11> or C<13>,
334 they depend on the selected distribution suite. Defaults to none, which selects
335 the unversioned metapackage that pulls in the suites default version, normally
336 a good choice to make.
340 Start the postgres server immediately. Useful, for example, if you want to
341 execute sql commands during appliance generation.
345 =item B<dab task php>
351 =item I<--memlimit=i>
353 Set the php I<memory_limit>.
357 =item B<dab finalize>
359 Cleanup everything inside the container and generate the final appliance
366 Do not delete file C</root/.my.cfg> (mysql).
368 =item I<--compressor <gz[ip] (default)|zst[d]|zstd-max>]>
370 Select the compressor to process the rootfs archive with. C<gzip> is a good
371 choice to make the archive also available on older systems, but using C<zstd>
372 or even C<zstd-max> results in a higher compression ration while keeping
373 decompression very fast and highly efficient. Note that C<zstd-max> uses the
374 highest compression ratio without any decompression performance hit possible,
375 it will use as many threads as there are onlince CPU threads and may thus
376 increase the system load significantly for tens of seconds up to minutes.
382 List installed packages.
388 Also print package versions.
394 Remove all temporary files and destroy the container.
396 =item B<dab dist-clean>
398 Like clean, but also removes the package cache (except when you specified your
399 own cache directory in the config file)
405 dab is a script to automate the creation of LXC appliances. It is basically a
406 rewrite of debootstrap in perl, but uses LXC instead of chroot and generates
407 LXC templates. Another difference is that it supports multi-stage building of
408 templates. That way you can execute arbitrary scripts between to accomplish
411 Furthermore some common tasks are fully automated, like setting up a database
412 server (mysql or postgres).
414 To accomplish minimal template creation time, packages are cached to a local
415 directory, so you do not need a local debian mirror (although this would speed
418 See http://pve.proxmox.com/wiki/Debian_Appliance_Builder for examples.
420 This script need to be run as root, so it is not recommended to start it on a
421 production machine with running containers. So many people run Proxmox VE
422 inside a KVM or VMWare 64bit virtual machine to build appliances.
424 All generated templates includes an appliance description file. Those can be
425 used to build appliance repositories.
429 Configuration is read from the file C<dab.conf> inside the current working
430 directory. The files contains key value pairs, separated by colon.
434 =item B<Suite:> I<squeeze|wheezy|jessie|trusty|vivid>
436 The Debian or Ubuntu suite.
438 =item B<Source:> I<URL [components]>
440 Defines a source location. By default we use the following for debian:
442 Source: http://ftp.debian.org/debian SUITE main contrib
443 Source: http://security.debian.org SUITE/updates main contrib
445 Note: SUITE is a variable and will be substituted.
447 There are also reasonable defaults for Ubuntu. If you do not specify any source
448 the defaults are used.
450 =item B<Depends:> I<dependencies>
452 Debian like package dependencies. This can be used to make sure that speific
453 package versions are available.
455 =item B<CacheDir>: I<path>
457 Allows you to specify the directory where downloaded packages are cached.
459 =item B<Mirror:> I<SRCURL> => I<DSTURL>
461 Define a mirror location. for example:
463 Mirror: http://ftp.debian.org/debian => ftp://mirror/debian
467 All other settings in this files are also included into the appliance
472 =item B<Name:> I<name>
474 The name of the appliance.
476 Appliance names must consist only of lower case letters (a-z), digits (0-9),
477 plus (+) and minus (-) signs, and periods (.). They must be at least two
478 characters long and must start with an alphanumeric character.
480 =item B<Architecture:> I<i386|amd64>
484 =item B<Version:> I<upstream_version[-build_revision]>
486 The version number of an appliance.
488 =item: B<Section:> I<section>
490 This field specifies an application area into which the appliance has been
491 classified. Currently we use the following section names: system, mail
493 =item B<Maintainer:> I<name <email>>
495 The appliance maintainer's name and email address. The name should come first,
496 then the email address inside angle brackets <> (in RFC822 format).
498 =item B<Infopage:> I<URL>
500 Link to web page containing more informations about this appliance.
502 =item B<Description:> I<single line synopsis>
504 extended description over several lines (indended by space) may follow.
508 =head1 Appliance description file
510 All generated templates includes an appliance description file called
514 this is the first file inside the tar archive. That way it can be easily
515 exctracted without scanning the whole archive. The file itself contains
516 informations like a debian C<control> file. It can be used to build appliance
519 Most fields are directly copied from the configuration file C<dab.conf>.
521 Additionally there are some auto-generated files:
525 =item B<Installed-Size:> I<bytes>
527 It gives the total amount of disk space required to install the named
528 appliance. The disk space is represented in megabytes as a simple decimal
531 =item B<Type:> I<type>
533 This is always C<lxc>.
535 =item B<OS:> I<[debian-4.0|debian-5.0|ubuntu-8.0]>
541 Appliance repositories usually add additional fields:
545 =item B<md5sum:> I<md5sum>
553 The following files are created inside your working directory:
555 dab.conf appliance configuration file
557 logfile contains installation logs
559 .veid stores the used container ID
561 cache/* default package cache directory
563 info/* package information cache
567 Dietmar Maurer <dietmar@proxmox.com>
568 Thomas Lamprecht <t.lamprecht@proxmox.com>
570 Many thanks to Proxmox Server Solutions (www.proxmox.com) for sponsoring this
573 =head1 COPYRIGHT AND DISCLAIMER
575 Copyright (C) 2007-2021 Proxmox Server Solutions GmbH
577 Copyright: dab is under GNU GPL, the GNU General Public License.
579 This program is free software; you can redistribute it and/or modify
580 it under the terms of the GNU General Public License as published by
581 the Free Software Foundation; version 2 dated June, 1991.
583 This program is distributed in the hope that it will be useful,
584 but WITHOUT ANY WARRANTY; without even the implied warranty of
585 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
586 GNU General Public License for more details.
588 You should have received a copy of the GNU General Public License
589 along with this program; if not, write to the
590 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,