Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
915fb3e1f0 | ||
|
|
6b62f87bf6 | ||
|
|
d4baa191d6 | ||
|
|
98c0ab336f | ||
|
|
cdbf4ed7d5 | ||
|
|
bfa1d110c4 |
8
Makefile
8
Makefile
@@ -10,13 +10,17 @@
|
||||
|
||||
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.7-0
|
||||
VERSION := $(shell grep 'VERSION =>' SRC/snap/Snap.pm| \
|
||||
sed "s/.*=> '\|',//g")-$(SNAPVER)
|
||||
|
||||
include /usr/share/snap/Makefile.snaplinux
|
||||
|
||||
|
||||
@@ -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 => {
|
||||
@@ -227,15 +244,17 @@ 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]";
|
||||
}
|
||||
|
||||
if ( @$options ) {
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
@@ -248,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";
|
||||
|
||||
@@ -257,7 +276,7 @@ sub help {
|
||||
}
|
||||
|
||||
print "\nTo view more information for commands run:\n"
|
||||
. "snap <COMMAND> -h\n\n";
|
||||
. "snap <COMMAND> -h\n";
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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:
|
||||
@@ -18,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
|
||||
|
||||
@@ -8,9 +8,65 @@
|
||||
# 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 =
|
||||
REPO =
|
||||
BRIEF =
|
||||
DESC =
|
||||
SNAPVER =
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -8,17 +8,58 @@
|
||||
# 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
|
||||
|
||||
# This allows the package Makefile to override the name
|
||||
# of the package file. Added for the kernel package
|
||||
# though could be useful for others
|
||||
# This will set PACKAGE to the name of the current working directory
|
||||
# if the package itself has not provided a package name
|
||||
|
||||
ifndef SNAP
|
||||
SNAP := $(PACKAGE)-$(VERSION).snap
|
||||
ifndef PACKAGE
|
||||
PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
|
||||
endif
|
||||
|
||||
# If VERSION is not set then we must fail
|
||||
|
||||
ifndef VERSION
|
||||
$(error VERSION is not set)
|
||||
endif
|
||||
|
||||
# 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
|
||||
@@ -26,45 +67,48 @@ MANIFEST = $(SNAPDIR)/manifest
|
||||
USHER = $(SNAPDIR)/usher
|
||||
FILES = $(SNAPDIR)/files.tar.gz
|
||||
|
||||
# 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
|
||||
# BRIEF is required.
|
||||
|
||||
ifndef SRCPKG)
|
||||
SRCPKG := $(PACKAGE)
|
||||
ifndef BRIEF
|
||||
$(error BRIEF is not set)
|
||||
endif
|
||||
|
||||
# The following values must be set in the Makefile for the package
|
||||
|
||||
ifndef VERSION
|
||||
$(error VERSION is not set)
|
||||
endif
|
||||
|
||||
$(SNAP): $(SNAPINFO) $(FILES)
|
||||
@if [ -f $(SNAP) ]; then \
|
||||
rm -v $(SNAP); \
|
||||
$(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)
|
||||
@@ -106,10 +150,13 @@ $(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
|
||||
|
||||
@find $(ROOT) -type f | while read -r file; do \
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
298
SRC/snap/Snap.pm
298
SRC/snap/Snap.pm
@@ -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,6 +20,7 @@ our @EXPORT = qw(
|
||||
genpkg
|
||||
httpget
|
||||
human
|
||||
kernver
|
||||
list
|
||||
listfiles
|
||||
virtfs
|
||||
@@ -30,6 +30,7 @@ our @EXPORT = qw(
|
||||
sha
|
||||
sha256
|
||||
target
|
||||
templates
|
||||
termsize
|
||||
vercmp
|
||||
);
|
||||
@@ -89,7 +90,7 @@ use constant VERFILE => eval {
|
||||
}
|
||||
};
|
||||
use constant {
|
||||
VERSION => '0.7',
|
||||
VERSION => '0.13',
|
||||
SNAPDIR => TARGET . '/var/lib/snap',
|
||||
PKGDIR => TARGET . '/var/lib/snap/packages',
|
||||
INSTDIR => TARGET . '/var/lib/snap/installed',
|
||||
@@ -105,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" );
|
||||
}
|
||||
|
||||
############################################################
|
||||
#
|
||||
@@ -121,7 +133,9 @@ $0 =~ s/.*\///;
|
||||
############################################################
|
||||
|
||||
$SIG{INT} = sub{
|
||||
if ( TARGET ) {
|
||||
virtfs( 'umount' );
|
||||
}
|
||||
|
||||
print "\e[?25h\n";
|
||||
|
||||
@@ -170,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': ";
|
||||
@@ -182,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
|
||||
@@ -234,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"
|
||||
@@ -293,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;
|
||||
|
||||
@@ -314,7 +360,7 @@ sub httpget {
|
||||
|
||||
while ( <$sock> ) {
|
||||
if ( $dest ) {
|
||||
$bytes = ( stat( $dest ) )[7] || 0;
|
||||
$bytes += length( $_ );
|
||||
}
|
||||
|
||||
if ( ! $httpget{'dflag'} ) {
|
||||
@@ -365,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 '*';
|
||||
if ( $p >= $#wheel ) {
|
||||
$p = 0;
|
||||
}
|
||||
else {
|
||||
print ' ';
|
||||
$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 );
|
||||
}
|
||||
@@ -433,7 +480,50 @@ sub ismountpoint {
|
||||
}
|
||||
}
|
||||
|
||||
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 = {};
|
||||
|
||||
@@ -441,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;
|
||||
}
|
||||
|
||||
@@ -499,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;
|
||||
@@ -515,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*(.*)$/ ) {
|
||||
@@ -553,7 +674,7 @@ sub readconf {
|
||||
}
|
||||
}
|
||||
|
||||
close( FILE );
|
||||
close( $fh );
|
||||
|
||||
return( $data );
|
||||
}
|
||||
@@ -596,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: $!" );
|
||||
}
|
||||
@@ -650,7 +742,14 @@ 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 );
|
||||
@@ -675,6 +774,53 @@ sub sha256 {
|
||||
return( $digest->hexdigest );
|
||||
}
|
||||
|
||||
sub templates {
|
||||
my $conf = shift;
|
||||
my $templatedir = $conf->{'snapinstall'}{'templatedir'};
|
||||
my $unsorted = [];
|
||||
my $templates = {};
|
||||
|
||||
opendir( my $dh, $templatedir ) ||
|
||||
Snap->error( int( $! ), "templates(): $!" );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
closedir( $dh );
|
||||
|
||||
foreach ( sort { $a cmp $b }( @$unsorted ) ) {
|
||||
push( @$templates, $_ );
|
||||
}
|
||||
|
||||
return( $templates );
|
||||
}
|
||||
|
||||
sub termsize {
|
||||
my $row = 24;
|
||||
my $col = 80;
|
||||
@@ -716,7 +862,7 @@ sub termsize {
|
||||
waitpid( $pid, 0 );
|
||||
$stat = $? >> 8;
|
||||
|
||||
if ( $stdout =~ /(\d+)\s+(\d+)/ ) {
|
||||
if ( $stdout && $stdout =~ /(\d+)\s+(\d+)/ ) {
|
||||
$row = $1;
|
||||
$col = $2;
|
||||
}
|
||||
@@ -724,6 +870,13 @@ sub termsize {
|
||||
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
|
||||
@@ -800,6 +953,18 @@ 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 = {
|
||||
@@ -820,7 +985,7 @@ sub virtfs {
|
||||
}
|
||||
};
|
||||
|
||||
if ( ! TARGET ) {
|
||||
if ( $> || ! TARGET ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -832,7 +997,8 @@ sub virtfs {
|
||||
my $stat = 0;
|
||||
my $pid;
|
||||
|
||||
if ( ! -f $virtfs->{$fs}{'dir'} ) {
|
||||
|
||||
if ( ! -d $virtfs->{$fs}{'dir'} ) {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Compress::Zlib;
|
||||
use Data::Dumper;
|
||||
|
||||
use parent 'Snap';
|
||||
|
||||
|
||||
286
SRC/snap/snap
286
SRC/snap/snap
@@ -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' ) {
|
||||
@@ -104,6 +116,8 @@ elsif ( $command eq 'install' ) {
|
||||
my $bytes = 0;
|
||||
my $virtfs = 0;
|
||||
|
||||
setup();
|
||||
|
||||
foreach my $attrib ( @attribs ) {
|
||||
if ( $string =~ /$attrib\s*:\s*(\S+)/ ) {
|
||||
$opts->{$attrib} = $1;
|
||||
@@ -112,8 +126,6 @@ elsif ( $command eq 'install' ) {
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
|
||||
$sources->readpkgs();
|
||||
|
||||
####################################################
|
||||
@@ -139,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;
|
||||
|
||||
@@ -151,7 +163,7 @@ elsif ( $command eq 'install' ) {
|
||||
}
|
||||
|
||||
if ( ! $package ) {
|
||||
Snap->error( -1, "$arg: No such package found" );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if ( ! $opts->{'nodeps'} ) {
|
||||
@@ -164,21 +176,10 @@ elsif ( $command eq 'install' ) {
|
||||
print "Ignoring dependencies for $package->{'name'}\n";
|
||||
}
|
||||
|
||||
if ( ! grep( $_->{'name'} eq $package->{'name'},
|
||||
@$packages ) ) {
|
||||
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 } );
|
||||
}
|
||||
|
||||
for ( my $i = 0; $i <= $#$packages; $i++ ) {
|
||||
@@ -301,7 +302,9 @@ elsif ( $command eq 'install' ) {
|
||||
. ". Continue? (y/n): ";
|
||||
}
|
||||
|
||||
if ( ! $opts->{'yes'} ) {
|
||||
chkyes();
|
||||
}
|
||||
|
||||
foreach my $package ( @$packages ) {
|
||||
if ( ! $virtfs ) {
|
||||
@@ -316,26 +319,71 @@ elsif ( $command eq 'install' ) {
|
||||
if ( $virtfs ) {
|
||||
virtfs( 'umount' );
|
||||
}
|
||||
|
||||
print "\n";
|
||||
}
|
||||
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 ) ) ) {
|
||||
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'}} ) {
|
||||
@@ -348,6 +396,7 @@ elsif ( $command eq 'refresh' ) {
|
||||
}
|
||||
elsif ( $command eq 'reinstall' ) {
|
||||
my $opts = {
|
||||
quiet => 1,
|
||||
yes => eval {
|
||||
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
|
||||
if ( $ARGV[$i] eq '-y' ) {
|
||||
@@ -358,13 +407,15 @@ elsif ( $command eq 'reinstall' ) {
|
||||
}
|
||||
}
|
||||
};
|
||||
my $termsize = Snap->termsize();
|
||||
my $packages = [];
|
||||
my $virtfs = 0;
|
||||
my $cnt = 0;
|
||||
|
||||
setup();
|
||||
|
||||
$sources->readpkgs();
|
||||
|
||||
print "\n";
|
||||
|
||||
foreach my $pkgname ( @ARGV ) {
|
||||
my $package;
|
||||
|
||||
@@ -372,6 +423,10 @@ elsif ( $command eq 'reinstall' ) {
|
||||
$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'},
|
||||
@@ -380,12 +435,6 @@ elsif ( $command eq 'reinstall' ) {
|
||||
} );
|
||||
}
|
||||
|
||||
if ( ! $package ) {
|
||||
print STDERR "Package '$pkgname' not installed\n";
|
||||
|
||||
next;
|
||||
}
|
||||
|
||||
if ( $package->{'path'} =~ /https*:\/\// ) {
|
||||
( my $filename = $package->{'path'} ) =~ s/.*\///;
|
||||
|
||||
@@ -397,18 +446,21 @@ elsif ( $command eq 'reinstall' ) {
|
||||
$package->{'path'} = Snap->PKGDIR . "/$filename";
|
||||
}
|
||||
|
||||
$package->files( $opts );
|
||||
|
||||
if ( ! grep( $_->{'name'} eq $package->{'name'},
|
||||
@$packages ) ) {
|
||||
push( @$packages, $package );
|
||||
}
|
||||
|
||||
foreach my $package ( @$packages ) {
|
||||
my $termsize = Snap->termsize();
|
||||
my $cnt = 0;
|
||||
}
|
||||
|
||||
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(
|
||||
@@ -421,13 +473,13 @@ elsif ( $command eq 'reinstall' ) {
|
||||
print "$package->{'name'} ";
|
||||
|
||||
$termsize->{'col'} -= length( $package->{'name'} ) + 1;
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
print "\n\nContinue? (y/n): ";
|
||||
|
||||
if ( ! $opts->{'yes'} ) {
|
||||
chkyes();
|
||||
}
|
||||
|
||||
foreach my $package ( @$packages ) {
|
||||
if ( ! $virtfs ) {
|
||||
@@ -436,12 +488,10 @@ elsif ( $command eq 'reinstall' ) {
|
||||
|
||||
print "\n";
|
||||
|
||||
$package->install();
|
||||
$package->install( $sources );
|
||||
}
|
||||
|
||||
virtfs( 'umount' );
|
||||
|
||||
print "\n";
|
||||
}
|
||||
elsif ( $command eq 'remove' ) {
|
||||
my $opts = {
|
||||
@@ -470,8 +520,7 @@ elsif ( $command eq 'remove' ) {
|
||||
my $bytes = 0;
|
||||
my $cnt = 0;
|
||||
my $termsize = Snap->termsize();
|
||||
|
||||
print "\n";
|
||||
my $virtfs = 0;
|
||||
|
||||
$sources->readpkgs();
|
||||
|
||||
@@ -503,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(
|
||||
@@ -524,21 +579,35 @@ elsif ( $command eq 'remove' ) {
|
||||
print "\n\n" . human( $bytes ) . " will be recovered."
|
||||
. " Continue? (y/n): ";
|
||||
|
||||
if ( ! $opts->{'yes'} ) {
|
||||
chkyes();
|
||||
|
||||
print "\n";
|
||||
|
||||
foreach my $package ( @$packages ) {
|
||||
$package->remove( $sources );
|
||||
}
|
||||
|
||||
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 ) {
|
||||
@@ -554,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 );
|
||||
@@ -600,36 +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 );
|
||||
}
|
||||
}
|
||||
elsif ( $command eq 'source' ) {
|
||||
my $opts = {
|
||||
latest => eval {
|
||||
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
|
||||
if ( $ARGV[$i] eq '-l' ) {
|
||||
splice( @ARGV, $i, 1 );
|
||||
|
||||
return( 1 );
|
||||
}
|
||||
}
|
||||
},
|
||||
quiet => 1
|
||||
};
|
||||
$sources->readpkgs();
|
||||
|
||||
if ( ! @ARGV ) {
|
||||
Snap->error( 0, "'$command': You must supply an argument" );
|
||||
|
||||
$commands->commandhelp( 'source' );
|
||||
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
print "\n";
|
||||
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 );
|
||||
}
|
||||
|
||||
$package->source();
|
||||
}
|
||||
}
|
||||
elsif ( $command eq 'upgrade' ) {
|
||||
print "Not yet implemented\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 "\n" . Snap->VERSION . "\n\n";
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -4,86 +4,141 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Snap;
|
||||
use Data::Dumper;
|
||||
|
||||
setup();
|
||||
|
||||
my $conf = readconf();
|
||||
my $templates = templates( $conf );
|
||||
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";
|
||||
my @packages = ();
|
||||
my $template;
|
||||
|
||||
if ( ! Snap->TARGET ) {
|
||||
Snap->error( -1, 'A target must be specified with -t' );
|
||||
}
|
||||
|
||||
$template = $ARGV[0];
|
||||
$sources->readpkgs();
|
||||
$corepkgs = $sources->search( $opts );
|
||||
|
||||
for ( my $i = 0; $i <= $#$corepkgs; $i++ ) {
|
||||
if ( ! $opts->{'nodeps'} ) {
|
||||
print "Resolving dependencies for"
|
||||
. " $corepkgs->[$i]{'name'}\n";
|
||||
foreach my $pkgname ( @{$templates->{$template}{'packages'}} ) {
|
||||
my $package = $sources->search( { name => $pkgname, quiet => 1 } );
|
||||
|
||||
$corepkgs->[$i]->depends( $sources, $packages );
|
||||
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 {
|
||||
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--;
|
||||
Snap->error( -1, "$package->{'name'}:"
|
||||
. " Unable to determine package path" );
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $package ( @$prelist ) {
|
||||
print "\n";
|
||||
|
||||
$prepkgs->{$package}->install();
|
||||
push( @packages, $package );
|
||||
}
|
||||
|
||||
foreach my $package ( @$packages ) {
|
||||
if ( ! $virtfs ) {
|
||||
$virtfs = virtfs( 'mount' );
|
||||
}
|
||||
foreach my $package ( @packages ) {
|
||||
$package->files( { quiet => 1 } );
|
||||
|
||||
print "\n";
|
||||
|
||||
$package->install();
|
||||
}
|
||||
|
||||
virtfs( 'umount' );
|
||||
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;
|
||||
|
||||
print "\n";
|
||||
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" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
SRC/snap/templates/container/packages
Normal file
57
SRC/snap/templates/container/packages
Normal 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
|
||||
37
SRC/snap/templates/container/rootfs/etc/inittab
Normal file
37
SRC/snap/templates/container/rootfs/etc/inittab
Normal 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
|
||||
7
SRC/snap/templates/container/rootfs/etc/network.conf
Executable file
7
SRC/snap/templates/container/rootfs/etc/network.conf
Executable file
@@ -0,0 +1,7 @@
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
|
||||
source-directory network.d
|
||||
61
SRC/snap/templates/server/packages
Normal file
61
SRC/snap/templates/server/packages
Normal 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
|
||||
29
SRC/snap/templates/server/postinst
Normal file
29
SRC/snap/templates/server/postinst
Normal 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";
|
||||
# }
|
||||
8
SRC/snap/templates/server/rootfs/etc/snap.conf
Normal file
8
SRC/snap/templates/server/rootfs/etc/snap.conf
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user