The following changes were made:

* removed usher
  * various cleanup in output
  * corrected issues with usher() in Package.pm, now using fork()/exec()
  * added snapinstall
  * made virtfs() more robust, will still attempt if fails
  * made strip a little more thoughtful in Makefile.snaplinux
This commit is contained in:
2017-05-22 10:43:07 -05:00
parent 47dfb92801
commit 6a9cce6b3f
9 changed files with 340 additions and 130 deletions

View File

@@ -19,7 +19,7 @@ ARCHIVE := $(PWD)/SRC/$(shell ls SRC|egrep '(bz2|gz|tar|xz)$$'|tail -1)
TYPE := $(shell file -ib $(ARCHIVE)|cut -d';' -f1|tr -d '\n')
SRCDIR := $(shell tar -tf $(ARCHIVE)|head -1|sed 's/\/.*//')
PATCHDIR := $(PWD)/SRC/patches
VERSION := $(shell echo $(SRCDIR)|egrep -o '\-[0-9].*'|sed 's/^-//')$(SNAPVER)
VERSION := $(shell echo $(SRCDIR)|egrep -o '\-[0-9].*'|sed 's/^-//')-$(SNAPVER)
include /usr/share/snap/Makefile.snaplinux

View File

@@ -13,7 +13,14 @@ PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
SNAPDIR = $(PWD)/SNAP
ROOT = $(PWD)/ROOT
# This allows the package Makefile to override the name
# of the package file. Added for the kernel package
# though could be useful for others
ifeq ( $(SNAP), )
SNAP = $(PACKAGE)-$(VERSION).snap
endif
SNAPINFO = $(SNAPDIR)/snapinfo
MANIFEST = $(SNAPDIR)/manifest
USHER = $(SNAPDIR)/usher
@@ -105,21 +112,19 @@ $(FILES): $(ROOT)
done; \
fi
if [ "$(PACKAGE)" != 'grub' ]; then
@find $(ROOT) -type f | while read -r file; do \
type=`file -i $$file|sed 's/.*: //'`; \
case $$type in \
*'/x-executable; charset=binary') \
strip --strip-unneeded $$file \
;; \
*'/x-object; charset=binary') \
strip --strip-unneeded $$file \
;; \
*'/x-sharedlib; charset=binary') \
strip --strip-unneeded $$file \
;; \
esac; \
done; \
fi
@find $(ROOT) -type f | while read -r file; do \
type=`file -i $$file|sed 's/.*: //'`; \
case $$type in \
*'/x-executable; charset=binary') \
strip --strip-unneeded $$file \
;; \
*'/x-object; charset=binary') \
strip --strip-debug $$file \
;; \
*'/x-sharedlib; charset=binary') \
strip --strip-debug $$file \
;; \
esac; \
done
@cd $(ROOT) && tar cvzf $(FILES) *

View File

@@ -255,7 +255,7 @@ sub depends {
} );
if ( ! $package ) {
push( @$failures, $depend );
push( @$failures, "$depend" );
next;
}
@@ -273,10 +273,9 @@ sub depends {
}
if ( @$failures ) {
print STDERR "Failed to resolve dependencies for"
. " $self->{'name'}!\n";
print STDERR "Failed to resolve dependencies\n";
Snap->error( -1, "depends(): dependencies failed: "
Snap->error( -1, "depends(): unresolved dependencies: "
. join( ",", @$failures ) );
}
@@ -402,7 +401,12 @@ sub install {
my $stat;
local $| = 1;
print "\e[?25lInstalling $self->{'name'}:\r";
$ENV{'VERSION'} = $self->{'version'};
if ( ! -f $self->{'path'} ) {
Snap->error( -1, "install(): $self->{'path'}:"
. " No such file or directory" );
}
if ( $self->{'path'} =~ /^https*:\/\// ) {
( my $filename = $self->{'path'} ) =~ s/.*\///;
@@ -443,13 +447,19 @@ sub install {
Snap->error( int( $! ), "rename(): $manifest: $!" );
}
print "Installing $self->{'name'}=$self->{'version'}\n";
$self->usher( 'preinst' );
print "\e[?25l\r";
eval {
my $target = Snap->TARGET || '/';
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"/usr/bin/ar p $self->{'path'} files.tar.gz|"
. "tar --no-overwrite-dir -hzvxf - -C "
. Snap->TARGET );
. "tar --no-overwrite-dir --keep-directory-symlink"
. " -hzvxf - -C $target" );
} || Snap->error( int( $! ), "open3(): /usr/bin/ar: $!" );
close( CHLDIN );
@@ -481,8 +491,7 @@ sub install {
if ( $file ) {
$cnt++;
print "\e[KInstalling "
. "$self->{'name'}: $file\r";
print "\e[K$file\r";
}
}
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
@@ -502,6 +511,8 @@ sub install {
. " $stderr\e[?25h" );
}
print "\e[K$cnt files extracted\e[?25h\n";
if ( $oldpkg ) {
foreach ( @{$oldpkg->{'files'}} ) {
if ( -f Snap->TARGET . "/$_" ) {
@@ -548,7 +559,7 @@ sub install {
Snap->error( int( $! ), "unlink(): $manifest: $!" );
}
print "\e[KInstalling $self->{'name'}: DONE\e[?25h\n";
print "Finished installing $self->{'name'}\n";
}
sub installed {
@@ -741,7 +752,7 @@ sub usher {
my $stderr;
my $stat;
if ( ! -f $usher || $action eq 'preinst' ) {
if ( $action eq 'preinst' ) {
my $cnt = 0;
eval {
@@ -769,17 +780,16 @@ sub usher {
if ( fileno( $fh ) == fileno( *CHLDOUT ) ) {
my $line = <$fh>;
if ( ! $cnt && $line =~
/^no entry usher in archive$/ ) {
last;
}
print USHER $line;
$cnt++;
}
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
$stderr .= <$fh>;
if ( $stderr =~ /^no entry usher/ ) {
last;
}
}
}
}
@@ -798,6 +808,8 @@ sub usher {
if ( ! $cnt && -f $usher ) {
unlink( $usher );
return;
}
}
@@ -805,17 +817,17 @@ sub usher {
return;
}
eval {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"TARGET=" . Snap->TARGET . " $usher $action" );
} || Snap->error( int( $! ), "open3():"
. " $usher ($action): $!" );
if ( $pid = fork() ) {
waitpid( $pid, 0 );
$stat = $? >> 8;
}
else {
exec( "$usher $action" );
}
close( CHLDIN );
$sel = IO::Select->new();
$sel->add( *CHLDOUT, *CHLDERR );
$sel = IO::Select->new();
if ( $stat ) {
Snap->error( $stat, "usher(): Failed executing usher" );
}
}
############################################################

View File

@@ -23,6 +23,7 @@ our @EXPORT = qw(
human
list
listfiles
virtfs
readconf
refresh
setup
@@ -118,6 +119,8 @@ $0 =~ s/.*\///;
############################################################
$SIG{INT} = sub{
virtfs( 'umount' );
print "\e[?25h\n";
exit( -1 );
@@ -125,7 +128,7 @@ $SIG{INT} = sub{
############################################################
#
# Export TARGET to the environment
# Export TARGET to the environment for usher
#
############################################################
@@ -195,6 +198,8 @@ sub error {
chomp( $errstr );
print "\e[?25h\n";
print STDERR ( caller() )[1] .":\n $errstr at line "
. ( caller() )[2] . "\n";
@@ -212,6 +217,8 @@ sub error {
print "\n";
if ( $status ) {
virtfs( 'umount' );
exit( $status );
}
}
@@ -404,6 +411,26 @@ sub human {
return( $human );
}
sub ismountpoint {
my $dir = shift;
my $statA;
my $statB;
if ( ! -d $dir ) {
return( 0 );
}
$statA = ( stat( $dir ) )[0];
$statB = ( stat( "$dir/.." ) )[0];
if ( $statA == $statB ) {
return( 0 );
}
else {
return( 1 );
}
}
sub list {
my $packages = {};
my $package = {};
@@ -638,20 +665,50 @@ sub sha256 {
}
sub termsize {
require 'sys/ioctl.ph';
my $data;
my $row;
my $col;
my $row = 24;
my $col = 80;
my $sel = IO::Select->new();
my $stdout;
my $stderr;
my $stat;
my $pid;
open( TTY, "+</dev/tty" ) || Snap->error( 0, "No tty: $!" );
eval {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"stty size -F /dev/tty" );
} || return( { row => $row, col => $col } );
if ( ! ioctl( TTY, &TIOCGWINSZ, $data='' ) ) {
Snap->error( 0, "Failed to determine window size" );
close( CHLDIN );
$sel->add( *CHLDOUT, *CHLDERR );
while ( my @fhs = $sel->can_read ) {
foreach my $fh ( @fhs ) {
if ( eof( $fh ) ) {
$sel->remove( $fh );
next;
}
if ( fileno( $fh ) == fileno( *CHLDOUT ) ) {
$stdout .= <$fh>;
}
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
$stderr .= <$fh>;
}
}
}
close( TTY );
close( CHLDOUT );
close( CHLDERR );
( $row, $col ) = unpack( 'S4', $data );
waitpid( $pid, 0 );
$stat = $? >> 8;
if ( $stdout =~ /(\d+)\s+(\d+)/ ) {
$row = $1;
$col = $2;
}
return( { row => $row, col => $col } );
}
@@ -732,4 +789,108 @@ sub vercmp {
@A <=> @B;
}
sub virtfs {
my $command = shift;
my $virtfs = {
dev => {
fs => 'devtmpfs',
dev => 'none',
dir => TARGET . '/dev'
},
proc => {
fs => 'proc',
dev => 'none',
dir => TARGET . '/proc'
},
sys => {
fs => 'sysfs',
dev => 'none',
dir => TARGET .'/sys'
}
};
if ( ! TARGET ) {
return;
}
foreach my $fs ( sort( keys( %$virtfs ) ) ) {
my $sel;
my $cmd;
my $stdout = '';
my $stderr = '';
my $stat = 0;
my $pid;
if ( ! -f $virtfs->{$fs}{'dir'} ) {
next;
}
if ( $command eq 'mount' ) {
if ( ismountpoint( $virtfs->{$fs}{'dir'} ) ) {
next;
}
$cmd = "mount -t $virtfs->{$fs}{'fs'}"
. " $virtfs->{$fs}{'dev'}"
. " $virtfs->{$fs}{'dir'}";
}
elsif ( $command eq 'umount' ) {
if ( ! ismountpoint( $virtfs->{$fs}{'dir'} ) ) {
next;
}
$cmd = "umount $virtfs->{$fs}{'dir'}";
}
else {
Snap->error( -1, "virtfs(): $command:"
. " not a valid command" );
}
eval {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR, $cmd );
} || Snap->error( int( $! ), "open3(): $cmd: $!" );
close( CHLDIN );
$sel = IO::Select->new();
$sel->add( *CHLDOUT, *CHLDERR );
while ( my @fhs = $sel->can_read ) {
foreach my $fh ( @fhs ) {
if ( eof( $fh ) ) {
$sel->remove( $fh );
next;
}
if ( fileno( $fh ) == fileno( *CHLDOUT ) ) {
$stdout .= <$fh>;
}
elsif ( fileno( $fh ) == fileno( *CHLDERR ) ) {
$stderr .= <$fh>;
}
}
}
close( CHLDOUT );
close( CHLDERR );
waitpid( $pid, 0 );
$stat = $? >> 8;
if ( $stat ) {
Snap->error( $stat, "Failed $command for"
. " $virtfs->{$fs}{'dir'}: $stderr" );
}
}
foreach my $fs ( sort( keys( %$virtfs ) ) ) {
if ( ! ismountpoint( $virtfs->{$fs}{'dir'} ) ) {
return( 0 );
}
}
return( 1 );
}
1;

View File

@@ -219,7 +219,7 @@ sub search {
if ( ! @$packages ) {
if ( $opts->{'name'} && $opts->{'version'} ) {
Snap->error( 0, "Snap::Sources::search():"
. " $opts->{'name'}=$opts->{'version'}:"
. " $opts->{'name'}$opts->{'version'}:"
. " No such package" );
}
elsif ( $opts->{'name'} ) {

View File

@@ -102,6 +102,7 @@ elsif ( $command eq 'install' ) {
my $string = "@ARGV";
my $packages = [];
my $bytes = 0;
my $virtfs = 0;
foreach my $attrib ( @attribs ) {
if ( $string =~ /$attrib\s*:\s*(\S+)/ ) {
@@ -291,17 +292,31 @@ elsif ( $command eq 'install' ) {
}
}
print "\n\nInstall will require " . human( $bytes )
. ". Continue? (y/n): ";
if ( $bytes < 0 ) {
print "\n\nInstall will recover " . human( -1 * $bytes )
. ". Continue? (y/n): ";
}
else {
print "\n\nInstall will require " . human( $bytes )
. ". Continue? (y/n): ";
}
chkyes();
print "\n";
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
$package->install( $sources );
}
if ( $virtfs ) {
virtfs( 'umount' );
}
print "\n";
}
elsif ( $command eq 'list' ) {
@@ -498,35 +513,6 @@ elsif ( $command eq 'search' ) {
exit -1;
}
print "\n";
}
elsif ( $command eq 'setup' ) {
my $opts = {
repo => 'core',
quiet => 1
};
my $packages;
print "\n";
if ( ! Snap->TARGET ) {
Snap->error( -1, 'A target must be specified with -t' );
}
$sources->readpkgs();
$packages = $sources->search( $opts );
for ( my $i = 0; $i <= $#$packages; $i++ ) {
if ( $packages->[$i]{'name'} eq 'snap-base' ) {
unshift( @$packages, $packages->[$i] );
splice( @$packages, $i+1, 1 );
}
}
foreach my $package ( @$packages ) {
$package->install();
}
print "\n";
}
elsif ( $command eq 'verify' ) {

89
SRC/snapinstall Executable file
View File

@@ -0,0 +1,89 @@
#!/usr/bin/perl
use strict;
use warnings;
use Snap;
use Data::Dumper;
setup();
my $conf = readconf();
my $sources = Snap::Sources->new( $conf->{'sources'} );
my $opts = {
repo => 'core',
quiet => 1
};
my $corepkgs;
my $packages;
my $virtfs = 0;
my $prepkgs = {};
my $prelist = [ 'snap-base', 'bash', 'coreutils', 'glibc',
'libacl', 'libattr', 'libcap', 'ncurses', 'readline',
'tzdata', 'perl', 'initscripts' ];
print "\n";
if ( ! Snap->TARGET ) {
Snap->error( -1, 'A target must be specified with -t' );
}
$sources->readpkgs();
$corepkgs = $sources->search( $opts );
for ( my $i = 0; $i <= $#$corepkgs; $i++ ) {
if ( ! $opts->{'nodeps'} ) {
print "Resolving dependencies for"
. " $corepkgs->[$i]{'name'}\n";
$corepkgs->[$i]->depends( $sources, $packages );
}
else {
print "Ignoring dependencies for"
. " $corepkgs->[$i]{'name'}\n";
}
push( @$packages, $corepkgs->[$i] );
}
for ( my $i = 0; $i <= $#$packages; $i++ ) {
if ( $packages->[$i]{'path'} =~ /https*:\/\// ) {
( my $filename = $packages->[$i]{'path'} ) =~ s/.*\///;
if ( ! -f Snap->PKGDIR . "/$filename" ) {
Snap->httpget( $packages->[$i]{'path'},
Snap->PKGDIR . "/$filename", 0644 );
}
$packages->[$i]{'path'} = Snap->PKGDIR . "/$filename";
}
if ( grep( $_ eq $packages->[$i]{'name'}, @$prelist ) ) {
$prepkgs->{$packages->[$i]{'name'}} = $packages->[$i];
splice( @$packages, $i, 1 );
$i--;
}
}
foreach my $package ( @$prelist ) {
print "\n";
$prepkgs->{$package}->install();
}
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
print "\n";
$package->install();
}
virtfs( 'umount' );
print "\n";