#!/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' ); }