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!)
This commit is contained in:
4
Makefile
4
Makefile
@@ -10,7 +10,9 @@
|
|||||||
|
|
||||||
DEPENDS = binutils,coreutils,gzip,perl>=5.20.0,tar
|
DEPENDS = binutils,coreutils,gzip,perl>=5.20.0,tar
|
||||||
ARCH = x86_64
|
ARCH = x86_64
|
||||||
URL =
|
URL = http://snaplinux.org
|
||||||
|
REPO = core
|
||||||
|
BRIEF = The Snaplinux package management system
|
||||||
DESC = The Snaplinux package management system
|
DESC = The Snaplinux package management system
|
||||||
SNAPVER = 0
|
SNAPVER = 0
|
||||||
|
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ my $commands = {
|
|||||||
],
|
],
|
||||||
brief => 'List package info',
|
brief => 'List package info',
|
||||||
help => [
|
help => [
|
||||||
"\t\tPKGNAME or FILE is required."
|
"\t\tOne or more PKGNAME or FILE is required.\n"
|
||||||
. " A version string\n\t\t\t\tcan optionally"
|
. "\t\t\t\tA version string can optionally"
|
||||||
. " be provided with the PKGNAME\n"
|
. " be provided\n\t\t\t\twith PKGNAME"
|
||||||
. "\t\t\t\tas packagename=x.x.x\n",
|
. " as packagename=x.x.x\n",
|
||||||
"\t\t\tAn optional target may be specified"
|
"\t\t\tAn optional target may be specified"
|
||||||
. " to\n\t\t\t\tquery a separate directory"
|
. " to\n\t\t\t\tquery a separate directory"
|
||||||
. "/file system"
|
. "/file system"
|
||||||
@@ -150,6 +150,17 @@ my $commands = {
|
|||||||
"\t\t\t\tProceed without prompting"
|
"\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 => {
|
search => {
|
||||||
options => [
|
options => [
|
||||||
'[STRING[=VER]]',
|
'[STRING[=VER]]',
|
||||||
@@ -167,14 +178,16 @@ my $commands = {
|
|||||||
},
|
},
|
||||||
source => {
|
source => {
|
||||||
options => [
|
options => [
|
||||||
'<PKGNAME[=VER]>'
|
'<PKGNAME[=VER]>',
|
||||||
|
'[-l]'
|
||||||
],
|
],
|
||||||
brief => 'Retrieve package source',
|
brief => 'Retrieve package source',
|
||||||
help => [
|
help => [
|
||||||
"\t\tPKGNAME is required."
|
"\t\tPKGNAME is required."
|
||||||
. " A version string\n\t\t\t\tcan optionally"
|
. " A version string\n\t\t\t\tcan optionally"
|
||||||
. " be provided with the PKGNAME\n"
|
. " 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 => {
|
upgrade => {
|
||||||
@@ -227,14 +240,12 @@ sub commandhelp {
|
|||||||
my $options = $commands->{$command}{'options'};
|
my $options = $commands->{$command}{'options'};
|
||||||
my $help = $commands->{$command}{'help'};
|
my $help = $commands->{$command}{'help'};
|
||||||
|
|
||||||
print "\nsnap $command @{$commands->{$command}{'options'}}\n\n";
|
print "snap $command @{$commands->{$command}{'options'}}\n\n";
|
||||||
print "$commands->{$command}{'brief'}\n\n";
|
print "$commands->{$command}{'brief'}\n\n";
|
||||||
|
|
||||||
for ( my $i = 0; $i <= $#{$options}; $i++ ) {
|
for ( my $i = 0; $i <= $#{$options}; $i++ ) {
|
||||||
print " $options->[$i]$help->[$i]\n";
|
print " $options->[$i]$help->[$i]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
print "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
@@ -248,7 +259,7 @@ sub help {
|
|||||||
Snap->error( -1, "usage(): Invalid option '$ARGV[0]'" );
|
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"
|
. "snap is the Snaplinux package management utility\n\n"
|
||||||
. "COMMANDS\n\n";
|
. "COMMANDS\n\n";
|
||||||
|
|
||||||
@@ -257,7 +268,7 @@ sub help {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print "\nTo view more information for commands run:\n"
|
print "\nTo view more information for commands run:\n"
|
||||||
. "snap <COMMAND> -h\n\n";
|
. "snap <COMMAND> -h\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
dirs:
|
dirs:
|
||||||
install -d -v -m 755 $(DESTDIR)/etc
|
install -d -v -m 755 $(DESTDIR)/etc/snap.d
|
||||||
install -d -v -m 755 $(DESTDIR)/usr/{bin,share/snap}
|
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
|
install -d -v -m 755 $(DESTDIR)/usr/lib/perl5/vendor_perl/5.24.0/Snap
|
||||||
|
|
||||||
files:
|
files:
|
||||||
|
install -v -m 644 core.spt $(DESTDIR)/etc/snap.d/core.spt
|
||||||
install -v -m 755 snap $(DESTDIR)/usr/bin/snap
|
install -v -m 755 snap $(DESTDIR)/usr/bin/snap
|
||||||
install -v -m 755 snapinstall $(DESTDIR)/usr/bin/snapinstall
|
install -v -m 755 snapinstall $(DESTDIR)/usr/bin/snapinstall
|
||||||
install -v -m 644 Makefile.skel \
|
install -v -m 644 Makefile.skel \
|
||||||
|
|||||||
@@ -8,9 +8,65 @@
|
|||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# 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 =
|
ARCH =
|
||||||
|
DEPENDS =
|
||||||
|
BUILDDEPS =
|
||||||
|
SRCPKG =
|
||||||
URL =
|
URL =
|
||||||
|
REPO =
|
||||||
BRIEF =
|
BRIEF =
|
||||||
DESC =
|
DESC =
|
||||||
SNAPVER =
|
SNAPVER =
|
||||||
@@ -50,6 +106,11 @@ $(SRCDIR)/config.log: $(SRCDIR)/configure
|
|||||||
--host=x86_64-snap-linux-gnu \
|
--host=x86_64-snap-linux-gnu \
|
||||||
--target=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
|
$(SRCDIR)/binfile: $(SRCDIR)/config.log
|
||||||
@cd $(SRCDIR) && make
|
@cd $(SRCDIR) && make
|
||||||
|
|
||||||
|
|||||||
@@ -8,42 +8,69 @@
|
|||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
export SHELL := /bin/bash
|
||||||
|
|
||||||
PWD := $(shell pwd)
|
PWD := $(shell pwd)
|
||||||
SNAPDIR = $(PWD)/SNAP
|
SNAPDIR = $(PWD)/SNAP
|
||||||
ROOT = $(PWD)/ROOT
|
ROOT = $(PWD)/ROOT
|
||||||
|
|
||||||
# This will set PACKAGE only if the package itself has
|
# This will set PACKAGE to the name of the current working directory
|
||||||
# not provided a package name
|
# if the package itself has not provided a package name
|
||||||
|
|
||||||
ifndef PACKAGE
|
ifndef PACKAGE
|
||||||
PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
|
PACKAGE := $(shell echo $(PWD)|sed 's/.*\///')
|
||||||
endif
|
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
|
# This defines the name of the package file unless
|
||||||
# specified
|
# it is already specified in the package Makefile
|
||||||
|
|
||||||
ifndef PKGFILE
|
ifndef PKGFILE
|
||||||
PKGFILE := $(PACKAGE)-$(VERSION).snap
|
PKGFILE := $(PACKAGE)-$(VERSION).snap
|
||||||
endif
|
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
|
SNAPINFO = $(SNAPDIR)/snapinfo
|
||||||
MANIFEST = $(SNAPDIR)/manifest
|
MANIFEST = $(SNAPDIR)/manifest
|
||||||
USHER = $(SNAPDIR)/usher
|
USHER = $(SNAPDIR)/usher
|
||||||
FILES = $(SNAPDIR)/files.tar.gz
|
FILES = $(SNAPDIR)/files.tar.gz
|
||||||
|
|
||||||
# If multiple packages are pulled from a single source
|
# BRIEF is required.
|
||||||
# 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
|
|
||||||
|
|
||||||
ifndef SRCPKG
|
ifndef BRIEF
|
||||||
SRCPKG := $(PACKAGE)
|
$(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
|
endif
|
||||||
|
|
||||||
$(PKGFILE): $(SNAPINFO) $(FILES)
|
$(PKGFILE): $(SNAPINFO) $(FILES)
|
||||||
@@ -65,11 +92,23 @@ $(SNAPINFO): $(MANIFEST)
|
|||||||
$(eval BYTES := $(shell gzip -l $(FILES)|tail -1|awk '{print $$2}'))
|
$(eval BYTES := $(shell gzip -l $(FILES)|tail -1|awk '{print $$2}'))
|
||||||
$(eval SHA256MAN := $(shell sha256sum $(MANIFEST)|awk '{print $$1}'))
|
$(eval SHA256MAN := $(shell sha256sum $(MANIFEST)|awk '{print $$1}'))
|
||||||
|
|
||||||
@printf "name: $(PACKAGE)\nversion: $(VERSION)\n" > $(SNAPINFO) && \
|
@fields=( \
|
||||||
printf "depends: $(DEPENDS)\narch: $(ARCH)\n" >> $(SNAPINFO) && \
|
"name: $(PACKAGE)" \
|
||||||
printf "srcpkg: $(SRCPKG)\nbytes: $(BYTES)\n" >> $(SNAPINFO) && \
|
"version: $(VERSION)" \
|
||||||
printf "url: $(URL)\nsha256man: $(SHA256MAN)\n" >> $(SNAPINFO) && \
|
"arch: $(ARCH)" \
|
||||||
printf "brief: $(BRIEF)\ndescription: $(DESC)" >> $(SNAPINFO)
|
"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): $(FILES)
|
||||||
@>$(MANIFEST)
|
@>$(MANIFEST)
|
||||||
@@ -111,10 +150,13 @@ $(FILES): $(ROOT)
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
@if [ -d $(ROOT)/usr/share/info ]; then \
|
@if [ -d $(ROOT)/usr/share/info ]; then \
|
||||||
find $(ROOT)/usr/share/info -type f -name \*.info| \
|
find $(ROOT)/usr/share/info -name '*.info' -o \
|
||||||
while read -r file; do \
|
-name '*.info-[0-9]*'|while read -r file; do \
|
||||||
gzip $$file; \
|
gzip $$file; \
|
||||||
done; \
|
done; \
|
||||||
|
if [ -f $(ROOT)/usr/share/info/dir ]; then \
|
||||||
|
rm -v $(ROOT)/usr/share/info/dir; \
|
||||||
|
fi; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@find $(ROOT) -type f | while read -r file; do \
|
@find $(ROOT) -type f | while read -r file; do \
|
||||||
|
|||||||
@@ -11,72 +11,82 @@ use Data::Dumper;
|
|||||||
|
|
||||||
use parent 'Snap';
|
use parent 'Snap';
|
||||||
|
|
||||||
### new() ##################################################
|
############################################################
|
||||||
#
|
#
|
||||||
# This creates a new package object. The attributes are:
|
# The FIELDS constant defines all available attributes for
|
||||||
|
# package files. The following is a brief description of
|
||||||
|
# each:
|
||||||
#
|
#
|
||||||
# * arch: The architecture for which the package is built
|
# * arch: The architecture for which the package is built
|
||||||
# * brief: short desription of package
|
# * brief: short desription of package
|
||||||
|
# * builddeps: dependencies for building the package
|
||||||
# * bytes: total bytes of installed package
|
# * bytes: total bytes of installed package
|
||||||
# * depends: comma separated list of package dependencies
|
# * depends: comma separated list of package dependencies
|
||||||
# * description: long description of package
|
# * description: long description of package
|
||||||
# * name: package name
|
# * name: package name
|
||||||
# * path: path to package, either local or repo file
|
# * path: path to package, either local or repo file
|
||||||
# * source: source server
|
|
||||||
# * repo: repository where package is located, empty for
|
# * repo: repository where package is located, empty for
|
||||||
# local file
|
# local file
|
||||||
# * sha256: sha256sum for package file
|
# * sha256: sha256sum for package file
|
||||||
# * sha256man: sha256sum for package manifest file
|
# * sha256man: sha256sum for package manifest file
|
||||||
# * status: The current status of the package, one of:
|
# * source: source server
|
||||||
|
# * srcpkg: name of git repo for package source
|
||||||
|
# * status: status of package currently one of:
|
||||||
# installed
|
# installed
|
||||||
# installing
|
# installing
|
||||||
# removing
|
# removing
|
||||||
# uninstalled
|
# uninstalled
|
||||||
# upgrading
|
# upgrading
|
||||||
|
# * status: The current status of the package, one of:
|
||||||
# * url: upstream source url
|
# * url: upstream source url
|
||||||
# * version: version string
|
# * version: version string
|
||||||
#
|
#
|
||||||
############################################################
|
############################################################
|
||||||
|
|
||||||
|
use constant FIELDS => qw(
|
||||||
|
name
|
||||||
|
version
|
||||||
|
arch
|
||||||
|
depends
|
||||||
|
builddeps
|
||||||
|
srcpkg
|
||||||
|
status
|
||||||
|
bytes
|
||||||
|
url
|
||||||
|
path
|
||||||
|
source
|
||||||
|
repo
|
||||||
|
sha256
|
||||||
|
sha256man
|
||||||
|
brief
|
||||||
|
description
|
||||||
|
);
|
||||||
|
|
||||||
|
### new() ##################################################
|
||||||
|
#
|
||||||
|
# This creates a new package object. The attributes are
|
||||||
|
# defined in the FIELDS constant.
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
my $package = shift;
|
my $package = shift;
|
||||||
my $infofile = Snap->INSTDIR . "/$package/snapinfo";
|
my $infofile = Snap->INSTDIR . "/$package/snapinfo";
|
||||||
my $self = {
|
my $self = {};
|
||||||
arch => '',
|
|
||||||
brief => '',
|
|
||||||
bytes => 0,
|
|
||||||
depends => '',
|
|
||||||
srcpkg => '',
|
|
||||||
description => '',
|
|
||||||
name => '',
|
|
||||||
source => '',
|
|
||||||
path => '',
|
|
||||||
repo => '',
|
|
||||||
sha256 => '',
|
|
||||||
sha256man => '',
|
|
||||||
status => '',
|
|
||||||
url => '',
|
|
||||||
version => ''
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( ref( $package ) ) {
|
if ( ref( $package ) ) {
|
||||||
foreach my $attr ( keys( %$self ) ) {
|
foreach my $attr ( FIELDS ) {
|
||||||
$self->{$attr} = $package->{$attr};
|
$self->{$attr} = $package->{$attr};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( -f $package ) {
|
elsif ( -f $package && Snap->issnap( $package ) ) {
|
||||||
my $sel = IO::Select->new();
|
my $sel = IO::Select->new();
|
||||||
my $stdout;
|
my $stdout;
|
||||||
my $stderr;
|
my $stderr;
|
||||||
my $stat;
|
my $stat;
|
||||||
my $pid;
|
my $pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
|
||||||
|
|
||||||
eval {
|
|
||||||
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
|
|
||||||
"/usr/bin/ar p $package snapinfo" );
|
"/usr/bin/ar p $package snapinfo" );
|
||||||
} || Snap->error( int( $! ), "open3(): /usr/bin/ar:"
|
|
||||||
. " $!" );
|
|
||||||
|
|
||||||
close( CHLDIN );
|
close( CHLDIN );
|
||||||
|
|
||||||
@@ -106,10 +116,8 @@ sub new {
|
|||||||
$stat = $? >> 8;
|
$stat = $? >> 8;
|
||||||
|
|
||||||
if ( $stat ) {
|
if ( $stat ) {
|
||||||
$stderr =~ s/.*: //;
|
Snap->error( $stat,
|
||||||
|
"Failed to read $package: $stderr" );
|
||||||
Snap->error( $stat, "Failed reading '$package':"
|
|
||||||
. " $stderr" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ( split( /\n/, $stdout ) ) {
|
foreach ( split( /\n/, $stdout ) ) {
|
||||||
@@ -150,6 +158,10 @@ sub new {
|
|||||||
Snap->error( -2, "'$package': No such file or package found" );
|
Snap->error( -2, "'$package': No such file or package found" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! $self->{'srcpkg'} ) {
|
||||||
|
$self->{'srcpkg'} = $self->{'name'};
|
||||||
|
}
|
||||||
|
|
||||||
return( bless( $self, $class ) );
|
return( bless( $self, $class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,6 +495,87 @@ sub files {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
#
|
||||||
|
# This just generates the dir directory file for info docs
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
sub infodir {
|
||||||
|
my $self = shift;
|
||||||
|
my $infodir = Snap->TARGET . '/usr/share/info';
|
||||||
|
my $infofiles = [];
|
||||||
|
|
||||||
|
if ( ! @{$self->{'files'}} ) {
|
||||||
|
return();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $file ( sort( @{$self->{'files'}} ) ) {
|
||||||
|
if ( $file !~ /usr\/share\/info\/.*\.info*/ ||
|
||||||
|
! -f Snap->TARGET . "/$file" ) {
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
push( @$infofiles, Snap->TARGET . "/$file" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( @$infofiles == 0 ) {
|
||||||
|
return();
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Updating " . @$infofiles . " info/dir entries\n";
|
||||||
|
|
||||||
|
print "\e[?25l\r";
|
||||||
|
|
||||||
|
foreach my $file ( @$infofiles ) {
|
||||||
|
my $sel = IO::Select->new();
|
||||||
|
my $stdout;
|
||||||
|
my $stderr;
|
||||||
|
my $stat;
|
||||||
|
my $pid;
|
||||||
|
|
||||||
|
print "\e[K$file\r";
|
||||||
|
|
||||||
|
eval {
|
||||||
|
$pid = open3( \*CHLDIN, \*CHLDOUT, \*CHLDERR,
|
||||||
|
"install-info $file $infodir/dir" );
|
||||||
|
} || Snap->error( 0, 'install-info failed' );
|
||||||
|
|
||||||
|
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 ( $? ) {
|
||||||
|
Snap->error( 0, "install-info: $file: $stderr" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print "\e[Kdone\e[?25h\r";
|
||||||
|
}
|
||||||
|
|
||||||
sub install {
|
sub install {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $sources = shift;
|
my $sources = shift;
|
||||||
@@ -498,6 +591,17 @@ sub install {
|
|||||||
my $stat;
|
my $stat;
|
||||||
local $| = 1;
|
local $| = 1;
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
#
|
||||||
|
# This should attempt to get an exclusive lock on
|
||||||
|
# a temporary lock file. If it fails lock() will
|
||||||
|
# assume this means that a snap process is already
|
||||||
|
# running and die.
|
||||||
|
#
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
Snap->lock();
|
||||||
|
|
||||||
$ENV{'VERSION'} = $self->{'version'};
|
$ENV{'VERSION'} = $self->{'version'};
|
||||||
|
|
||||||
if ( ! -f $self->{'path'} ) {
|
if ( ! -f $self->{'path'} ) {
|
||||||
@@ -515,7 +619,7 @@ sub install {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( ! -d $pkgdir ) {
|
if ( ! -d $pkgdir ) {
|
||||||
mkdir( $pkgdir, 0644 ) ||
|
mkdir( $pkgdir, 0755 ) ||
|
||||||
Snap->error( int( $! ), "mkdir(): $pkgdir: $!" );
|
Snap->error( int( $! ), "mkdir(): $pkgdir: $!" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,6 +760,10 @@ sub install {
|
|||||||
Snap->error( int( $! ), "unlink(): $manifest: $!" );
|
Snap->error( int( $! ), "unlink(): $manifest: $!" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$self->infodir();
|
||||||
|
|
||||||
|
Snap->unlock();
|
||||||
|
|
||||||
print "Finished installing $self->{'name'}\n";
|
print "Finished installing $self->{'name'}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,9 +771,14 @@ sub installed {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $infofile;
|
my $infofile;
|
||||||
|
|
||||||
$infofile = Snap->INSTDIR . "/$self->{'name'}/snapinfo";
|
if ( ref( $self ) ) {
|
||||||
|
$infofile = Snap->INSTDIR . "/$self->{'name'}/snapinfo";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$infofile = Snap->INSTDIR . "/$self/snapinfo";
|
||||||
|
}
|
||||||
|
|
||||||
if ( -f $infofile ) {
|
if ( ref( $self ) && -f $infofile ) {
|
||||||
my $snapinfo;
|
my $snapinfo;
|
||||||
|
|
||||||
open( SNAPINFO, "<$infofile" ) ||
|
open( SNAPINFO, "<$infofile" ) ||
|
||||||
@@ -685,6 +798,9 @@ sub installed {
|
|||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
elsif ( -f $infofile ) {
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@@ -693,9 +809,9 @@ sub printbrief {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
if ( -t STDOUT ) {
|
if ( -t STDOUT ) {
|
||||||
printf( '%-12.12s ', $self->{'name'} );
|
printf( '%-16.16s ', $self->{'name'} );
|
||||||
printf( '%-10.10s ', $self->{'version'} );
|
printf( '%-10.10s ', $self->{'version'} );
|
||||||
printf( '%.58s', $self->{'brief'} || $self->{'description'} );
|
printf( '%.52s', $self->{'brief'} || $self->{'description'} );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf( '%-30.30s', $self->{'name'} );
|
printf( '%-30.30s', $self->{'name'} );
|
||||||
@@ -708,25 +824,8 @@ sub printbrief {
|
|||||||
|
|
||||||
sub printself {
|
sub printself {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my @fields = qw(
|
|
||||||
name
|
|
||||||
version
|
|
||||||
depends
|
|
||||||
srcpkg
|
|
||||||
arch
|
|
||||||
status
|
|
||||||
bytes
|
|
||||||
url
|
|
||||||
path
|
|
||||||
source
|
|
||||||
repo
|
|
||||||
sha256
|
|
||||||
sha256man
|
|
||||||
brief
|
|
||||||
description
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach my $field ( @fields ) {
|
foreach my $field ( FIELDS ) {
|
||||||
if ( $self->{$field} ) {
|
if ( $self->{$field} ) {
|
||||||
print "$field: $self->{$field}\n";
|
print "$field: $self->{$field}\n";
|
||||||
}
|
}
|
||||||
@@ -738,18 +837,28 @@ sub remove {
|
|||||||
my $pkgdir = Snap->INSTDIR . "/$self->{'name'}";
|
my $pkgdir = Snap->INSTDIR . "/$self->{'name'}";
|
||||||
my $snapinfo = "$pkgdir/snapinfo";
|
my $snapinfo = "$pkgdir/snapinfo";
|
||||||
my $manifest = "$pkgdir/manifest";
|
my $manifest = "$pkgdir/manifest";
|
||||||
|
my $usher = "$pkgdir/usher";
|
||||||
|
my $cnt = 0;
|
||||||
|
|
||||||
|
Snap->lock();
|
||||||
|
|
||||||
$self->files( { quiet => 1, all => 1 } );
|
$self->files( { quiet => 1, all => 1 } );
|
||||||
|
|
||||||
print "Removing $self->{'name'}... ";
|
print "Removing $self->{'name'}=$self->{'version'}\n";
|
||||||
|
|
||||||
$self->usher( 'prerm' );
|
$self->usher( 'prerm' );
|
||||||
|
|
||||||
|
print "\e[?25l\r";
|
||||||
|
|
||||||
foreach ( @{$self->{'files'}} ) {
|
foreach ( @{$self->{'files'}} ) {
|
||||||
if ( -f Snap->TARGET . "/$_" ) {
|
if ( -f Snap->TARGET . "/$_" ) {
|
||||||
unlink( Snap->TARGET . "/$_" ) || Snap->error(
|
unlink( Snap->TARGET . "/$_" ) || Snap->error(
|
||||||
int( $! ), "unlink(): " . Snap->TARGET
|
int( $! ), "unlink(): " . Snap->TARGET
|
||||||
. "/$_: $!" );
|
. "/$_: $!" );
|
||||||
|
|
||||||
|
print "\e[K$_\r";
|
||||||
|
|
||||||
|
$cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,7 +869,16 @@ sub remove {
|
|||||||
unlink( $snapinfo ) || Snap->error( int( $! ), "unlink():"
|
unlink( $snapinfo ) || Snap->error( int( $! ), "unlink():"
|
||||||
. " $snapinfo: $!" );
|
. " $snapinfo: $!" );
|
||||||
|
|
||||||
print "DONE\n";
|
if ( -f $usher ) {
|
||||||
|
unlink( $usher ) || Snap->error( int( $! ), "unlink():"
|
||||||
|
. " $usher: $!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
print "\e[K$cnt files removed\e[?25h\n";
|
||||||
|
|
||||||
|
Snap->unlock();
|
||||||
|
|
||||||
|
print "Finished removing $self->{'name'}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub revdeps {
|
sub revdeps {
|
||||||
@@ -910,6 +1028,34 @@ sub usher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
#
|
||||||
|
# The usher script is forked and execed as a child
|
||||||
|
# process. For most packages the process will be
|
||||||
|
# executed in a chroot environment if a TARGET has
|
||||||
|
# been specified.
|
||||||
|
#
|
||||||
|
# The presence of coreutils should indicate an
|
||||||
|
# environment in which a chroot would be successful.
|
||||||
|
# We also check for bash or dash since usher
|
||||||
|
# should always be a shell script. This should be
|
||||||
|
# reduced to only checking for dash in the future
|
||||||
|
# since the intention is for all usher scripts
|
||||||
|
# to use /bin/sh which is expected to be dash.
|
||||||
|
#
|
||||||
|
# Certain packages (such as glibc) need to be able
|
||||||
|
# to execute usher without a chroot if a full
|
||||||
|
# environment is unavailable.
|
||||||
|
#
|
||||||
|
# For non-root users a fake chroot environment is
|
||||||
|
# created (if fakeroot and fakechroot is present).
|
||||||
|
#
|
||||||
|
# There is a bit of a hack here to undef TARGET
|
||||||
|
# so that usher scripts which still attempt to
|
||||||
|
# perform a chroot will not do so.
|
||||||
|
#
|
||||||
|
####################################################
|
||||||
|
|
||||||
if ( ! -f $usher ) {
|
if ( ! -f $usher ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -918,6 +1064,25 @@ sub usher {
|
|||||||
waitpid( $pid, 0 );
|
waitpid( $pid, 0 );
|
||||||
$stat = $? >> 8;
|
$stat = $? >> 8;
|
||||||
}
|
}
|
||||||
|
elsif ( Snap->TARGET && installed( 'coreutils' ) &&
|
||||||
|
installed( 'dash' ) ) {
|
||||||
|
my $cmd;
|
||||||
|
$usher = substr( $usher, length( Snap->TARGET ) );
|
||||||
|
undef( $ENV{'TARGET'} );
|
||||||
|
|
||||||
|
if ( $> ) {
|
||||||
|
$ENV{'PATH'} = "$ENV{'PATH'}:/sbin:/usr/sbin";
|
||||||
|
$cmd = "fakeroot fakechroot /usr/sbin/chroot "
|
||||||
|
. Snap->TARGET . " $usher $action";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chroot( Snap->TARGET );
|
||||||
|
chdir( '/' );
|
||||||
|
$cmd = "$usher $action";
|
||||||
|
}
|
||||||
|
|
||||||
|
exec( $cmd );
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
exec( "$usher $action" );
|
exec( "$usher $action" );
|
||||||
}
|
}
|
||||||
@@ -933,7 +1098,7 @@ sub usher {
|
|||||||
# because the first shift gives you the class due to the
|
# because the first shift gives you the class due to the
|
||||||
# fact that it must be called while specifying the namespace
|
# fact that it must be called while specifying the namespace
|
||||||
#
|
#
|
||||||
# It has be modded on the central server only for now...
|
# It has been modded on the central server only for now...
|
||||||
#
|
#
|
||||||
############################################################
|
############################################################
|
||||||
|
|
||||||
@@ -946,4 +1111,33 @@ sub sha256 {
|
|||||||
return( $digest->hexdigest );
|
return( $digest->hexdigest );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub source {
|
||||||
|
my $self = shift;
|
||||||
|
my $gitcmd = "git clone git://git.snaplinux.org/$self->{'srcpkg'}.git";
|
||||||
|
my $sel = IO::Select->new();
|
||||||
|
my $stat;
|
||||||
|
my $pid;
|
||||||
|
|
||||||
|
if ( $pid = fork() ) {
|
||||||
|
waitpid( $pid, 0 );
|
||||||
|
$stat = $? >> 8;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
exec( $gitcmd );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $stat ) {
|
||||||
|
Snap->error( $stat, "Failed to clone $self->{'srcpkg'}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $pid = fork() ) {
|
||||||
|
waitpid( $pid, 0 );
|
||||||
|
$stat = $? >> 8;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chdir( $self->{'srcpkg'} );
|
||||||
|
exec( "git checkout v$self->{'version'}" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
216
SRC/snap/Snap.pm
216
SRC/snap/Snap.pm
@@ -89,7 +89,7 @@ use constant VERFILE => eval {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
use constant {
|
use constant {
|
||||||
VERSION => '0.11',
|
VERSION => '0.12',
|
||||||
SNAPDIR => TARGET . '/var/lib/snap',
|
SNAPDIR => TARGET . '/var/lib/snap',
|
||||||
PKGDIR => TARGET . '/var/lib/snap/packages',
|
PKGDIR => TARGET . '/var/lib/snap/packages',
|
||||||
INSTDIR => TARGET . '/var/lib/snap/installed',
|
INSTDIR => TARGET . '/var/lib/snap/installed',
|
||||||
@@ -105,7 +105,7 @@ use constant SNAPVER => eval {
|
|||||||
|
|
||||||
return( $version );
|
return( $version );
|
||||||
};
|
};
|
||||||
use constant LOCKFILE => '/var/lock/snap';
|
use constant LOCKFILE => TARGET . '/.snap';
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
#
|
#
|
||||||
@@ -115,17 +115,6 @@ use constant LOCKFILE => '/var/lock/snap';
|
|||||||
|
|
||||||
$0 =~ s/.*\///;
|
$0 =~ s/.*\///;
|
||||||
|
|
||||||
############################################################
|
|
||||||
#
|
|
||||||
# Exit unless we can get exclusive 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" );
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
#
|
#
|
||||||
# Make sure we bring back the cursor if we're killed
|
# Make sure we bring back the cursor if we're killed
|
||||||
@@ -133,7 +122,9 @@ flock( LOCK, LOCK_EX|LOCK_NB ) || Snap->error( int( $! ), "flock(): "
|
|||||||
############################################################
|
############################################################
|
||||||
|
|
||||||
$SIG{INT} = sub{
|
$SIG{INT} = sub{
|
||||||
virtfs( 'umount' );
|
if ( TARGET ) {
|
||||||
|
virtfs( 'umount' );
|
||||||
|
}
|
||||||
|
|
||||||
print "\e[?25h\n";
|
print "\e[?25h\n";
|
||||||
|
|
||||||
@@ -182,9 +173,9 @@ sub chkyes {
|
|||||||
chomp( $yes );
|
chomp( $yes );
|
||||||
|
|
||||||
if ( lc( $yes ) eq 'n' ){
|
if ( lc( $yes ) eq 'n' ){
|
||||||
print STDERR "\nAborting!\n\n";
|
print STDERR "\nAborting!\n";
|
||||||
|
|
||||||
exit 1;
|
exit( 1 );
|
||||||
}
|
}
|
||||||
elsif ( lc( $yes ne 'y' ) ){
|
elsif ( lc( $yes ne 'y' ) ){
|
||||||
print "Answer 'y' or 'n': ";
|
print "Answer 'y' or 'n': ";
|
||||||
@@ -305,7 +296,9 @@ sub httpget {
|
|||||||
PeerPort => 'http(80)',
|
PeerPort => 'http(80)',
|
||||||
Proto => 'tcp'
|
Proto => 'tcp'
|
||||||
) || Snap->error( int( $! ), "IO::Socket::Inet->new(): $!" );
|
) || Snap->error( int( $! ), "IO::Socket::Inet->new(): $!" );
|
||||||
my $bytes;
|
my $bytes = 0;
|
||||||
|
my @wheel = qw( - \ | / );
|
||||||
|
my $p = 0;
|
||||||
|
|
||||||
local $| = 1;
|
local $| = 1;
|
||||||
|
|
||||||
@@ -326,7 +319,7 @@ sub httpget {
|
|||||||
|
|
||||||
while ( <$sock> ) {
|
while ( <$sock> ) {
|
||||||
if ( $dest ) {
|
if ( $dest ) {
|
||||||
$bytes = ( stat( $dest ) )[7] || 0;
|
$bytes += length( $_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $httpget{'dflag'} ) {
|
if ( ! $httpget{'dflag'} ) {
|
||||||
@@ -377,24 +370,25 @@ sub httpget {
|
|||||||
$httpget{'length'} * 100 );
|
$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 ( $p >= $#wheel ) {
|
||||||
if ( $i < $httpget{'pct'} / 5 ) {
|
$p = 0;
|
||||||
print '*';
|
}
|
||||||
}
|
else {
|
||||||
else {
|
$p++;
|
||||||
print ' ';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print "] $httpget{'pct'}%\r";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $dest ) {
|
if ( $dest ) {
|
||||||
print "Retrieving $filename [********************] 100%"
|
printf( "%-50.50s [%-20s] %s\e[?25h\n",
|
||||||
. "\e[?25h\n";
|
" * Downloaded $filename",
|
||||||
|
'*' x 20,
|
||||||
|
'100%' );
|
||||||
|
|
||||||
close( DEST );
|
close( DEST );
|
||||||
}
|
}
|
||||||
@@ -445,7 +439,46 @@ 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 list {
|
sub list {
|
||||||
|
my $listpackages = shift;
|
||||||
my $packages = {};
|
my $packages = {};
|
||||||
my $package = {};
|
my $package = {};
|
||||||
|
|
||||||
@@ -453,7 +486,8 @@ sub list {
|
|||||||
. INSTDIR . ": $!" );
|
. INSTDIR . ": $!" );
|
||||||
|
|
||||||
foreach my $dir ( sort { $a cmp $b } readdir( DIR ) ) {
|
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;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,6 +545,13 @@ sub listfiles {
|
|||||||
return( $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{
|
sub mkdirp{
|
||||||
( my $dir = shift ) =~ s/\/^//;
|
( my $dir = shift ) =~ s/\/^//;
|
||||||
my $mode = shift;
|
my $mode = shift;
|
||||||
@@ -527,28 +568,58 @@ sub mkdirp{
|
|||||||
|
|
||||||
### readconf() #############################################
|
### readconf() #############################################
|
||||||
#
|
#
|
||||||
# reads CONFFILE and builds a data structure with the
|
# reads INI style files and builds a data structure with the
|
||||||
# parsed values. Only the 'sources' section is treated
|
# parsed values.
|
||||||
# in a special way - it is pushed into an array to maintain
|
#
|
||||||
# the order. This allows us to give priority to the topmost
|
# The config file can 'include' additional directories.
|
||||||
# repositories
|
# 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 {
|
sub readconf {
|
||||||
|
my $conffile = shift || CONFFILE;
|
||||||
|
my $data = shift || {};
|
||||||
my $section = '';
|
my $section = '';
|
||||||
my $data = {};
|
|
||||||
my $line = 0;
|
my $line = 0;
|
||||||
|
my $type;
|
||||||
|
|
||||||
open( FILE, "<", CONFFILE ) || Snap->error( int( $! ),
|
if ( $conffile =~ /\.spt$/ ) {
|
||||||
"open: " . CONFFILE . ": $!\n" );
|
$type = 'template';
|
||||||
|
}
|
||||||
|
elsif ( $conffile =~ /\.conf$/ ) {
|
||||||
|
$type = 'config';
|
||||||
|
}
|
||||||
|
|
||||||
while ( <FILE> ) {
|
open( my $fh, "<", $conffile ) || Snap->error( int( $! ),
|
||||||
|
"open(): $conffile: $!\n" );
|
||||||
|
|
||||||
|
while ( <$fh> ) {
|
||||||
chomp( $_ );
|
chomp( $_ );
|
||||||
|
|
||||||
if ( $_ =~ /^\s*#/ ) {
|
if ( $_ =~ /^\s*#/ || $_ =~ /^$/ ) {
|
||||||
next;
|
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*/ ) {
|
elsif ( $_ =~ /\s*\[(\S+)\]\s*/ ) {
|
||||||
$section = $1;
|
$section = $1;
|
||||||
|
|
||||||
@@ -556,16 +627,22 @@ sub readconf {
|
|||||||
$data->{$section} = [];
|
$data->{$section} = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $section eq 'sources' &&
|
elsif ( $section eq 'sources' ) {
|
||||||
$_ =~ /(\S+)\s*=\s*(.*)$/ ) {
|
|
||||||
push( @{$data->{$section}}, $_ );
|
push( @{$data->{$section}}, $_ );
|
||||||
}
|
}
|
||||||
|
elsif ( $section && $type eq 'template' ) {
|
||||||
|
if ( ! $data->{'templates'}{$section} ) {
|
||||||
|
$data->{'templates'}{$section} = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
push( @{$data->{'templates'}{$section}}, $_ );
|
||||||
|
}
|
||||||
elsif ( $_ =~ /(\S+)\s*=\s*(.*)$/ ) {
|
elsif ( $_ =~ /(\S+)\s*=\s*(.*)$/ ) {
|
||||||
$data->{$section}{$1} = $2;
|
$data->{$section}{$1} = $2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close( FILE );
|
close( $fh );
|
||||||
|
|
||||||
return( $data );
|
return( $data );
|
||||||
}
|
}
|
||||||
@@ -608,35 +685,6 @@ sub setup {
|
|||||||
$chkfails++;
|
$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 ) {
|
if ( $target ) {
|
||||||
mkdir( TARGET, 0755 ) || Snap->error( int( $! ), "mkdir: $!" );
|
mkdir( TARGET, 0755 ) || Snap->error( int( $! ), "mkdir: $!" );
|
||||||
}
|
}
|
||||||
@@ -736,6 +784,13 @@ sub termsize {
|
|||||||
return( { row => $row, col => $col } );
|
return( { row => $row, col => $col } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub unlock {
|
||||||
|
if ( -f LOCKFILE ) {
|
||||||
|
unlink( LOCKFILE ) || Snap->error( int( $! ), "unlink(): "
|
||||||
|
. LOCKFILE . ": Unable to remove lock file" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
### vercmp() ###############################################
|
### vercmp() ###############################################
|
||||||
#
|
#
|
||||||
# This subroutine was basically copied verbatim from the
|
# This subroutine was basically copied verbatim from the
|
||||||
@@ -812,6 +867,18 @@ sub vercmp {
|
|||||||
@A <=> @B;
|
@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 {
|
sub virtfs {
|
||||||
my $command = shift;
|
my $command = shift;
|
||||||
my $virtfs = {
|
my $virtfs = {
|
||||||
@@ -832,7 +899,7 @@ sub virtfs {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( ! TARGET ) {
|
if ( $> || ! TARGET ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,6 +911,7 @@ sub virtfs {
|
|||||||
my $stat = 0;
|
my $stat = 0;
|
||||||
my $pid;
|
my $pid;
|
||||||
|
|
||||||
|
|
||||||
if ( ! -d $virtfs->{$fs}{'dir'} ) {
|
if ( ! -d $virtfs->{$fs}{'dir'} ) {
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|||||||
59
SRC/snap/core.spt
Normal file
59
SRC/snap/core.spt
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#
|
||||||
|
# These packages are the bare minimum necessary for a functional system.
|
||||||
|
# This file is required for snapinstall to function, so don't delete it!
|
||||||
|
#
|
||||||
|
|
||||||
|
[core]
|
||||||
|
snap-base
|
||||||
|
dash
|
||||||
|
texinfo
|
||||||
|
coreutils
|
||||||
|
glibc
|
||||||
|
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
|
||||||
|
mkinitramfs
|
||||||
|
mpfr
|
||||||
|
net-tools
|
||||||
|
procps-ng
|
||||||
|
psmisc
|
||||||
|
sed
|
||||||
|
shadow
|
||||||
|
tar
|
||||||
|
snap
|
||||||
|
initscripts
|
||||||
|
sysklogd
|
||||||
|
sysvinit
|
||||||
|
tar
|
||||||
|
util-linux
|
||||||
|
xz
|
||||||
|
zlib
|
||||||
233
SRC/snap/snap
233
SRC/snap/snap
@@ -6,7 +6,7 @@ use warnings;
|
|||||||
use Snap;
|
use Snap;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
my $command = shift( @ARGV );
|
my $command = shift( @ARGV ) || '';
|
||||||
my $conf = readconf();
|
my $conf = readconf();
|
||||||
my $commands = Snap::Commands->new();
|
my $commands = Snap::Commands->new();
|
||||||
my $sources = Snap::Sources->new( $conf->{'sources'} );
|
my $sources = Snap::Sources->new( $conf->{'sources'} );
|
||||||
@@ -48,15 +48,11 @@ elsif ( $command eq 'files' ) {
|
|||||||
};
|
};
|
||||||
my $string = "@ARGV";
|
my $string = "@ARGV";
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
foreach my $arg ( @ARGV ) {
|
foreach my $arg ( @ARGV ) {
|
||||||
my $package = Snap::Package->new( $arg );
|
my $package = Snap::Package->new( $arg );
|
||||||
|
|
||||||
$package->files( $opts );
|
$package->files( $opts );
|
||||||
}
|
}
|
||||||
|
|
||||||
print "\n";
|
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'genpkg' ) {
|
elsif ( $command eq 'genpkg' ) {
|
||||||
foreach my $arg ( @ARGV ) {
|
foreach my $arg ( @ARGV ) {
|
||||||
@@ -67,14 +63,26 @@ elsif ( $command eq 'help' ) {
|
|||||||
$commands->help();
|
$commands->help();
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'info' ) {
|
elsif ( $command eq 'info' ) {
|
||||||
print "\n";
|
my $cnt = 0;
|
||||||
|
|
||||||
|
if ( ! @ARGV ) {
|
||||||
|
Snap->error( 0, "'$command': You must supply an argument" );
|
||||||
|
|
||||||
|
$commands->commandhelp( 'info' );
|
||||||
|
|
||||||
|
exit( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
foreach my $arg ( @ARGV ) {
|
foreach my $arg ( @ARGV ) {
|
||||||
my $package = Snap::Package->new( $arg );
|
my $package = Snap::Package->new( $arg );
|
||||||
|
|
||||||
|
if ( $cnt ) {
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
$package->printself();
|
$package->printself();
|
||||||
|
|
||||||
print "\n";
|
$cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'install' ) {
|
elsif ( $command eq 'install' ) {
|
||||||
@@ -115,8 +123,6 @@ elsif ( $command eq 'install' ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
$sources->readpkgs();
|
$sources->readpkgs();
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
@@ -142,8 +148,8 @@ elsif ( $command eq 'install' ) {
|
|||||||
my $package;
|
my $package;
|
||||||
|
|
||||||
if ( ! -f $arg ) {
|
if ( ! -f $arg ) {
|
||||||
my ( $name, $version ) = split( /(((<|>)=?|=)(.*))/,
|
my ( $name, $version ) =
|
||||||
$arg );
|
split( /(((<|>)=?|=)(.*))/, $arg );
|
||||||
$opts->{'name'} = $name;
|
$opts->{'name'} = $name;
|
||||||
$opts->{'version'} = $version;
|
$opts->{'version'} = $version;
|
||||||
|
|
||||||
@@ -154,7 +160,7 @@ elsif ( $command eq 'install' ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $package ) {
|
if ( ! $package ) {
|
||||||
Snap->error( -1, "$arg: No such package found" );
|
exit( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $opts->{'nodeps'} ) {
|
if ( ! $opts->{'nodeps'} ) {
|
||||||
@@ -304,7 +310,9 @@ elsif ( $command eq 'install' ) {
|
|||||||
. ". Continue? (y/n): ";
|
. ". Continue? (y/n): ";
|
||||||
}
|
}
|
||||||
|
|
||||||
chkyes();
|
if ( ! $opts->{'yes'} ) {
|
||||||
|
chkyes();
|
||||||
|
}
|
||||||
|
|
||||||
foreach my $package ( @$packages ) {
|
foreach my $package ( @$packages ) {
|
||||||
if ( ! $virtfs ) {
|
if ( ! $virtfs ) {
|
||||||
@@ -319,28 +327,51 @@ elsif ( $command eq 'install' ) {
|
|||||||
if ( $virtfs ) {
|
if ( $virtfs ) {
|
||||||
virtfs( 'umount' );
|
virtfs( 'umount' );
|
||||||
}
|
}
|
||||||
|
|
||||||
print "\n";
|
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'list' ) {
|
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 ) ) ) {
|
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 'purge' ) {
|
||||||
|
print "Not yet implemented\n";
|
||||||
|
|
||||||
|
exit( -1 );
|
||||||
|
}
|
||||||
|
elsif ( $command eq 'rebuild' ) {
|
||||||
|
print "Not yet implemented\n";
|
||||||
|
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'refresh' ) {
|
elsif ( $command eq 'refresh' ) {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
$sources->refresh();
|
$sources->refresh();
|
||||||
|
|
||||||
print "\n";
|
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
foreach my $source ( @{$conf->{'sources'}} ) {
|
foreach my $source ( @{$conf->{'sources'}} ) {
|
||||||
@@ -353,6 +384,7 @@ elsif ( $command eq 'refresh' ) {
|
|||||||
}
|
}
|
||||||
elsif ( $command eq 'reinstall' ) {
|
elsif ( $command eq 'reinstall' ) {
|
||||||
my $opts = {
|
my $opts = {
|
||||||
|
quiet => 1,
|
||||||
yes => eval {
|
yes => eval {
|
||||||
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
|
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
|
||||||
if ( $ARGV[$i] eq '-y' ) {
|
if ( $ARGV[$i] eq '-y' ) {
|
||||||
@@ -363,15 +395,15 @@ elsif ( $command eq 'reinstall' ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
my $termsize = Snap->termsize();
|
||||||
my $packages = [];
|
my $packages = [];
|
||||||
my $virtfs = 0;
|
my $virtfs = 0;
|
||||||
|
my $cnt = 0;
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
$sources->readpkgs();
|
$sources->readpkgs();
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
foreach my $pkgname ( @ARGV ) {
|
foreach my $pkgname ( @ARGV ) {
|
||||||
my $package;
|
my $package;
|
||||||
|
|
||||||
@@ -379,6 +411,10 @@ elsif ( $command eq 'reinstall' ) {
|
|||||||
$package = Snap::Package->new( $pkgname );
|
$package = Snap::Package->new( $pkgname );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ( ! $sources->{'installed'}{$pkgname} ) {
|
||||||
|
Snap->error( -1, "$pkgname not installed" );
|
||||||
|
}
|
||||||
|
|
||||||
$package = $sources->{'installed'}{$pkgname};
|
$package = $sources->{'installed'}{$pkgname};
|
||||||
$package = $sources->search( {
|
$package = $sources->search( {
|
||||||
name => $package->{'name'},
|
name => $package->{'name'},
|
||||||
@@ -387,12 +423,6 @@ elsif ( $command eq 'reinstall' ) {
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $package ) {
|
|
||||||
print STDERR "Package '$pkgname' not installed\n";
|
|
||||||
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $package->{'path'} =~ /https*:\/\// ) {
|
if ( $package->{'path'} =~ /https*:\/\// ) {
|
||||||
( my $filename = $package->{'path'} ) =~ s/.*\///;
|
( my $filename = $package->{'path'} ) =~ s/.*\///;
|
||||||
|
|
||||||
@@ -404,37 +434,37 @@ elsif ( $command eq 'reinstall' ) {
|
|||||||
$package->{'path'} = Snap->PKGDIR . "/$filename";
|
$package->{'path'} = Snap->PKGDIR . "/$filename";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$package->files( $opts );
|
||||||
|
|
||||||
push( @$packages, $package );
|
push( @$packages, $package );
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $package ( @$packages ) {
|
foreach my $package ( sort { $a->{'name'} cmp $b->{'name'} }
|
||||||
my $termsize = Snap->termsize();
|
( @$packages ) ) {
|
||||||
my $cnt = 0;
|
if ( ! $cnt ) {
|
||||||
|
print "The following packages will be"
|
||||||
|
. " reinstalled:\n ";
|
||||||
|
|
||||||
foreach my $package ( sort { $a->{'name'} cmp $b->{'name'} }
|
|
||||||
( @$packages ) ) {
|
|
||||||
if ( ! $cnt ) {
|
|
||||||
print "The following packages will be"
|
|
||||||
. " reinstalled:\n ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $termsize->{'col'} - ( length(
|
|
||||||
$package->{'name'} ) + 3 ) <= 0 ) {
|
|
||||||
print "\n ";
|
|
||||||
|
|
||||||
$termsize = Snap->termsize();
|
|
||||||
}
|
|
||||||
|
|
||||||
print "$package->{'name'} ";
|
|
||||||
|
|
||||||
$termsize->{'col'} -= length( $package->{'name'} ) + 1;
|
|
||||||
$cnt++;
|
$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): ";
|
print "\n\nContinue? (y/n): ";
|
||||||
|
|
||||||
chkyes();
|
if ( ! $opts->{'yes'} ) {
|
||||||
|
chkyes();
|
||||||
|
}
|
||||||
|
|
||||||
foreach my $package ( @$packages ) {
|
foreach my $package ( @$packages ) {
|
||||||
if ( ! $virtfs ) {
|
if ( ! $virtfs ) {
|
||||||
@@ -447,8 +477,6 @@ elsif ( $command eq 'reinstall' ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtfs( 'umount' );
|
virtfs( 'umount' );
|
||||||
|
|
||||||
print "\n";
|
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'remove' ) {
|
elsif ( $command eq 'remove' ) {
|
||||||
my $opts = {
|
my $opts = {
|
||||||
@@ -478,8 +506,6 @@ elsif ( $command eq 'remove' ) {
|
|||||||
my $cnt = 0;
|
my $cnt = 0;
|
||||||
my $termsize = Snap->termsize();
|
my $termsize = Snap->termsize();
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
$sources->readpkgs();
|
$sources->readpkgs();
|
||||||
|
|
||||||
foreach my $arg ( split( /\s/, $string ) ) {
|
foreach my $arg ( split( /\s/, $string ) ) {
|
||||||
@@ -510,7 +536,13 @@ elsif ( $command eq 'remove' ) {
|
|||||||
foreach my $package ( sort { $a->{'name'} cmp $b->{'name'} }
|
foreach my $package ( sort { $a->{'name'} cmp $b->{'name'} }
|
||||||
( @$packages ) ) {
|
( @$packages ) ) {
|
||||||
if ( ! $cnt ) {
|
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(
|
if ( $termsize->{'col'} - ( length(
|
||||||
@@ -531,21 +563,27 @@ elsif ( $command eq 'remove' ) {
|
|||||||
print "\n\n" . human( $bytes ) . " will be recovered."
|
print "\n\n" . human( $bytes ) . " will be recovered."
|
||||||
. " Continue? (y/n): ";
|
. " Continue? (y/n): ";
|
||||||
|
|
||||||
chkyes();
|
if ( ! $opts->{'yes'} ) {
|
||||||
|
chkyes();
|
||||||
print "\n";
|
|
||||||
|
|
||||||
foreach my $package ( @$packages ) {
|
|
||||||
$package->remove( $sources );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print "\n";
|
print "\n";
|
||||||
|
|
||||||
|
$cnt = 0;
|
||||||
|
|
||||||
|
foreach my $package ( @$packages ) {
|
||||||
|
if ( $cnt ) {
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$package->remove( $sources );
|
||||||
|
|
||||||
|
$cnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'revdep' ) {
|
elsif ( $command eq 'revdep' ) {
|
||||||
my $revdeps = [];
|
my $revdeps = [];
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
$sources->readpkgs();
|
$sources->readpkgs();
|
||||||
|
|
||||||
foreach my $arg ( @ARGV ) {
|
foreach my $arg ( @ARGV ) {
|
||||||
@@ -561,8 +599,6 @@ elsif ( $command eq 'revdep' ) {
|
|||||||
if ( ! @$revdeps ) {
|
if ( ! @$revdeps ) {
|
||||||
print "No reverse dependencies found\n";
|
print "No reverse dependencies found\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
print "\n";
|
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'search' ) {
|
elsif ( $command eq 'search' ) {
|
||||||
my @attribs = qw( name version depends source repo description );
|
my @attribs = qw( name version depends source repo description );
|
||||||
@@ -607,19 +643,64 @@ elsif ( $command eq 'search' ) {
|
|||||||
( $opts->{'string'} = $string ) =~ s/^ *| *$//g;
|
( $opts->{'string'} = $string ) =~ s/^ *| *$//g;
|
||||||
}
|
}
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
if ( ! $sources->readpkgs() ) {
|
if ( ! $sources->readpkgs() ) {
|
||||||
exit -1;
|
exit( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $sources->search( $opts ) ) {
|
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' ) {
|
elsif ( $command eq 'verify' ) {
|
||||||
|
print "Not yet implemented\n";
|
||||||
|
|
||||||
|
exit( -1 );
|
||||||
|
|
||||||
foreach my $arg ( @ARGV ) {
|
foreach my $arg ( @ARGV ) {
|
||||||
my $package = Snap::Package->new( $arg );
|
my $package = Snap::Package->new( $arg );
|
||||||
|
|
||||||
@@ -627,16 +708,20 @@ elsif ( $command eq 'verify' ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'version' ) {
|
elsif ( $command eq 'version' ) {
|
||||||
print "\n" . Snap->VERSION . "\n\n";
|
print Snap->VERSION . "\n";
|
||||||
}
|
}
|
||||||
elsif ( $command ) {
|
elsif ( $command ) {
|
||||||
print "\n";
|
Snap->error( 0, "'$command': Invalid command" );
|
||||||
|
|
||||||
Snap->error( -1, "'$command': Invalid command" );
|
$commands->help();
|
||||||
|
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Snap->error( 0, "You must supply a command" );
|
Snap->error( 0, "You must supply a command" );
|
||||||
|
|
||||||
$commands->help();
|
$commands->help();
|
||||||
|
|
||||||
|
exit( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,15 @@ setup();
|
|||||||
my $conf = readconf();
|
my $conf = readconf();
|
||||||
my $sources = Snap::Sources->new( $conf->{'sources'} );
|
my $sources = Snap::Sources->new( $conf->{'sources'} );
|
||||||
|
|
||||||
|
my $container = eval {
|
||||||
|
for ( my $i = 0; $i <= $#ARGV; $i++ ) {
|
||||||
|
if ( $ARGV[$i] eq '-c' || $ARGV[$i] eq '--container' ) {
|
||||||
|
splice ( @ARGV, $i, 1 );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
my $opts = {
|
my $opts = {
|
||||||
repo => 'core',
|
repo => 'core',
|
||||||
quiet => 1
|
quiet => 1
|
||||||
@@ -19,82 +28,135 @@ my $corepkgs;
|
|||||||
my $packages;
|
my $packages;
|
||||||
my $virtfs = 0;
|
my $virtfs = 0;
|
||||||
my $prepkgs = {};
|
my $prepkgs = {};
|
||||||
my $prelist = [ 'snap-base', 'bash', 'coreutils', 'glibc',
|
my @prelist = qw(
|
||||||
'libacl', 'libattr', 'libcap', 'ncurses', 'readline',
|
);
|
||||||
'tzdata', 'perl', 'initscripts' ];
|
my @packages = ();
|
||||||
|
|
||||||
print "\n";
|
|
||||||
|
|
||||||
if ( ! Snap->TARGET ) {
|
if ( ! Snap->TARGET ) {
|
||||||
Snap->error( -1, 'A target must be specified with -t' );
|
Snap->error( -1, 'A target must be specified with -t' );
|
||||||
}
|
}
|
||||||
|
|
||||||
$sources->readpkgs();
|
$sources->readpkgs();
|
||||||
$corepkgs = $sources->search( $opts );
|
|
||||||
|
|
||||||
for ( my $i = 0; $i <= $#$corepkgs; $i++ ) {
|
foreach my $pkgname ( @{$conf->{'templates'}{'core'}} ) {
|
||||||
if ( ! $opts->{'nodeps'} ) {
|
my $package = $sources->search( { name => $pkgname, quiet => 1 } );
|
||||||
print "Resolving dependencies for"
|
|
||||||
. " $corepkgs->[$i]{'name'}\n";
|
|
||||||
|
|
||||||
$corepkgs->[$i]->depends( $sources, $packages );
|
if ( $package->{'status'} && $package->{'status'} eq 'installed' ) {
|
||||||
}
|
next;
|
||||||
else {
|
|
||||||
print "Ignoring dependencies for"
|
|
||||||
. " $corepkgs->[$i]{'name'}\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
push( @$packages, $corepkgs->[$i] );
|
if ( $package->{'path'} =~ /https*:\/\// ) {
|
||||||
}
|
( my $filename = $package->{'path'} ) =~ s/.*\///;
|
||||||
|
|
||||||
for ( my $i = 0; $i <= $#$packages; $i++ ) {
|
if ( -f "/var/lib/snap/packages/$filename" ) {
|
||||||
if ( $packages->[$i]{'path'} =~ /https*:\/\// ) {
|
$package->{'path'} = "/var/lib/snap/packages/$filename";
|
||||||
( my $filename = $packages->[$i]{'path'} ) =~ s/.*\///;
|
|
||||||
|
|
||||||
if ( ! -f Snap->PKGDIR . "/$filename" ) {
|
|
||||||
Snap->httpget( $packages->[$i]{'path'},
|
|
||||||
Snap->PKGDIR . "/$filename", 0644 );
|
|
||||||
}
|
}
|
||||||
|
elsif ( ! -f Snap->PKGDIR . "/$filename" ) {
|
||||||
|
Snap->httpget( $package->{'path'},
|
||||||
|
Snap->PKGDIR . "/$filename", 0644 );
|
||||||
|
|
||||||
$packages->[$i]{'path'} = Snap->PKGDIR . "/$filename";
|
$package->{'path'} = Snap->PKGDIR . "/$filename";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Snap->error( -1, "$package->{'name'}:"
|
||||||
|
. " Unable to determine package path" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
push( @packages, $package );
|
||||||
if ( grep( $_ eq $packages->[$i]{'name'}, @$prelist ) ) {
|
|
||||||
$prepkgs->{$packages->[$i]{'name'}} = $packages->[$i];
|
|
||||||
|
|
||||||
splice( @$packages, $i, 1 );
|
|
||||||
$i--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $package ( @$prelist ) {
|
foreach my $package ( @packages ) {
|
||||||
print "\n";
|
$package->files( $opts );
|
||||||
|
|
||||||
$prepkgs->{$package}->install();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach my $package ( @$packages ) {
|
|
||||||
if ( ! $virtfs ) {
|
|
||||||
$virtfs = virtfs( 'mount' );
|
|
||||||
}
|
|
||||||
|
|
||||||
print "\n";
|
print "\n";
|
||||||
|
|
||||||
$package->install();
|
$package->install();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $virtfs ) {
|
if ( ! @packages ) {
|
||||||
my $pid;
|
print "Nothing to do\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Setting root password\n";
|
||||||
|
|
||||||
if ( $pid = fork() ) {
|
if ( $> ) {
|
||||||
waitpid( $pid, 0 );
|
exec( "fakeroot fakechroot /usr/sbin/chroot "
|
||||||
|
. Snap->TARGET . " passwd root" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exec( "chroot " . Snap->TARGET . " passwd" );
|
exec ( "chroot " . Snap->TARGET . " passwd root" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtfs( 'umount' );
|
exit;
|
||||||
|
|
||||||
print "\n";
|
#$sources->readpkgs();
|
||||||
|
#$corepkgs = $sources->search( $opts );
|
||||||
|
|
||||||
|
#for ( my $i = 0; $i <= $#$corepkgs; $i++ ) {
|
||||||
|
# if ( ! $opts->{'nodeps'} ) {
|
||||||
|
# print "Resolving dependencies for"
|
||||||
|
# . " $corepkgs->[$i]{'name'}\n";
|
||||||
|
#
|
||||||
|
# $corepkgs->[$i]->depends( $sources, $packages );
|
||||||
|
# }
|
||||||
|
# else {
|
||||||
|
# print "Ignoring dependencies for"
|
||||||
|
# . " $corepkgs->[$i]{'name'}\n";
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# push( @$packages, $corepkgs->[$i] );
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
#for ( my $i = 0; $i <= $#$packages; $i++ ) {
|
||||||
|
# if ( $packages->[$i]{'path'} =~ /https*:\/\// ) {
|
||||||
|
# ( my $filename = $packages->[$i]{'path'} ) =~ s/.*\///;
|
||||||
|
#
|
||||||
|
# if ( ! -f Snap->PKGDIR . "/$filename" ) {
|
||||||
|
# Snap->httpget( $packages->[$i]{'path'},
|
||||||
|
# Snap->PKGDIR . "/$filename", 0644 );
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# $packages->[$i]{'path'} = Snap->PKGDIR . "/$filename";
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# if ( grep( $_ eq $packages->[$i]{'name'}, @$prelist ) ) {
|
||||||
|
# $prepkgs->{$packages->[$i]{'name'}} = $packages->[$i];
|
||||||
|
#
|
||||||
|
# splice( @$packages, $i, 1 );
|
||||||
|
# $i--;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
#foreach my $package ( @prelist ) {
|
||||||
|
# print "\n";
|
||||||
|
#
|
||||||
|
# $prepkgs->{$package}->install();
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
#foreach my $package ( @$packages ) {
|
||||||
|
# if ( ! $virtfs ) {
|
||||||
|
# $virtfs = virtfs( 'mount' );
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# print "\n";
|
||||||
|
#
|
||||||
|
# $package->install();
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
#if ( $virtfs ) {
|
||||||
|
# my $pid;
|
||||||
|
#
|
||||||
|
# if ( $pid = fork() ) {
|
||||||
|
# waitpid( $pid, 0 );
|
||||||
|
# }
|
||||||
|
# else {
|
||||||
|
# exec( "chroot " . Snap->TARGET . " passwd" );
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
#virtfs( 'umount' );
|
||||||
|
#
|
||||||
|
#print "\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user