196 lines
3.9 KiB
Perl
Executable File
196 lines
3.9 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use Data::Dumper;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Snap;
|
|
|
|
setup();
|
|
|
|
my $conf = readconf();
|
|
my $templates = templates( $conf );
|
|
my $template = $ARGV[0] || Snap->error( 1, 'Failed to supply template' );
|
|
my $sources = Snap::Sources->new( $conf->{'sources'} );
|
|
my @basepkgs = qw( snap-base coreutils dash );
|
|
my @packages = ();
|
|
my $rootfs;
|
|
my $preinst;
|
|
my $rootpw;
|
|
my $postinst;
|
|
my $pid;
|
|
my $stat;
|
|
my $virtfs;
|
|
my $dialog;
|
|
|
|
if ( ! $snap->{'target'} ) {
|
|
Snap->error( -1, 'A target must be specified with -t' );
|
|
}
|
|
|
|
if ( ! $templates->{$template} ) {
|
|
Snap->error( -1, "$template: Invalid template" );
|
|
}
|
|
|
|
$rootfs = "$conf->{'snapinstall'}{'templatedir'}/$template/rootfs";
|
|
$preinst = "$conf->{'snapinstall'}{'templatedir'}"
|
|
. "/$template/preinst";
|
|
$postinst = "$conf->{'snapinstall'}{'templatedir'}"
|
|
. "/$template/postinst";
|
|
|
|
if ( -f $preinst ) {
|
|
pipe( my $reader, my $writer ) ||
|
|
Snap->error( int( $! ), "pipe(): $!" );
|
|
|
|
if ( $pid = fork() ) {
|
|
close( $writer );
|
|
}
|
|
else {
|
|
close( $reader );
|
|
open( STDERR, '>&', $writer );
|
|
exec( $preinst ) || die( $! );
|
|
|
|
exit;
|
|
}
|
|
|
|
waitpid( $pid, 0 );
|
|
$stat = $? >> 8;
|
|
|
|
while ( readline( $reader ) ) {
|
|
if ( $_ =~ /^([a-zA-Z]+)=\s*(.*)$/ ) {
|
|
$ENV{$1} = $2;
|
|
}
|
|
}
|
|
|
|
close( $reader );
|
|
}
|
|
|
|
$sources->readpkgs();
|
|
|
|
foreach my $pkgname ( @basepkgs ) {
|
|
my $package = $sources->latest( $pkgname );
|
|
|
|
$package->depends( $sources, \@packages );
|
|
|
|
if ( ! grep( $_ eq $package->{'name'}, @packages ) ) {
|
|
push( @packages, $package );
|
|
}
|
|
}
|
|
|
|
foreach my $pkgname ( @{$templates->{$template}{'packages'}} ) {
|
|
my $package = $sources->latest( $pkgname ) ||
|
|
Snap->error( 1, "$pkgname: Unable to find package" );
|
|
|
|
if ( grep( $_->{'name'} eq $pkgname, @packages ) ) {
|
|
next;
|
|
}
|
|
|
|
$package->depends( $sources, \@packages );
|
|
|
|
if ( ! grep( $_ eq $package->{'name'}, @packages ) ) {
|
|
push( @packages, $package );
|
|
}
|
|
}
|
|
|
|
open( $dialog, "|dialog --title ' Downloading Packages ' --gauge '' 8 70 0" );
|
|
select( $dialog );
|
|
|
|
foreach my $package ( @packages ) {
|
|
if ( $package->{'path'} =~ /https*:\/\// ) {
|
|
( my $filename = $package->{'path'} ) =~ s/.*\///;
|
|
|
|
if ( -f $snap->{'pkgdir'} . "/$filename" ) {
|
|
$package->{'path'} = $snap->{'pkgdir'} . "/$filename";
|
|
}
|
|
elsif ( -f "/var/lib/snap/packages/$filename" ) {
|
|
$package->{'path'} = "/var/lib/snap/packages/$filename";
|
|
}
|
|
else {
|
|
Snap->httpget( $package->{'path'},
|
|
"$snap->{'pkgdir'}/$filename", 0644,
|
|
{ dialog => 1 } );
|
|
|
|
$package->{'path'} = "$snap->{'pkgdir'}/$filename";
|
|
}
|
|
}
|
|
}
|
|
|
|
select( STDOUT );
|
|
close( $dialog );
|
|
|
|
if ( -d $rootfs && ! Snap->dirempty( $rootfs ) ) {
|
|
if ( $pid = fork() ) {
|
|
waitpid( $pid, 0 );
|
|
$stat = $? >> 8;
|
|
}
|
|
else {
|
|
# print "\nCopying rootfs files\n";
|
|
# exec( "cp -va '$rootfs'/* $snap->{'target'}" );
|
|
exec( "cp -a '$rootfs'/* $snap->{'target'}" );
|
|
}
|
|
|
|
if ( $stat ) {
|
|
Snap->error( $stat, "Failed to copy rootfs" );
|
|
}
|
|
}
|
|
|
|
open( $dialog, "|dialog --title ' Installing Packages ' --gauge '' 8 70 0" );
|
|
select( $dialog );
|
|
|
|
foreach my $package ( @packages ) {
|
|
if ( ! $virtfs ) {
|
|
$virtfs = virtfs( 'mount' );
|
|
}
|
|
|
|
# print "\n";
|
|
|
|
$package->install( $sources, { dialog => 1 } );
|
|
}
|
|
|
|
select( STDOUT );
|
|
close( $dialog );
|
|
|
|
print "\033[2J";
|
|
print "\033[0;0H";
|
|
|
|
trigger();
|
|
|
|
if ( -f $postinst ) {
|
|
my $tmpscript = "/var/lib/snap/postinst";
|
|
|
|
open( my $fh, '<', $postinst ) || Snap->error( int( $! ),
|
|
"Failed to open $postinst" );
|
|
open( my $wh, '>', "$snap->{'target'}/$tmpscript" ) ||
|
|
Snap->error( int( $! ), "Failed to open $tmpscript" );
|
|
chmod( 0755, "$snap->{'target'}/$tmpscript" );
|
|
|
|
while ( <$fh> ) {
|
|
print $wh $_;
|
|
}
|
|
|
|
close( $wh );
|
|
close( $fh );
|
|
|
|
if ( $pid = fork() ) {
|
|
waitpid( $pid, 0 );
|
|
$stat = $? >> 8;
|
|
}
|
|
else {
|
|
if ( $> ) {
|
|
exec( "fakeroot fakechroot /usr/sbin/chroot "
|
|
. "$snap->{'target'} $tmpscript" );
|
|
}
|
|
else {
|
|
exec ( "chroot $snap->{'target'} $tmpscript" );
|
|
}
|
|
}
|
|
|
|
if ( $stat ) {
|
|
Snap->error( $stat, "Failed to execute $tmpscript" );
|
|
}
|
|
}
|
|
|
|
if ( $virtfs ) {
|
|
virtfs( 'umount' );
|
|
}
|