]>
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>]',
20 'list' => '[--verbose]',
21 'task' => '<postgres|mysql|php> [--version] [--password] [--memlimit]',
22 'install' => '<package or *.pkglist file> ...',
23 'exec' => '<cmd> ...',
31 print STDERR
"USAGE: dab <command> [parameters]\n\n";
33 for my $cmd (sort keys %$commands) {
34 if (my $opts = $commands->{$cmd}) {
35 print STDERR
" dab $cmd $opts\n";
37 print STDERR
" dab $cmd\n";
45 print STDERR
"\nERROR: $msg\n\n" if $msg;
51 if (scalar (@ARGV) == 0) {
52 fatal_usage
("no command specified");
55 my $cmdline = join (' ', @ARGV);
56 my $cmd = shift @ARGV;
59 fatal_usage
("no command specified");
60 } elsif (!exists $commands->{$cmd}) {
61 fatal_usage
("unknown command '$cmd'");
62 } elsif ($cmd eq 'help') {
68 sub dab
:prototype() { # make it a directly as `dab->foo()` callable singleton
69 $dab = PVE
::DAB-
>new() if !$dab;
73 dab-
>writelog ("dab: $cmdline\n");
75 $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = sub {
76 die "interrupted by signal\n";
81 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
85 } elsif ($cmd eq 'bootstrap') {
87 if (!GetOptions
($opts, 'exim', 'minimal', 'include=s', 'exclude=s')) {
90 die "command 'bootstrap' expects no arguments.\n" if scalar (@ARGV) != 0;
93 $dab->bootstrap ($opts);
95 } elsif ($cmd eq 'finalize') {
97 if (!GetOptions
($opts, 'keepmycnf', 'compressor=s')) {
100 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
102 $dab->finalize($opts);
104 } elsif ($cmd eq 'veid') {
105 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
107 print $dab->{veid
} . "\n";
109 } elsif ($cmd eq 'basedir') {
110 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
112 print $dab->{rootfs
} . "\n";
113 } elsif ($cmd eq 'targetname') {
114 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
115 print $dab->{targetname
} . "\n";
117 } elsif ($cmd eq 'packagefile') {
118 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
119 # FIXME: either drop this or make it compressor aware, not all end with .gz...
120 print "$dab->{targetname}.tar.gz\n";
122 } elsif ($cmd eq 'list') {
124 if (!GetOptions
('verbose' =>\
$verbose)) {
127 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
129 my $instpkgs = $dab->read_installed ();
131 foreach my $pkg (sort keys %$instpkgs) {
133 my $version = $instpkgs->{$pkg}->{version
};
134 print "$pkg $version\n";
140 } elsif ($cmd eq 'task') {
141 my $task = shift @ARGV;
143 fatal_usage
("no task specified");
147 if ($task eq 'mysql') {
148 if (!GetOptions
($opts, 'password=s', 'start')) {
151 die "task '$task' expects no arguments.\n" if scalar (@ARGV) != 0;
153 $dab->task_mysql ($opts);
155 } elsif ($task eq 'postgres') {
156 if (!GetOptions
($opts, 'version=s', 'start')) {
159 die "task '$task' expects no arguments.\n" if scalar (@ARGV) != 0;
161 $dab->task_postgres ($opts);
163 } elsif ($task eq 'php') {
164 if (!GetOptions
($opts, 'memlimit=i')) {
167 die "task '$task' expects no arguments.\n" if scalar (@ARGV) != 0;
169 $dab->task_php ($opts);
172 fatal_usage
("unknown task '$task'");
175 } elsif ($cmd eq 'install' || $cmd eq 'unpack') {
177 foreach my $arg (@ARGV) {
178 if ($arg =~ m/\.pkglist$/) {
180 die "cant open package list '$arg' - $!";
181 while (defined (my $line = <TMP
>)) {
183 next if $line =~ m/^\s*$/;
184 next if $line =~ m/\#/;
185 if ($line =~ m/^\s*(\S+)\s*$/) {
188 die "invalid package name in '$arg' - $line\n";
192 push @$required, $arg;
198 $dab->install ($required, $cmd eq 'unpack');
200 } elsif ($cmd eq 'exec') {
202 $dab->ve_exec (@ARGV);
204 } elsif ($cmd eq 'enter') {
205 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
209 } elsif ($cmd eq 'clean') {
210 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
214 } elsif ($cmd eq 'dist-clean') {
215 die "command '$cmd' expects no arguments.\n" if scalar (@ARGV) != 0;
220 fatal_usage
("invalid command '$cmd'");
235 dab - Debian LXC Appliance Builder
241 =item B<dab> I<command> I<[OPTIONS]>
245 Downloads the package descriptions form the repository. Also truncates the
248 =item B<dab bootstrap>
250 Bootstrap a debian system and allocate a temporary container (we use IDs 90000
257 Use exim as MTA (dab selects postfix by default)
261 Do not auto-select packages with standard priority for installation.
263 =item I<--include <a[,b..]]>
265 A comma-separated list of packages to always include in bootstrap. Note that no
266 transitive dependency resolution is done, you may need to specify those
269 =item I<--exclude <a[,b..]]>
271 A comma-separated list of packages to exlcude in bootstrap. Note that no
272 transitive dependency resolution is done for others to get excluded, you may
273 need to specify those yourself.
279 Print used container ID.
283 Print container private directory.
285 =item B<dab packagefile>
287 Print the appliance file name.
289 =item B<dab install I<pkg ...>>
291 Install one or more packages. I<pkg> can also refer to a file named
292 C<xyz.pkglist> which contains a list of packages. All dependencies are
293 automatically installed.
295 =item B<dab unpack I<pkg ...>>
297 Unpack one or more packages. I<pkg> can also refer to a file named
298 C<xyz.pkglist> which contains a list of packages. All dependencies are
299 automatically unpacked.
301 =item B<dab exec I<CMD> I<ARGS>>
303 Executes command CMD inside the container.
307 Calls C<lxc-attach> - this is for debugging only.
309 =item B<dab task mysql>
311 Install a mysql database server. During appliance generation we use C<admin> as
312 mysql root password (also stored in /root/.my.cnf).
316 =item I<--password=XXX>
318 Specify the mysql root password. The special value C<random> can be use to
319 generate a random root password when the appliance is started first time
320 (stored in /root/.my.cnf)
324 Start the mysql server (if you want to execute sql commands during
325 appliance generation).
329 =item B<dab task postgres>
331 Install a postgres database server.
335 =item I<--version=XXX>
337 Select Postgres version. Posible values are for example C<9.6>, C<11> or C<13>,
338 they depend on the selected distribution suite. Defaults to none, which selects
339 the unversioned metapackage that pulls in the suites default version, normally
340 a good choice to make.
344 Start the postgres server immediately. Useful, for example, if you want to
345 execute sql commands during appliance generation.
349 =item B<dab task php>
355 =item I<--memlimit=i>
357 Set the php I<memory_limit>.
361 =item B<dab finalize>
363 Cleanup everything inside the container and generate the final appliance
370 Do not delete file C</root/.my.cfg> (mysql).
372 =item I<--compressor <gz[ip] (default)|zst[d]|zstd-max>]>
374 Select the compressor to process the rootfs archive with. C<gzip> is a good
375 choice to make the archive also available on older systems, but using C<zstd>
376 or even C<zstd-max> results in a higher compression ration while keeping
377 decompression very fast and highly efficient. Note that C<zstd-max> uses the
378 highest compression ratio without any decompression performance hit possible,
379 it will use as many threads as there are onlince CPU threads and may thus
380 increase the system load significantly for tens of seconds up to minutes.
386 List installed packages.
392 Also print package versions.
398 Remove all temporary files and destroy the container.
400 =item B<dab dist-clean>
402 Like clean, but also removes the package cache (except when you specified your
403 own cache directory in the config file)
409 dab is a script to automate the creation of LXC appliances. It is basically a
410 rewrite of debootstrap in perl, but uses LXC instead of chroot and generates
411 LXC templates. Another difference is that it supports multi-stage building of
412 templates. That way you can execute arbitrary scripts between to accomplish
415 Furthermore some common tasks are fully automated, like setting up a database
416 server (mysql or postgres).
418 To accomplish minimal template creation time, packages are cached to a local
419 directory, so you do not need a local debian mirror (although this would speed
422 See http://pve.proxmox.com/wiki/Debian_Appliance_Builder for examples.
424 This script need to be run as root, so it is not recommended to start it on a
425 production machine with running containers. So many people run Proxmox VE
426 inside a KVM or VMWare 64bit virtual machine to build appliances.
428 All generated templates includes an appliance description file. Those can be
429 used to build appliance repositories.
433 Configuration is read from the file C<dab.conf> inside the current working
434 directory. The files contains key value pairs, separated by colon.
438 =item B<Suite:> I<squeeze|wheezy|jessie|trusty|vivid>
440 The Debian or Ubuntu suite.
442 =item B<Source:> I<URL [components]>
444 Defines a source location. By default we use the following for debian:
446 Source: http://ftp.debian.org/debian SUITE main contrib
447 Source: http://security.debian.org SUITE/updates main contrib
449 Note: SUITE is a variable and will be substituted.
451 There are also reasonable defaults for Ubuntu. If you do not specify any source
452 the defaults are used.
454 =item B<Depends:> I<dependencies>
456 Debian like package dependencies. This can be used to make sure that speific
457 package versions are available.
459 =item B<CacheDir>: I<path>
461 Allows you to specify the directory where downloaded packages are cached.
463 =item B<Mirror:> I<SRCURL> => I<DSTURL>
465 Define a mirror location. for example:
467 Mirror: http://ftp.debian.org/debian => ftp://mirror/debian
471 All other settings in this files are also included into the appliance
476 =item B<Name:> I<name>
478 The name of the appliance.
480 Appliance names must consist only of lower case letters (a-z), digits (0-9),
481 plus (+) and minus (-) signs, and periods (.). They must be at least two
482 characters long and must start with an alphanumeric character.
484 =item B<Architecture:> I<i386|amd64>
488 =item B<Version:> I<upstream_version[-build_revision]>
490 The version number of an appliance.
492 =item: B<Section:> I<section>
494 This field specifies an application area into which the appliance has been
495 classified. Currently we use the following section names: system, mail
497 =item B<Maintainer:> I<name <email>>
499 The appliance maintainer's name and email address. The name should come first,
500 then the email address inside angle brackets <> (in RFC822 format).
502 =item B<Infopage:> I<URL>
504 Link to web page containing more informations about this appliance.
506 =item B<Description:> I<single line synopsis>
508 extended description over several lines (indended by space) may follow.
512 =head1 Appliance description file
514 All generated templates includes an appliance description file called
518 this is the first file inside the tar archive. That way it can be easily
519 exctracted without scanning the whole archive. The file itself contains
520 informations like a debian C<control> file. It can be used to build appliance
523 Most fields are directly copied from the configuration file C<dab.conf>.
525 Additionally there are some auto-generated files:
529 =item B<Installed-Size:> I<bytes>
531 It gives the total amount of disk space required to install the named
532 appliance. The disk space is represented in megabytes as a simple decimal
535 =item B<Type:> I<type>
537 This is always C<lxc>.
539 =item B<OS:> I<[debian-4.0|debian-5.0|ubuntu-8.0]>
545 Appliance repositories usually add additional fields:
549 =item B<md5sum:> I<md5sum>
557 The following files are created inside your working directory:
559 dab.conf appliance configuration file
561 logfile contains installation logs
563 .veid stores the used container ID
565 cache/* default package cache directory
567 info/* package information cache
571 Dietmar Maurer <dietmar@proxmox.com>
572 Thomas Lamprecht <t.lamprecht@proxmox.com>
574 Many thanks to Proxmox Server Solutions (www.proxmox.com) for sponsoring this
577 =head1 COPYRIGHT AND DISCLAIMER
579 Copyright (C) 2007-2021 Proxmox Server Solutions GmbH
581 Copyright: dab is under GNU GPL, the GNU General Public License.
583 This program is free software; you can redistribute it and/or modify
584 it under the terms of the GNU General Public License as published by
585 the Free Software Foundation; version 2 dated June, 1991.
587 This program is distributed in the hope that it will be useful,
588 but WITHOUT ANY WARRANTY; without even the implied warranty of
589 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
590 GNU General Public License for more details.
592 You should have received a copy of the GNU General Public License
593 along with this program; if not, write to the
594 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,