10 Commits

Author SHA1 Message Date
Jay Larson
915fb3e1f0 The following changes were made:
* snapinstall now has template system
  * added code to symlink modules to different compatible kernel versions
  * snap will now detect if kernel or module package
  * snap remove should clean up directories not in snap-base
  * snap now exports $VERSION for usher
  * snap verify now works - will verify all installed files for package
  * a number of other small fixes and tweaks
2018-04-06 12:42:17 -05:00
Jay Larson
6b62f87bf6 The following changes were made:
* Cleaned up some output and variable assignments
  * Added additional error handling/output
  * Implemented 'source' command (git clones)
  * More variable requirements for Makefile.snaplinux
  * Package.pm is now more sane in dealing with the package object
  * Added chroot/fakechroot (will likely need further tweaking!)
  * Improved locking
  * Added ability to use templates for snapinstall (will be expanded!)
2018-01-17 09:25:06 -06:00
Jay Larson
d4baa191d6 Declared $pid in snapinstall 2017-06-02 18:54:55 -05:00
Jay Larson
98c0ab336f The following changes were made:
* Updated Makefile.snaplinux to be more flexible with package names
  * Added bit to set root password in snapinstall
2017-06-02 18:49:47 -05:00
Jay Larson
cdbf4ed7d5 The following changes were made:
* Added ability to dump contents of package
  * Wrapped open3 in eval in Package.pm files()
  * Added :flock to Fcntl in Snap.pm
  * Added lock file to Snap.pm
  * Moved setup() under conditionals where appropriate in snap
2017-06-01 10:39:51 -05:00
Jay Larson
bfa1d110c4 The following changes were made
* Updated Makefile to get version from Snap.pm
  * Updated virtfs() in Snap.pm to properly check for dir with -d
2017-05-31 10:54:33 -05:00
Jay Larson
d306fe03ae The following changes were made:
* corrected issue in reinstall that prevented reinstall of package files
  * added version command
  * updated files() in Package.pm to accept both quiet and verbose options
  * added sha() to Snap.pm which will be used for verify function in future
  * corrected missing '=' in output for search() in Sources.pm
  * removed duplicate file (SRC/snapinstall)
2017-05-26 15:48:52 -05:00
Jay Larson
319401eb51 Corrected issue in assignment to $(SNAP) in Makefile.snaplinux 2017-05-22 14:46:14 -05:00
Jay Larson
4cd5b95d7e The following changes were made:
* Added snapinstall (missed on last check in)
  * Added reinstall functionality to snap
2017-05-22 14:15:38 -05:00
Jay Larson
6a9cce6b3f 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
2017-05-22 10:43:07 -05:00
17 changed files with 2146 additions and 378 deletions

View File

@@ -8,17 +8,19 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
DEPENDS = binutils,coreutils,gzip,perl=5.20.0,tar
DEPENDS = binutils,coreutils,gzip,perl>=5.20.0,tar
ARCH = x86_64
URL =
URL = http://snaplinux.org
REPO = core
BRIEF = The Snaplinux package management system
DESC = The Snaplinux package management system
SNAPVER = 0
ARCHIVE := ''
SRCDIR := $(PWD)/SRC/snap
PATCHDIR := $(PWD)/SRC/patches
VERSION := 0.4-0
MAKEINST = make install
VERSION := $(shell grep 'VERSION =>' SRC/snap/Snap.pm| \
sed "s/.*=> '\|',//g")-$(SNAPVER)
include /usr/share/snap/Makefile.snaplinux
@@ -29,7 +31,7 @@ $(ROOT): $(SRCDIR)/Makefile
mkdir -v $(ROOT); \
fi
@cd $(SRCDIR) && $(MAKEINST) DESTDIR=$(ROOT)
@cd $(SRCDIR) && make install DESTDIR=$(ROOT)
clean:
@rm -rvf $(ROOT) \

View File

@@ -1,43 +0,0 @@
#!/bin/bash
set -e
case $1 in
preinst)
exit 0
;;
postinst)
setpass=`cat ${TARGET}/etc/shadow|grep ^root|awk -F':' '{print $2}'`
if [ "$setpass" == 'SETPASS' ]; then
echo "Setting root password"
if [[ ${TARGET} ]]; then
if ! mountpoint ${TARGET}/dev; then
mount -o ro -t devtmpfs devtmpfs ${TARGET}/dev
chroot ${TARGET} passwd root
umount ${TARGET}/dev
else
chroot ${TARGET} passwd root
fi
else
passwd root
fi
fi
echo "Refreshing snap"
if [[ ${TARGET} ]]; then
chroot ${TARGET} snap refresh
else
snap refresh
fi
exit 0
;;
prerm)
exit 0
;;
postrm)
exit 0
;;
esac

View File

@@ -48,10 +48,10 @@ my $commands = {
],
brief => 'List package info',
help => [
"\t\tPKGNAME or FILE is required."
. " A version string\n\t\t\t\tcan optionally"
. " be provided with the PKGNAME\n"
. "\t\t\t\tas packagename=x.x.x\n",
"\t\tOne or more PKGNAME or FILE is required.\n"
. "\t\t\t\tA version string can optionally"
. " be provided\n\t\t\t\twith PKGNAME"
. " as packagename=x.x.x\n",
"\t\t\tAn optional target may be specified"
. " to\n\t\t\t\tquery a separate directory"
. "/file system"
@@ -92,6 +92,10 @@ my $commands = {
. "/file system"
]
},
provides => {
options => [],
brief => 'List packages that provide a file'
},
purge => {
options => [
'<PKGNAME>',
@@ -150,6 +154,17 @@ my $commands = {
"\t\t\t\tProceed without prompting"
]
},
revdep => {
options => [
'<PKGNAME>',
'[-t TARGET]'
],
brief => 'List installed packages that depend on <PKGNAME>',
help => [
"\t\t\tPKGNAME is required\n",
"\t\t\tAn optional target may be specified"
]
},
search => {
options => [
'[STRING[=VER]]',
@@ -167,14 +182,16 @@ my $commands = {
},
source => {
options => [
'<PKGNAME[=VER]>'
'<PKGNAME[=VER]>',
'[-l]'
],
brief => 'Retrieve package source',
help => [
"\t\tPKGNAME is required."
. " A version string\n\t\t\t\tcan optionally"
. " be provided with the PKGNAME\n"
. "\t\t\t\tas packagename=x.x.x"
. "\t\t\t\tas packagename=x.x.x\n",
"\t\t\t\tRetrieve the latest version"
]
},
upgrade => {
@@ -208,6 +225,11 @@ my $commands = {
. " separate\n\t\t\t\tdirectory/file system\n",
"\t\t\t\tProceed without prompting"
]
},
version => {
options => [],
brief => 'Display version information',
help => []
}
};
@@ -222,14 +244,16 @@ sub commandhelp {
my $options = $commands->{$command}{'options'};
my $help = $commands->{$command}{'help'};
print "\nsnap $command @{$commands->{$command}{'options'}}\n\n";
print "$commands->{$command}{'brief'}\n\n";
print "snap $command @{$commands->{$command}{'options'}}\n\n";
print "$commands->{$command}{'brief'}\n";
for ( my $i = 0; $i <= $#{$options}; $i++ ) {
print " $options->[$i]$help->[$i]\n";
print "\n $options->[$i]$help->[$i]";
}
print "\n";
if ( @$options ) {
print "\n";
}
}
sub new {
@@ -243,7 +267,7 @@ sub help {
Snap->error( -1, "usage(): Invalid option '$ARGV[0]'" );
}
print "\nUsage: $0 <COMMAND> <ARGS>\n\n"
print "Usage: $0 <COMMAND> <ARGS>\n\n"
. "snap is the Snaplinux package management utility\n\n"
. "COMMANDS\n\n";
@@ -252,7 +276,7 @@ sub help {
}
print "\nTo view more information for commands run:\n"
. "snap <COMMAND> -h\n\n";
. "snap <COMMAND> -h\n";
}
1;

View File

@@ -1,10 +1,12 @@
dirs:
install -d -v -m 755 $(DESTDIR)/etc
install -d -v -m 755 $(DESTDIR)/usr/{bin,share/snap}
install -d -v -m 755 $(DESTDIR)/etc/snap.d/templates
install -d -v -m 755 $(DESTDIR)/usr/bin
install -d -v -m 755 $(DESTDIR)/usr/share/snap
install -d -v -m 755 $(DESTDIR)/usr/lib/perl5/vendor_perl/5.24.0/Snap
files:
install -v -m 755 snap $(DESTDIR)/usr/bin/snap
install -v -m 755 snapinstall $(DESTDIR)/usr/bin/snapinstall
install -v -m 644 Makefile.skel \
$(DESTDIR)/usr/share/snap/Makefile.skel
install -v -m 644 Makefile.snaplinux \
@@ -17,5 +19,9 @@ files:
$(DESTDIR)/usr/lib/perl5/vendor_perl/5.24.0/Snap/Sources.pm
install -v -m 644 Snap.pm \
$(DESTDIR)/usr/lib/perl5/vendor_perl/5.24.0/Snap.pm
@find templates -type d -exec install {} -d -v -m 755 \
$(DESTDIR)/etc/snap.d/templates/{} \; && \
find templates -type f -exec install {} -v -m 644 \
$(DESTDIR)/etc/snap.d/templates/{} \;
install: dirs files

View File

@@ -8,10 +8,66 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
DEPENDS =
# Some, but not all of variables are required. The following list
# describes the required variables:
#
# * URL: The main website of the upstream project
# * REPO: The location of the package on the source pacakge
# server. This might be one of core, main, dev, or
# perhaps others.
# * BRIEF: Short description, should be 50 chars or less
# * SNAPVER: This is the package version. When a package is
# changed, but no changes are made to the source code
# this value should be increased. This would include
# things like usher being modified, changes to default
# configuration files, file permissions, etc.
# * ARCHIVE: The default commands that set this variable should
# work in most cases, but in some cases it may need
# to be modified. This variable should contain the
# path to the source of the package (./SRC/filename)
# * TYPE: This is probably not really needed due to the
# ability of gnu tar to figure it out on its own.
# Should probably be removed at some point.
# * SRCDIR: This is the name of the source directory after the
# package source is extracted. The default command
# should in most cases set this automatically.
# * PATCHDIR: This directory should be ./SRC/patches and is
# required, whether or not patches are used.
# * VERSION: This should be set automatically based on the
# version string in the source directory and SNAPVER.
# The default command here should work in many cases,
# but certain packages may need to use a different
# method.
#
# Variables that aren't required:
#
# * ARCH: This should be populated for packages which contain
# compiled binaries. If it is not populated the ARCH
# will be set to 'noarch'.
# * DEPENDS: If any other packages are required for this package
# to function then they need to be listed here,
# preferably in alphabetical order.
# * BUILDDEPS: Any package beyond packages from the core repo
# need to be listed here. The idea is that we
# can automate building and testing packages
# from clean core systems. The core repo is
# intended to include only the base minimum
# packages which provide a functional system.
# * SRCPKG: By default this is populated automatically with
# the name of the package (current directory). If
# the source package is used to generate multiple
# packages then this variable should contain the
# name of the git repo that tracks the source.
# * DESC: This is to be used to provide a longer description
# of the package.
ARCH =
DEPENDS =
BUILDDEPS =
SRCPKG =
URL =
BRIEF =
REPO =
BRIEF =
DESC =
SNAPVER =
@@ -19,7 +75,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
@@ -50,6 +106,11 @@ $(SRCDIR)/config.log: $(SRCDIR)/configure
--host=x86_64-snap-linux-gnu \
--target=x86_64-snap-linux-gnu
# binfile should be replaced with a file generated by the
# make process. It won't really break anything if not
# set to a valid file, but the source make process will
# be re-executed even if it isn't necessary
$(SRCDIR)/binfile: $(SRCDIR)/config.log
@cd $(SRCDIR) && make

View File

@@ -8,56 +8,107 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
export SHELL := /bin/bash
PWD := $(shell pwd)
PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
SNAPDIR = $(PWD)/SNAP
ROOT = $(PWD)/ROOT
SNAP = $(PACKAGE)-$(VERSION).snap
SNAPINFO = $(SNAPDIR)/snapinfo
MANIFEST = $(SNAPDIR)/manifest
USHER = $(SNAPDIR)/usher
FILES = $(SNAPDIR)/files.tar.gz
# This will set PACKAGE to the name of the current working directory
# if the package itself has not provided a package name
# If multiple packages are pulled from a single source
# then that source needs to be specified in SRCPKG, but
# if we find that not to be supplied we're going to
# assume that the SRCPKG is the same as the PACKAGE
ifeq ( $(SRCPKG), )
SRCPKG := $(PACKAGE)
ifndef PACKAGE
PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
endif
# The following values must be set in the Makefile for the package
# If VERSION is not set then we must fail
ifndef VERSION
$(error VERSION is not set)
endif
$(SNAP): $(SNAPINFO) $(FILES)
@if [ -f $(SNAP) ]; then \
rm -v $(SNAP); \
# This defines the name of the package file unless
# it is already specified in the package Makefile
ifndef PKGFILE
PKGFILE := $(PACKAGE)-$(VERSION).snap
endif
# If ARCH is not set we will assume noarch
ifndef ARCH
ARCH := noarch
endif
# SRCPKG defines the git repo name from which the package
# is built. In many cases it should be the same as the
# package name, but in cases where multiple packages are
# built from the same source this is especially relevant.
ifndef SRCPKG
SRCPKG := $(PACKAGE)
endif
# URL is required - this should point to the upstream project
ifndef URL
$(error URL is not set)
endif
# REPO is required. This value is used to determine the
# location of the package on the package source server
ifndef REPO
$(error REPO is not set)
endif
SNAPINFO = $(SNAPDIR)/snapinfo
MANIFEST = $(SNAPDIR)/manifest
USHER = $(SNAPDIR)/usher
FILES = $(SNAPDIR)/files.tar.gz
# BRIEF is required.
ifndef BRIEF
$(error BRIEF is not set)
endif
$(PKGFILE): $(SNAPINFO) $(FILES)
@if [ -f $(PKGFILE) ]; then \
rm -v $(PKGFILE); \
fi
@ar cvr $(SNAP) $(SNAPINFO) $(MANIFEST); \
@ar cvr $(PKGFILE) $(SNAPINFO) $(MANIFEST); \
if [ -f $(USHER) ]; then \
chmod +x $(USHER); \
ar cvr $(SNAP) $(USHER); \
ar cvr $(PKGFILE) $(USHER); \
fi; \
ar cvr $(SNAP) $(FILES)
ar cvr $(PKGFILE) $(FILES)
@echo "Successfully built $(SNAP)"
@echo "Successfully built $(PKGFILE)"
$(SNAPINFO): $(MANIFEST)
@>$(SNAPINFO)
$(eval BYTES := $(shell gzip -l $(FILES)|tail -1|awk '{print $$2}'))
$(eval SHA256MAN := $(shell sha256sum $(MANIFEST)|awk '{print $$1}'))
@printf "name: $(PACKAGE)\nversion: $(VERSION)\n" > $(SNAPINFO) && \
printf "depends: $(DEPENDS)\narch: $(ARCH)\n" >> $(SNAPINFO) && \
printf "srcpkg: $(SRCPKG)\nbytes: $(BYTES)\n" >> $(SNAPINFO) && \
printf "url: $(URL)\nsha256man: $(SHA256MAN)\n" >> $(SNAPINFO) && \
printf "brief: $(BRIEF)\ndescription: $(DESC)" >> $(SNAPINFO)
@fields=( \
"name: $(PACKAGE)" \
"version: $(VERSION)" \
"arch: $(ARCH)" \
"depends: $(DEPENDS)" \
"builddeps: $(BUILDDEPS)" \
"srcpkg: $(SRCPKG)" \
"bytes: $(BYTES)" \
"url: $(URL)" \
"repo: $(REPO)" \
"sha256man: $(SHA256MAN)" \
"brief: $(BRIEF)" \
"description: $(DESC)" \
) && \
for field in "$${fields[@]}"; do \
printf "$$field\n"; \
done > $(SNAPINFO)
$(MANIFEST): $(FILES)
@>$(MANIFEST)
@@ -99,27 +150,31 @@ $(FILES): $(ROOT)
fi
@if [ -d $(ROOT)/usr/share/info ]; then \
find $(ROOT)/usr/share/info -type f -name \*.info| \
while read -r file; do \
find $(ROOT)/usr/share/info -name '*.info' -o \
-name '*.info-[0-9]*'|while read -r file; do \
gzip $$file; \
done; \
if [ -f $(ROOT)/usr/share/info/dir ]; then \
rm -v $(ROOT)/usr/share/info/dir; \
fi; \
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') \
echo "--strip-unneeded $$file"; \
strip --strip-unneeded $$file \
;; \
*'/x-object; charset=binary') \
echo "--strip-debug $$file"; \
strip --strip-debug $$file \
;; \
*'/x-sharedlib; charset=binary') \
echo "--strip-debug $$file"; \
strip --strip-debug $$file \
;; \
esac; \
done
@cd $(ROOT) && tar cvzf $(FILES) *

File diff suppressed because it is too large Load Diff

View File

@@ -7,12 +7,11 @@ use Snap::Commands;
use Snap::Package;
use Snap::Sources;
use Fcntl;
use Fcntl qw( :flock );
use IPC::Open3;
use IO::Socket::INET;
use Digest::SHA qw( sha256_hex );
use Digest::SHA qw( sha1_hex sha256_hex );
use POSIX;
use Data::Dumper;
use parent 'Exporter';
our @EXPORT = qw(
@@ -21,12 +20,17 @@ our @EXPORT = qw(
genpkg
httpget
human
kernver
list
listfiles
virtfs
readconf
refresh
setup
sha
sha256
target
templates
termsize
vercmp
);
@@ -86,7 +90,7 @@ use constant VERFILE => eval {
}
};
use constant {
VERSION => '0.3',
VERSION => '0.13',
SNAPDIR => TARGET . '/var/lib/snap',
PKGDIR => TARGET . '/var/lib/snap/packages',
INSTDIR => TARGET . '/var/lib/snap/installed',
@@ -102,6 +106,17 @@ use constant SNAPVER => eval {
return( $version );
};
use constant LOCKFILE => TARGET . '/.snap';
############################################################
#
# Verify TARGET is a valid directory
#
############################################################
if ( TARGET && ! -d TARGET ) {
Snap->error( -1, TARGET . ": invalid target directory" );
}
############################################################
#
@@ -118,6 +133,10 @@ $0 =~ s/.*\///;
############################################################
$SIG{INT} = sub{
if ( TARGET ) {
virtfs( 'umount' );
}
print "\e[?25h\n";
exit( -1 );
@@ -125,7 +144,7 @@ $SIG{INT} = sub{
############################################################
#
# Export TARGET to the environment
# Export TARGET to the environment for usher
#
############################################################
@@ -165,9 +184,9 @@ sub chkyes {
chomp( $yes );
if ( lc( $yes ) eq 'n' ){
print STDERR "\nAborting!\n\n";
print STDERR "\nAborting!\n";
exit 1;
exit( 1 );
}
elsif ( lc( $yes ne 'y' ) ){
print "Answer 'y' or 'n': ";
@@ -177,6 +196,36 @@ sub chkyes {
}
}
### dirempty() #############################################
#
# A simple test for an empty directory. The default $empty
# is 1 (meaning there are no files in the directory), and
# $empty is set to 0 if any files are found.
#
############################################################
sub dirempty {
my $class = shift;
my $dir = shift;
my $empty = 1;
if ( ! -d $dir ) {
Snap->error( -1, "dirempty(): $dir: Invalid directory" );
}
opendir( my $dh, $dir ) || Snap->error( int( $! ), "dirempty(): $!" );
while ( readdir( $dh ) ) {
if ( $_ ne '.' && $_ ne '..' ) {
$empty = 0;
last;
}
}
return( $empty );
}
### error() ################################################
#
# All errors should be sent here. This sub takes a status
@@ -195,6 +244,8 @@ sub error {
chomp( $errstr );
print "\e[?25h\n";
print STDERR ( caller() )[1] .":\n $errstr at line "
. ( caller() )[2] . "\n";
@@ -212,6 +263,8 @@ sub error {
print "\n";
if ( $status ) {
virtfs( 'umount' );
exit( $status );
}
}
@@ -225,7 +278,7 @@ sub error {
############################################################
sub genpkg{
my $pkgname = shift;
my $pkgname = shift || Snap->error( -1, "genpkg(): pkgname missing" );
my $skelfile = '/usr/share/snap/Makefile.skel';
my $snapreadme = "This is the directory where the manifest, snapinfo,\n"
. "and files.tar.gz files will be created. It is also\n"
@@ -284,7 +337,9 @@ sub httpget {
PeerPort => 'http(80)',
Proto => 'tcp'
) || Snap->error( int( $! ), "IO::Socket::Inet->new(): $!" );
my $bytes;
my $bytes = 0;
my @wheel = qw( - \ | / );
my $p = 0;
local $| = 1;
@@ -305,7 +360,7 @@ sub httpget {
while ( <$sock> ) {
if ( $dest ) {
$bytes = ( stat( $dest ) )[7] || 0;
$bytes += length( $_ );
}
if ( ! $httpget{'dflag'} ) {
@@ -356,24 +411,25 @@ sub httpget {
$httpget{'length'} * 100 );
}
print "Retrieving $filename [";
printf( "%-50.50s [%-20s] %s\r",
" $wheel[$p] Downloading $filename",
'*' x int( $httpget{'pct'} / 5 ),
"$httpget{'pct'}%" );
for ( my $i = 0; $i < 20; $i++ ){
if ( $i < $httpget{'pct'} / 5 ) {
print '*';
}
else {
print ' ';
}
if ( $p >= $#wheel ) {
$p = 0;
}
else {
$p++;
}
print "] $httpget{'pct'}%\r";
}
}
if ( $dest ) {
print "Retrieving $filename [********************] 100%"
. "\e[?25h\n";
printf( "%-50.50s [%-20s] %s\e[?25h\n",
" * Downloaded $filename",
'*' x 20,
'100%' );
close( DEST );
}
@@ -404,7 +460,70 @@ 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 issnap {
my $class = shift;
my $file = shift;
my $lines = 0;
my $snapinfo = 0;
my $name = 0;
my $version = 0;
my $issnap = 0;
open( FILE, "<$file" ) || Snap->error( -1, "open(): $file: $!" );
while ( <FILE> ) {
if ( substr( $_, 0, 9 ) eq 'snapinfo/' ) {
$snapinfo++;
}
elsif ( substr( $_, 0, 5 ) eq 'name:' ) {
$name++;
}
elsif ( substr( $_, 0, 8 ) eq 'version:' ) {
$version++;
}
$lines++;
if ( $lines >= 12 ) {
last;
}
}
close( FILE ) || Snap->error( -1, "close(): $file: $!" );
if ( $snapinfo && $name && $version ) {
return( 1 );
}
return( 0 );
}
sub kernver {
return( ( uname() )[2] );
}
sub list {
my $listpackages = shift;
my $packages = {};
my $package = {};
@@ -412,7 +531,8 @@ sub list {
. INSTDIR . ": $!" );
foreach my $dir ( sort { $a cmp $b } readdir( DIR ) ) {
if ( $dir =~ /^\.{1,2}$/ || ! -f INSTDIR . "/$dir/snapinfo" ) {
if ( $dir =~ /^\.{1,2}$/ || ! -f INSTDIR . "/$dir/snapinfo" ||
$listpackages->[0] && ! grep( $dir =~ /$_/, @$listpackages ) ) {
next;
}
@@ -470,6 +590,13 @@ sub listfiles {
return( $listfiles );
}
sub lock {
open( LOCK, '>', LOCKFILE ) || Snap->error( int( $! ), "open(): "
. LOCKFILE . ": Unable to open lock file" );
flock( LOCK, LOCK_EX|LOCK_NB ) || Snap->error( int( $! ), "flock(): "
. LOCKFILE . ": Unable to lock file" );
}
sub mkdirp{
( my $dir = shift ) =~ s/\/^//;
my $mode = shift;
@@ -486,37 +613,60 @@ sub mkdirp{
### readconf() #############################################
#
# reads CONFFILE and builds a data structure with the
# parsed values. Only the 'sources' section is treated
# in a special way - it is pushed into an array to maintain
# the order. This allows us to give priority to the topmost
# repositories
# reads INI style files and builds a data structure with the
# parsed values.
#
# The config file can 'include' additional directories.
# Files in these directories will be parsed and added to
# the the data structure.
#
# Files ending in .conf will be parsed into the root of the
# data structure while .spt (snap package template) files
# will be stored in 'templates'
#
############################################################
sub readconf {
my $conffile = shift || CONFFILE;
my $data = shift || {};
my $section = '';
my $data = {};
my $line = 0;
my $type;
open( FILE, "<", CONFFILE ) || Snap->error( int( $! ),
"open: " . CONFFILE . ": $!\n" );
open( my $fh, "<", $conffile ) || Snap->error( int( $! ),
"open(): $conffile: $!\n" );
while ( <FILE> ) {
while ( <$fh> ) {
chomp( $_ );
if ( $_ =~ /^\s*#/ ) {
if ( $_ =~ /^\s*#/ || $_ =~ /^$/ ) {
next;
}
elsif ( $_ =~ /\s*include\s+(.*)$/ ) {
foreach my $dir ( split( ' ', $1 ) ) {
opendir( my $dh, $dir ) ||
Snap->error( int( $! ),
"opendir(): $dir: $!" );
while ( my $file = readdir( $dh ) ) {
if ( -f "$dir/$file" ) {
readconf( "$dir/$file", $data );
}
}
closedir( $dh ) || Snap->error( int( $! ),
"closedir(): $dir: $!" );
}
}
elsif ( $_ =~ /\s*\[(\S+)\]\s*/ ) {
$section = $1;
if ( $section eq 'sources' ) {
if ( $section eq 'sources' && ! $data->{$section} ) {
$data->{$section} = [];
}
}
elsif ( $section eq 'sources' &&
$_ =~ /(\S+)\s*=\s*(.*)$/ ) {
elsif ( $section eq 'sources' ) {
push( @{$data->{$section}}, $_ );
}
elsif ( $_ =~ /(\S+)\s*=\s*(.*)$/ ) {
@@ -524,7 +674,7 @@ sub readconf {
}
}
close( FILE );
close( $fh );
return( $data );
}
@@ -567,35 +717,6 @@ sub setup {
$chkfails++;
}
if ( $chkfails ) {
print "The following files/directories are missing: \n\n";
}
else {
return;
}
if ( $target ) {
print " " . TARGET . "\n";
}
if ( $snapdir ) {
print " " . SNAPDIR . "\n";
}
if ( $pkgdir ) {
print " " . PKGDIR . "\n";
}
if ( $instdir ) {
print " " . INSTDIR . "\n";
}
if ( $srcdir ) {
print " " . SRCDIR . "\n";
}
print "\n";
print "Create files/directories? (y/n): ";
chkyes();
if ( $target ) {
mkdir( TARGET, 0755 ) || Snap->error( int( $! ), "mkdir: $!" );
}
@@ -621,6 +742,22 @@ sub setup {
}
}
### sha() ###############################################
#
# This sub returns a hex sha hash of a supplied file
#
############################################################
sub sha {
my $class = shift;
my $file = shift;
my $digest = eval {
Digest::SHA->new( 1 )->addfile( $file );
} || Snap->error( -1, "sha(): $file: $!\n" );
return( $digest->hexdigest );
}
### sha256() ###############################################
#
# This sub returns a hex sha256 hash of a supplied file
@@ -637,25 +774,109 @@ sub sha256 {
return( $digest->hexdigest );
}
sub termsize {
require 'sys/ioctl.ph';
my $data;
my $row;
my $col;
sub templates {
my $conf = shift;
my $templatedir = $conf->{'snapinstall'}{'templatedir'};
my $unsorted = [];
my $templates = {};
open( TTY, "+</dev/tty" ) || Snap->error( 0, "No tty: $!" );
opendir( my $dh, $templatedir ) ||
Snap->error( int( $! ), "templates(): $!" );
if ( ! ioctl( TTY, &TIOCGWINSZ, $data='' ) ) {
Snap->error( 0, "Failed to determine window size" );
while ( my $template = readdir( $dh ) ) {
if ( $template eq '.' || $template eq '..' ) {
next;
}
elsif ( ! -f "$templatedir/$template/packages" ) {
Snap->error( 0, "Template '$template' has"
. " no packages" );
next;
}
$templates->{$template}{'packages'} = [];
open( my $fh, "$templatedir/$template/packages" ) ||
Snap->error( int( $! ), "templates(): $!" );
while ( readline( $fh ) ) {
chomp();
if ( $_ =~ /^\s*#/ || $_ =~ /^$/ ) {
next;
}
push( @{$templates->{$template}{'packages'}}, $_ );
}
close( $fh );
}
close( TTY );
closedir( $dh );
( $row, $col ) = unpack( 'S4', $data );
foreach ( sort { $a cmp $b }( @$unsorted ) ) {
push( @$templates, $_ );
}
return( $templates );
}
sub termsize {
my $row = 24;
my $col = 80;
my $sel = IO::Select->new();
my $stdout;
my $stderr;
my $stat;
my $pid;
eval {
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
"stty size -F /dev/tty" );
} || return( { row => $row, col => $col } );
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( CHLDOUT );
close( CHLDERR );
waitpid( $pid, 0 );
$stat = $? >> 8;
if ( $stdout && $stdout =~ /(\d+)\s+(\d+)/ ) {
$row = $1;
$col = $2;
}
return( { row => $row, col => $col } );
}
sub unlock {
if ( -f LOCKFILE ) {
unlink( LOCKFILE ) || Snap->error( int( $! ), "unlink(): "
. LOCKFILE . ": Unable to remove lock file" );
}
}
### vercmp() ###############################################
#
# This subroutine was basically copied verbatim from the
@@ -732,4 +953,121 @@ sub vercmp {
@A <=> @B;
}
### virtfs() ###############################################
#
# Need to try and figure out a solution for user installs
#
# The user may not be able to mount the virt filesystems,
# so perhaps it could do some kind of linking instead?
#
# Also remember you might want to move chroot out of usher
# and into here! We could also try to do fakechroot as well
#
############################################################
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 ( ! -d $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

@@ -4,7 +4,6 @@ use strict;
use warnings;
use Compress::Zlib;
use Data::Dumper;
use parent 'Snap';

View File

@@ -4,18 +4,8 @@ use strict;
use warnings;
use Snap;
use Data::Dumper;
############################################################
#
# setup() will give the user the option to create the files
# and directories needed for snap to function
#
############################################################
setup();
my $command = shift( @ARGV );
my $command = shift( @ARGV ) || '';
my $conf = readconf();
my $commands = Snap::Commands->new();
my $sources = Snap::Sources->new( $conf->{'sources'} );
@@ -23,9 +13,15 @@ my $sources = Snap::Sources->new( $conf->{'sources'} );
if ( $ARGV[0] && $ARGV[0] eq '-h' ) {
$commands->commandhelp( $command );
}
elsif ( $command eq 'genpkg' ) {
elsif ( $command eq 'dump' ) {
print "\n";
foreach my $arg ( @ARGV ) {
genpkg( $arg );
my $package = Snap::Package->new( $arg );
$package->dump();
print "\n";
}
}
elsif ( $command eq 'files' ) {
@@ -51,29 +47,45 @@ elsif ( $command eq 'files' ) {
};
my $string = "@ARGV";
print "\n";
foreach my $arg ( @ARGV ) {
my $package = Snap::Package->new( $arg );
$package->files( $opts );
}
}
elsif ( $command eq 'genpkg' ) {
if ( ! @ARGV ) {
Snap->error( -1, "Failed to provide package name" );
}
print "\n";
foreach my $arg ( @ARGV ) {
genpkg( $arg );
}
}
elsif ( $command eq 'help' ) {
$commands->help();
}
elsif ( $command eq 'info' ) {
my $cnt = 0;
print "\n";
if ( ! @ARGV ) {
Snap->error( 0, "'$command': You must supply an argument" );
$commands->commandhelp( 'info' );
exit( -1 );
}
foreach my $arg ( @ARGV ) {
my $package = Snap::Package->new( $arg );
if ( $cnt ) {
print "\n";
}
$package->printself();
print "\n";
$cnt++;
}
}
elsif ( $command eq 'install' ) {
@@ -102,6 +114,9 @@ elsif ( $command eq 'install' ) {
my $string = "@ARGV";
my $packages = [];
my $bytes = 0;
my $virtfs = 0;
setup();
foreach my $attrib ( @attribs ) {
if ( $string =~ /$attrib\s*:\s*(\S+)/ ) {
@@ -111,8 +126,6 @@ elsif ( $command eq 'install' ) {
}
}
print "\n";
$sources->readpkgs();
####################################################
@@ -138,8 +151,8 @@ elsif ( $command eq 'install' ) {
my $package;
if ( ! -f $arg ) {
my ( $name, $version ) = split( /(((<|>)=?|=)(.*))/,
$arg );
my ( $name, $version ) =
split( /(((<|>)=?|=)(.*))/, $arg );
$opts->{'name'} = $name;
$opts->{'version'} = $version;
@@ -150,7 +163,7 @@ elsif ( $command eq 'install' ) {
}
if ( ! $package ) {
Snap->error( -1, "$arg: No such package found" );
exit( -1 );
}
if ( ! $opts->{'nodeps'} ) {
@@ -163,21 +176,10 @@ elsif ( $command eq 'install' ) {
print "Ignoring dependencies for $package->{'name'}\n";
}
push( @$packages, $package );
}
####################################################
#
# Here we iterate through all installed packages
# and add their file lists. This will later be
# checked against for conflicts.
#
####################################################
foreach my $pkgname ( sort { $sources->{'installed'}{$a}{'name'} cmp
$sources->{'installed'}{$b}{'name'} }
keys( %{$sources->{'installed'}} ) ) {
$sources->{'installed'}{$pkgname}->files( { quiet => 1 } );
if ( ! grep( $_->{'name'} eq $package->{'name'},
@$packages ) ) {
push( @$packages, $package );
}
}
for ( my $i = 0; $i <= $#$packages; $i++ ) {
@@ -291,36 +293,97 @@ 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";
if ( ! $opts->{'yes'} ) {
chkyes();
}
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
print "\n";
$package->install( $sources );
}
print "\n";
if ( $virtfs ) {
virtfs( 'umount' );
}
}
elsif ( $command eq 'list' ) {
my $packages = list();
my $opts = {
verbose => eval {
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
if ( $ARGV[$i] eq '-v' ) {
splice( @ARGV, $i, 1 );
print "\n";
return( 1 );
}
}
}
};
my $packages = list( \@ARGV );
foreach my $package ( sort( keys( %$packages ) ) ) {
$packages->{$package}->printbrief();
if ( $opts->{'verbose'} ) {
print "\n";
$packages->{$package}->printself();
}
else {
$packages->{$package}->printbrief();
}
}
print "\n";
if ( ! keys( %$packages ) ) {
print "No installed packages found matching '@ARGV'\n";
}
}
elsif ( $command eq 'provides' ) {
( my $string = $ARGV[0] ) =~ s/^\/*/\//;
my $len = length( $string );
$sources->readpkgs();
foreach my $pkgname ( sort( keys( %{$sources->{'installed'}} ) ) ) {
my $package = $sources->{'installed'}{$pkgname};
$package->files( { quiet => 1 } );
foreach my $file ( @{$package->{'files'}} ) {
if ( substr( "/$file", -$len, $len ) eq "$string" ) {
print "$pkgname\n";
last;
}
}
}
}
elsif ( $command eq 'purge' ) {
print "Not yet implemented\n";
exit( -1 );
}
elsif ( $command eq 'rebuild' ) {
print "Not yet implemented\n";
exit( -1 );
}
elsif ( $command eq 'refresh' ) {
print "\n";
setup();
$sources->refresh();
print "\n";
exit;
foreach my $source ( @{$conf->{'sources'}} ) {
@@ -331,6 +394,105 @@ elsif ( $command eq 'refresh' ) {
print "\n";
}
}
elsif ( $command eq 'reinstall' ) {
my $opts = {
quiet => 1,
yes => eval {
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
if ( $ARGV[$i] eq '-y' ) {
splice( @ARGV, $i, 1 );
return( 1 );
}
}
}
};
my $termsize = Snap->termsize();
my $packages = [];
my $virtfs = 0;
my $cnt = 0;
setup();
$sources->readpkgs();
foreach my $pkgname ( @ARGV ) {
my $package;
if ( -f $pkgname ) {
$package = Snap::Package->new( $pkgname );
}
else {
if ( ! $sources->{'installed'}{$pkgname} ) {
Snap->error( -1, "$pkgname not installed" );
}
$package = $sources->{'installed'}{$pkgname};
$package = $sources->search( {
name => $package->{'name'},
version => $package->{'version'},
quiet => 1
} );
}
if ( $package->{'path'} =~ /https*:\/\// ) {
( my $filename = $package->{'path'} ) =~ s/.*\///;
if ( ! -f Snap->PKGDIR . "/$filename" ) {
Snap->httpget( $package->{'path'},
Snap->PKGDIR . "/$filename", 0644 );
}
$package->{'path'} = Snap->PKGDIR . "/$filename";
}
$package->files( $opts );
if ( ! grep( $_->{'name'} eq $package->{'name'},
@$packages ) ) {
push( @$packages, $package );
}
}
foreach my $package ( sort { $a->{'name'} cmp $b->{'name'} }
( @$packages ) ) {
if ( ! $cnt ) {
print "The following packages will be"
. " reinstalled:\n ";
$cnt++;
}
if ( $termsize->{'col'} - ( length(
$package->{'name'} ) + 3 ) <= 0 ) {
print "\n ";
$termsize = Snap->termsize();
}
print "$package->{'name'} ";
$termsize->{'col'} -= length( $package->{'name'} ) + 1;
}
print "\n\nContinue? (y/n): ";
if ( ! $opts->{'yes'} ) {
chkyes();
}
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
print "\n";
$package->install( $sources );
}
virtfs( 'umount' );
}
elsif ( $command eq 'remove' ) {
my $opts = {
nodeps => eval {
@@ -358,8 +520,7 @@ elsif ( $command eq 'remove' ) {
my $bytes = 0;
my $cnt = 0;
my $termsize = Snap->termsize();
print "\n";
my $virtfs = 0;
$sources->readpkgs();
@@ -391,7 +552,13 @@ elsif ( $command eq 'remove' ) {
foreach my $package ( sort { $a->{'name'} cmp $b->{'name'} }
( @$packages ) ) {
if ( ! $cnt ) {
print "\nThe following packages will be removed:\n ";
print "\nThe following packages will be removed";
if ( Snap->TARGET ) {
print " from " . Snap->TARGET;
}
print ":\n ";
}
if ( $termsize->{'col'} - ( length(
@@ -412,21 +579,35 @@ elsif ( $command eq 'remove' ) {
print "\n\n" . human( $bytes ) . " will be recovered."
. " Continue? (y/n): ";
chkyes();
print "\n";
foreach my $package ( @$packages ) {
$package->remove( $sources );
if ( ! $opts->{'yes'} ) {
chkyes();
}
print "\n";
$cnt = 0;
foreach my $package ( @$packages ) {
if ( ! $virtfs ) {
$virtfs = virtfs( 'mount' );
}
if ( $cnt ) {
print "\n";
}
$package->remove( $sources );
$cnt++;
}
if ( $virtfs ) {
virtfs( 'umount' );
}
}
elsif ( $command eq 'revdep' ) {
my $revdeps = [];
print "\n";
$sources->readpkgs();
foreach my $arg ( @ARGV ) {
@@ -442,8 +623,6 @@ elsif ( $command eq 'revdep' ) {
if ( ! @$revdeps ) {
print "No reverse dependencies found\n";
}
print "\n";
}
elsif ( $command eq 'search' ) {
my @attribs = qw( name version depends source repo description );
@@ -488,62 +667,93 @@ elsif ( $command eq 'search' ) {
( $opts->{'string'} = $string ) =~ s/^ *| *$//g;
}
print "\n";
if ( ! $sources->readpkgs() ) {
exit -1;
exit( -1 );
}
if ( ! $sources->search( $opts ) ) {
exit -1;
exit( -1 );
}
print "\n";
}
elsif ( $command eq 'setup' ) {
elsif ( $command eq 'source' ) {
my $opts = {
repo => 'core',
latest => eval {
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
if ( $ARGV[$i] eq '-l' ) {
splice( @ARGV, $i, 1 );
return( 1 );
}
}
},
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 );
if ( ! @ARGV ) {
Snap->error( 0, "'$command': You must supply an argument" );
$commands->commandhelp( 'source' );
exit( -1 );
}
foreach my $arg ( @ARGV ) {
my $package;# = Snap::Package->new( $arg );
if ( $sources->{'installed'}{$arg} && ! $opts->{'latest'} ) {
$package = $sources->{'installed'}{$arg};
}
else {
my ( $name, $version ) =
split( /(((<|>)=?|=)(.*))/, $arg );
$opts->{'name'} = $name;
$opts->{'version'} = $version;
$package = $sources->search( $opts );
}
}
foreach my $package ( @$packages ) {
$package->install();
$package->source();
}
}
elsif ( $command eq 'upgrade' ) {
print "Not yet implemented\n";
print "\n";
exit( -1 );
}
elsif ( $command eq 'verify' ) {
my $opts = {
verbose => eval {
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
if ( $ARGV[$i] eq '-v' ) {
splice( @ARGV, $i, 1 );
return( 1 );
}
}
}
};
foreach my $arg ( @ARGV ) {
my $package = Snap::Package->new( $arg );
print Dumper( $package );
$package->verify( $opts );
}
}
elsif ( $command eq 'version' ) {
print Snap->VERSION . "\n";
}
elsif ( $command ) {
print "\n";
Snap->error( 0, "'$command': Invalid command" );
Snap->error( -1, "'$command': Invalid command" );
$commands->help();
exit( -1 );
}
else {
Snap->error( 0, "You must supply a command" );
$commands->help();
exit( -1 );
}

144
SRC/snap/snapinstall Executable file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/perl
use strict;
use warnings;
use Snap;
setup();
my $conf = readconf();
my $templates = templates( $conf );
my $sources = Snap::Sources->new( $conf->{'sources'} );
my @packages = ();
my $template;
if ( ! Snap->TARGET ) {
Snap->error( -1, 'A target must be specified with -t' );
}
$template = $ARGV[0];
$sources->readpkgs();
foreach my $pkgname ( @{$templates->{$template}{'packages'}} ) {
my $package = $sources->search( { name => $pkgname, quiet => 1 } );
if ( $package->{'status'} && $package->{'status'} eq 'installed' ) {
next;
}
if ( $package->{'path'} =~ /https*:\/\// ) {
( my $filename = $package->{'path'} ) =~ s/.*\///;
if ( -f "/var/lib/snap/packages/$filename" ) {
$package->{'path'} = "/var/lib/snap/packages/$filename";
}
elsif ( -f Snap->PKGDIR . "/$filename" ) {
$package->{'path'} = Snap->PKGDIR . "/$filename";
}
elsif ( ! -f Snap->PKGDIR . "/$filename" ) {
Snap->httpget( $package->{'path'},
Snap->PKGDIR . "/$filename", 0644 );
$package->{'path'} = Snap->PKGDIR . "/$filename";
}
else {
Snap->error( -1, "$package->{'name'}:"
. " Unable to determine package path" );
}
}
push( @packages, $package );
}
foreach my $package ( @packages ) {
$package->files( { quiet => 1 } );
print "\n";
$package->install();
}
if ( ! @packages ) {
print "Nothing to do\n";
}
else {
my $rootfs = "$conf->{'snapinstall'}{'templatedir'}/$template/rootfs";
my $postinst = "$conf->{'snapinstall'}{'templatedir'}"
. "/$template/postinst";
my $pid;
my $stat;
if ( ! Snap->dirempty( $rootfs ) ) {
if ( $pid = fork() ) {
waitpid( $pid, 0 );
$stat = $? >> 8;
}
else {
exec( "cp -a '$rootfs'/* " . Snap->TARGET );
}
if ( $stat ) {
Snap->error( $stat, "Failed to copy rootfs" );
}
}
print "Setting root password\n";
virtfs( 'mount' );
if ( $pid = fork() ) {
waitpid( $pid, 0 );
$stat = $? >> 8;
}
else {
if ( $> ) {
exec( "fakeroot fakechroot /usr/sbin/chroot "
. Snap->TARGET . " passwd root" );
}
else {
exec ( "chroot " . Snap->TARGET . " passwd root" );
}
}
virtfs( 'umount' );
if ( $stat ) {
Snap->error( $stat, "Failed to set password" );
}
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" );
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" );
}
}
}

View File

@@ -0,0 +1,57 @@
#
# These packages are the bare minimum necessary for a functional system.
# This file is required for snapinstall to function, so don't delete it!
#
snap-base
dash
texinfo
glibc
coreutils
libacl
libattr
libcap
ncurses
readline
tzdata
perl
binutils
bzip2
cpio
dhclient
e2fsprogs
ex
findutils
gawk
gdbm
gmp
grep
groff
gzip
iana-etc
iftools
inetutils
iproute2
kmod
less
libgcc
libpipeline
libstdc++
libzfs
linux-firmware
man-db
mpfr
net-tools
procps-ng
psmisc
sed
shadow
tar
snap
initscripts
sysklogd
sysvinit
tar
util-linux
xz
zlib

View File

@@ -0,0 +1,37 @@
# Default runlevel
id:3:initdefault:
# This is the set of scripts that prepare the system prior to entering runlevels
si::sysinit:/etc/init.d/rc S
# /etc/init.d/rc executes the S and K scripts when runlevel is changed
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevel 2 is multi-user without networking.
# Runlevel 3 is multi-user with networking.
# Runlevel 4 is not used by default.
# Runlevel 5 is multi-user with GUI.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# This allows ctrl-alt-del to reboot the system
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# Single user mode
su:S1:respawn:/sbin/sulogin
# The following spawns agetty on tty1-6
#
# Format:
# id:runlevels:action:process
#
# More information is available with 'man inittab'
1:2345:respawn:/sbin/agetty --noclear --nohints tty1 38400

View File

@@ -0,0 +1,7 @@
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
source-directory network.d

View File

@@ -0,0 +1,61 @@
#
# These packages are the bare minimum necessary for a functional system.
# This file is required for snapinstall to function, so don't delete it!
#
snap-base
dash
texinfo
glibc
coreutils
libacl
libattr
libcap
ncurses
readline
tzdata
perl
binutils
bzip2
cpio
dhclient
e2fsprogs
ex
findutils
gawk
gdbm
gmp
grep
groff
grub
gzip
iana-etc
iftools
inetutils
iproute2
kmod
less
libgcc
libpipeline
libstdc++
libzfs
linux-firmware
man-db
mkinitramfs
mpfr
net-tools
openssh-client
openssh-server
procps-ng
psmisc
sed
shadow
tar
snap
initscripts
sysklogd
sysvinit
tar
util-linux
xz
zlib

View File

@@ -0,0 +1,29 @@
#!/bin/sh
### PLACEHOLDER ###
# This script needs to provide things like network setup perhaps
# This code should help with setting up the network interfaces
#
#my $dir = '/sys/class/net';
#my $devs = {};
#
#opendir( my $dh, $dir ) || die( $! );
#
#while ( readdir( $dh ) ) {
# my $link = readlink( "$dir/$_" ) || next;
#
# if ( $link =~ /virtual/ ) {
# next;
# }
#
# open( my $fh, "$dir/$_/address" ) || die( $! );
# $devs->{$_}{'mac'} = <$fh>;
# close( $fh );
#
# chomp( $devs->{$_}{'mac'} );
# }
#
#foreach my $dev ( sort( keys( %$devs ) ) ) {
# print "$dev - $devs->{$dev}{'mac'}\n";
# }

View File

@@ -0,0 +1,8 @@
[sources]
default = http://packages.snaplinux.org/ core dev main server
[snapinstall]
templatedir = /etc/snap.d/templates
include /etc/snap.d