[tmcode commit] r304 - in spine/branches/spine_2_2-devel: . lib/Spine lib/Spine/ConfigSource lib/Spine/Plugin lib/Spine/Plugin/PackageManager lib/Spine/Plugin/Parselet lib/Spine/Util

0 views
Skip to first unread message

oss...@gmail.com

unread,
Nov 20, 2009, 9:12:18 AM11/20/09
to tmcode...@googlegroups.com
Author: richard
Date: Fri Nov 20 06:12:16 2009
New Revision: 304

Log:
This is an initial merge with Trunk, there will probably need to be some more manual work so consider this revision of spine_2_2-devel broken.

Added:
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/Default.pm
spine/branches/spine_2_2-devel/spine-mgmt (contents, props changed)
- copied, changed from r254, spine/branches/spine_2_2-devel/spine-config
spine/branches/spine_2_2-devel/spine-mgmt.conf
- copied, changed from r254, spine/branches/spine_2_2-devel/spine-config.conf
Deleted:
spine/branches/spine_2_2-devel/spine-config
spine/branches/spine_2_2-devel/spine-config.conf
Modified:
spine/branches/spine_2_2-devel/lib/Spine/Chain.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/ConfigFile.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/ConfigSource/ (props changed)
spine/branches/spine_2_2-devel/lib/Spine/ConfigSource.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Constants.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Data.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Auth.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/DescendOrder.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/DryRun.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/EthernetInterfaces.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Finalize.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/FirstRun.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Hardware.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Interpolate.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/NFSExports.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Overlay.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager.pm
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/APT.pm
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/ConfBasic.pm
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/DEB.pm
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/RPM.pm
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/YUM.pm
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Parselet/Operator.pm
spine/branches/spine_2_2-devel/lib/Spine/Plugin/PrintData.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/RPMPackageManager.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/RestartServices.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Skeleton.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemHarden.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemInfo.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/Templates.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/TestCase.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/TweakStartup.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Plugin/YumPackageManager.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/RPM.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Registry.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Singleton.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/State.pm (props changed)
spine/branches/spine_2_2-devel/lib/Spine/Util.pm (contents, props changed)
spine/branches/spine_2_2-devel/lib/Spine/Util/Exec.pm (contents, props changed)

Modified: spine/branches/spine_2_2-devel/lib/Spine/Data.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Data.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Data.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -61,6 +61,7 @@
c_hostname => $args{hostname},
c_release => $args{release},
c_verbosity => $args{verbosity} || 0,
+ c_quiet => $args{quiet},
c_version => $args{version} || $::VERSION,
c_config => $args{config},
c_croot => $croot,
@@ -195,13 +196,13 @@
}

# Some truly basic stuff first.
- $self->{c_label} = 'spine_core';
+ $self->{c_label} = 'spine-mgmt core';
$self->{c_start_time} = time();
$self->{c_ppid} = $$;

# FIXME Should these be moved to Spine::Plugin::Overlay?
- $self->{c_tmpdir} = "/tmp/spine." . $self->{c_ppid};
- $self->{c_tmplink} = "/tmp/spine.lastrun";
+ $self->{c_tmpdir} = "/tmp/spine-mgmt." . $self->{c_ppid};
+ $self->{c_tmplink} = "/tmp/spine-mgmt.lastrun";

# Retrieve "internal" config values nesessary for bootstrapping of
# discovery and therefore parsing of the tree.
@@ -242,11 +243,8 @@
return SPINE_FAILURE;
}

- # We *always* parse the top level config directory
- unless ($self->_get_values($self->{c_croot} , 1)) {
- $self->error('error parsing root config', 'crit');
- return SPINE_FAILURE;
- }
+ # Parse the top level config directory if it exists.
+ $self->_get_values($self->{c_croot});

# HOOKME Discovery: policy selection
#
@@ -573,8 +571,21 @@
{
my $self = shift;
my $key = shift;
+ my $force = shift || 0;
+
$self->print(4, "getvals -> $key");
- return undef unless ($key && exists $self->{$key});
+
+ unless ($key && exists $self->{$key})
+ {
+ if ($force)
+ {
+ return [];
+ }
+ else
+ {
+ return undef;
+ }
+ }

if ((ref $self->{$key}) eq "ARRAY")
{
@@ -622,7 +633,7 @@
$self->print(4, "getvals_by_keyname -> $key_re");

foreach my $key (keys(%{$self})) {
- if ($key =~ m/$key_re/o) {
+ if ($key =~ m/$key_re/) {
push @matching_vals, $self->{key};
}
}
@@ -747,8 +758,10 @@

if ($level <= $self->{c_verbosity})
{
- print $self->{c_label}, ": $msg\n";
- syslog("info", "spine: $msg")
+ print $self->{c_label}, ": $msg\n"
+ unless $self->{c_quiet};
+
+ syslog("info", "$msg")
if ( not $self->{c_dryrun} or $log_to_syslog );
}
}
@@ -762,7 +775,8 @@
if ($lvl <= $self->{c_verbosity})
{
# print $self->{c_label}, '[', join('::', caller()), ']: ', @_, "\n";
- print $self->{c_label}, ': ', @_, "\n";
+ print $self->{c_label}, ': ', @_, "\n"
+ unless $self->{c_quiet};
}
}

@@ -773,7 +787,7 @@
my $msg = shift;

if (not $self->{c_dryrun}) {
- syslog('info', "spine: $msg");
+ syslog('info', "$msg");
}
}

@@ -796,7 +810,7 @@
print STDERR $self->{c_label} . ": \[$level\] $msg\n";
}

- syslog("$level", "spine: $msg")
+ syslog("$level", "$msg")
unless $self->{c_dryrun};
push(@{$self->{c_errors}}, $msg);
}

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/Auth.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/Auth.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/Auth.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -362,7 +362,7 @@
}

foreach my $value (@{$values}) {
- my @list = split(m/:/o, $value);
+ my @list = split(m/:/, $value);

if (scalar(@list) != 2) {
$c->error("Invalid line in $map: \"$value\"", 'crit');
@@ -427,7 +427,7 @@
#
# Grep all further groups, pass in at once, limit recursion
#
- my @nested_groups = grep(m/^@/o, @{$auth_groups->{$group}});
+ my @nested_groups = grep(m/^@/, @{$auth_groups->{$group}});

if (scalar(@nested_groups)) {
push @list, _expand_auth_group($auth_groups, $group);
@@ -1489,7 +1489,7 @@
}

while (defined(my $d_entry = readdir(DIR))) {
- if ($d_entry =~ m/^.{1,2}$/o) {
+ if ($d_entry =~ m/^.{1,2}$/) {
next;
}
push @entries, $d_entry;

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/DescendOrder.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/DescendOrder.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/DescendOrder.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -27,7 +27,7 @@
use Spine::Data;
use Spine::Plugin::Interpolate;

-our ($VERSION, $DESCRIPTION, $MODULE, $CURRENT_DEPTH, $MAX_NESTING_DEPTH);
+our ($VERSION, $DESCRIPTION, $MODULE, $ABORT, $CURRENT_DEPTH, $MAX_NESTING_DEPTH);

$VERSION = sprintf("%d", q$Revision$ =~ /(\d+)/);
$DESCRIPTION = "Determines which policies to apply based on the spine-config" .
@@ -44,6 +44,7 @@

use File::Spec::Functions;

+$ABORT = 0;
$CURRENT_DEPTH = 0;
$MAX_NESTING_DEPTH = 15;

@@ -64,7 +65,14 @@
push @{$c->{c_hierarchy}}, get_includes($c, $dir);
}

- return PLUGIN_SUCCESS;
+ if ($ABORT)
+ {
+ return PLUGIN_FATAL;
+ }
+ else
+ {
+ return PLUGIN_SUCCESS;
+ }
}


@@ -77,7 +85,9 @@

# FIXME Too deep. Log something.
if (++$CURRENT_DEPTH > $MAX_NESTING_DEPTH) {
- goto empty_set;
+ $c->error('Search depth limit exceeded, aborting!', 'crit');
+ $ABORT = 1;
+ goto empty_set;
}

# If we want includes to appear before their children do so now.
@@ -120,6 +130,7 @@
}

--$CURRENT_DEPTH;
+ empty_set:
return wantarray ? @included : \@included;
}


Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/Hardware.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/Hardware.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/Hardware.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -224,7 +224,7 @@
$changed++;
$v = 1;
}
- elsif ($v =~ m/^\d\+$/o) {
+ elsif ($v =~ m/^\d\+$/) {
$changed++;
$v = int($v);
}
@@ -455,7 +455,7 @@
my @dies = $self->find_items(class => 'processor', name => qr/^cpu:/);

foreach my $die (@dies) {
- if ($die->{product} =~ m/(?i:dual\s+core|duo)/o) {
+ if ($die->{product} =~ m/(?i:dual\s+core|duo)/) {
$cores++;
}
}

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/Overlay.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/Overlay.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/Overlay.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -47,7 +47,6 @@
use File::Find;
use File::Spec::Functions;
use File::stat;
-use File::Touch;
use Fcntl qw(:mode);
use IO::File;
use Spine::Constants qw(:basic);
@@ -123,6 +122,7 @@
{
$c->print(4, "performing overlay from $dir");
unless (do_rsync(Config => $c,
+ Inert => 1,
Source => $overlay,
Target => catfile($tmpdir, $target),
Excludes => \@excludes)) {
@@ -163,7 +163,6 @@
my $overlay_root = $c->getval('overlay_root');
my $excludes = $c->getvals('apply_overlay_excludes');
my $max_diff_lines = $c->getval('max_diff_lines_to_print');
- my $touch = File::Touch->new( no_create => 1 );
my %rsync_args = (Config => $c, Source => $tmpdir, Output => undef,
Target => $overlay_root, Options => [qw(-c)],
Excludes => $excludes);
@@ -247,7 +246,7 @@
$c->cprint(" $line", 2, 0) if ($line =~ /^[+-]/);
}
}
- $touch->touch($srcfile);
+ utime(time, time, $srcfile);
}
}
elsif (not -e $destfile)
@@ -259,7 +258,7 @@
. ' owner/group ' . uid_conv($src_stat->uid) . ':'
. gid_conv($src_stat->gid) . ']');

- $touch->touch($srcfile);
+ utime(time, time, $srcfile);
}
}


Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -1,7 +1,7 @@
# -*- mode: perl; cperl-continued-brace-offset: -4; indent-tabs-mode: nil; -*-
# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai:

-# $Id: Skeleton.pm,v 1.1.2.2.2.1 2007/10/02 22:01:36 phil Exp $
+# $Id$

#
# This program is free software; you can redistribute it and/or modify
@@ -27,391 +27,200 @@
use Spine::Constants qw(:plugin);
use Spine::Registry;

-
-our $DEBUG = $ENV{SPINE_PACKAGEMANAGER_DEBUG} || 0;
-our $CONF = {};
+our $DEBUG = $ENV{SPINE_PACKAGEMANAGER_DEBUG} || 0;
+our $CONF = {};
our $DRYRUN = undef;
-use constant PKGMGR_CONFKEY => 'pkgmgr_config';
-
+use constant PKGMGR_CONFKEY => 'pkgmgr_config';

-our ($VERSION, $DESCRIPTION, $MODULE);
+our ( $VERSION, $DESCRIPTION, $MODULE );
our $PKGPLUGNAME = "Default";

-$VERSION = sprintf("%d.%02d", q$Revision: 1.1.2.2.2.1 $ =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf( "%d.%02d", q$Revision: 1.1.2.2.2.1 $ =~ /(\d+)\.(\d+)/ );
$DESCRIPTION = "Package Management Abstraction Layer";

-$MODULE = { author => 'oss...@ticketmaster.com',
- description => $DESCRIPTION,
- version => $VERSION,
- hooks => {
- "PARSE/initialize" => [ { name => 'PackageManager Initialize',
- code => \&initialize } ],
- "PARSE/complete" => [ { name => 'PackageManager Configure',
- code => \&load_config, } ],
- APPLY => [ { name => 'PackageManager',
- code => \&apply_changes } ],
- CLEAN => [ { name => 'PackageManager Clean',
- code => \&post_tidy } ],
- "PKGMGR/CalcMissing" => [ { name => 'PackageManager CalcMissing',
- code => \&calc_missing } ],
- "PKGMGR/CalcRemove" => [ { name => 'PackageManager CalcRemove',
- code => \&calc_remove } ],
- "PKGMGR/Report" => [ { name => 'PackageManager Report',
- code => \&report } ],
- "PKGMGR/ResolveInstalled" => [ { name => 'PackageManager ResolveInstaled',
- code => \&resolve_deps } ],
-
- },
- cmdline => { _prefix => 'pkgmgr',
- options => { },
- },
- };
-
+$MODULE = {
+ author => 'oss...@ticketmaster.com',
+ description => $DESCRIPTION,
+ version => $VERSION,
+ hooks => {
+ "PARSE/initialize" => [ { name => 'PackageManager Initialize',
+ code => \&_initialize } ],
+ "PARSE/complete" => [ { name => 'PackageManager',
+ code => \&_parse_complete, } ],
+ APPLY => [ { name => 'PackageManager Apply',
+ code => \&_apply_changes } ],
+ CLEAN => [ { name => 'PackageManager Clean',
+ code => \&_post_tidy } ],
+
+ },
+ cmdline => { _prefix => 'pkgmgr',
+ options => {}, }, };
+
+# stores are used to pass package information between plugins.
+# a store as a interface to searching for items
+# see... Spine::Plugin::PackageManager::Store bellow
sub get_store {
- return undef unless (exists $CONF->{instance_cfg}->{$_[0]}->{store});
- return $CONF->{instance_cfg}->{$_[0]}->{store};
+ return undef unless ( exists $CONF->{instance_cfg}->{ $_[0] }->{store} );
+ return $CONF->{instance_cfg}->{ $_[0] }->{store};
}

-sub initialize {
+# Runn all configured hooks that should run within PARSE/initialize
+sub _initialize {
my $c = shift;
-
+
$DRYRUN = $c->getval('c_dryrun');
my $registry = new Spine::Registry();

$registry->create_hook_point(qw(PKGMGR/Config));

- # Create the default hook points for package management plugins
- # A plugin may chose to add it's own as needed... This is just
- # to try to keep plugins being readable...
- # Init => Initialization steps
- # Update => Run automatic updates
- # Lookup => Build list of installed packages
- # Diff => Build out Remove and Install lists
- # CheckMissing => Will check if the missing packages are available
- # may well have to check for 'provides' and manipulate
- # ResolveInstalled => Look up deps for installed packages that will stay
- # ResolveMissing => Look up deps for to be installed packages
- # Report => Will report what is intended
- # Retrieve => Retrieve packages
- # Install => Install packages
- # Remove => Remove packages
- # Validate => Reports what got done
- $registry->create_hook_point(qw(PKGMGR/Init
- PKGMGR/Update
- PKGMGR/CheckUpdates
- PKGMGR/Lookup
- PKGMGR/CalcMissing
- PKGMGR/CalcRemove
- PKGMGR/ResolveInstalled
- PKGMGR/ResolveMissing
- PKGMGR/Report
- PKGMGR/Retrieve
- PKGMGR/Install
- PKGMGR/Remove
- PKGMGR/Validate));
-
-
- return PLUGIN_SUCCESS;
+ return _run_section( $c, undef, 'PARSE/initialize' );
}

-# Start of real work, for each instance and it's config
-# we start the apply section for that instance.
-sub apply_changes {
- my $c = shift;
+# run all configured hooks that run within the APPLY phase
+sub _apply_changes {
+ my $c = shift;
my $pc = $CONF;
- my $rc = 0;
- my $point;
-

- $c->cprint("Starting");
+ return _run_section( $c, $pc, 'APPLY' );

- # Used to store anything that we might need
- # between hooks but don't want for later
- my $work = {};
-
- while (my ($instance, $pic) = each %{$pc->{instance_cfg}}) {
- # Create the work area for the instance
- # things that don't happen here will stay
- # in the data tree...
- $work->{$instance} = {} unless (exists $work->{$instance});
- process_instance($c, $pc, $pic, $work->{$instance});
- }
}

-
-# Load the Package Manager config then load instance configs
-sub load_config {
- my $c = shift;
+# run all configured hooks that run within the PARSE/complete phase
+sub _parse_complete {
+ my $c = shift;
my $pc = $CONF;

my $registry = new Spine::Registry();

- $c->cprint("Finding pkgmgr config", 4);
+ $c->cprint( "Finding pkgmgr config", 4 );
$CONF = $pc = $c->getval(PKGMGR_CONFKEY);
-
- $pc->{instance_cfg} = { };
+
+ $pc->{instance_cfg} = {};

# If we have no instances ten nothing to do.
- my ($pic, $point, $rc);
- unless (defined $pc->{instances}) {
- $c->cprint('No "instances" within ('.PKGMGR_CONFKEY.') key', 2);
+ my ( $pic, $point, $rc );
+ unless ( defined $pc->{instances} ) {
+ $c->cprint( 'No "instances" within (' . PKGMGR_CONFKEY . ') key', 2 );
return PLUGIN_SUCCESS;
}
- $c->cprint("Adding get_pkg_info data function", 2);
+
+ # Not sure if this is going to be useful... I guess it might be good
+ # to tie templates to pkg info???
+ $c->cprint( "Adding get_pkg_info data function", 3 );
+
# TODO catch errors
my $method = sub { new Spine::Plugin::PackageManager::DataHelper(@_) };
- unless ($registry->install_method("get_pkg_info", $method)) {
+ unless ( $registry->install_method( "get_pkg_info", $method ) ) {
return PLUGIN_ERROR;
}

# go through and load instance configs
- foreach my $instance (@{$pc->{instances}}) {
+ foreach my $instance ( @{ $pc->{instances} } ) {
+
# We assume that there will be a key for the instance, but
# fall back to a hash ref. XXX: This may be bad
$pic = $pc->{instance_cfg}->{$instance} = $c->getval($instance) || {};
+
+ $pic->{plugin_config} = {} unless exists $pic->{plugin_config};
+
# use a store for package information.
$pic->{store} = new Spine::Plugin::PackageManager::Store;
+
# we keep dryrun in the instance cfg since it can be placed
# in the key by the user not just a global dry run.
- $pic->{dryrun} = 1 if (defined $DRYRUN);
- # Take the instance conf and pass it through the config plugins
- # hopeful something will pick it up.
- $c->cprint("Finding config plugin for ($instance)", 4);
- $point = $registry->get_hook_point("PKGMGR/Config");
- # PKGINFO is passed to allow plugins to add functions
- (undef, $rc) = $point->run_hooks_until(PLUGIN_STOP, $c, $pic, $instance, $pc);
-
- if ($rc != PLUGIN_FINAL) {
- # Nothing implemented config for this instance...
- $c->error("Error with config for ($instance)", 'crit');
- return PLUGIN_ERROR;
- }
- }
-}
-
-sub process_instance {
- my $c = shift;
- my $pc = shift;
- my $pic = shift;
- my $work = shift;
-
- # IF we have not got a hook order for the instance
- # use the default one
- unless (exists $pic->{order}) {
- $pic->{order} = $pc->{default_order};
- }
-
- my $registry = new Spine::Registry();
-
- # Go through the order calling the hooks
- my ($point, $rc);
- foreach my $section (@{$pic->{order}}) {
- # XXX: each section can be in a few forms this might be confusing
- # what ever it is we want an array ref in the end
- # 1. A hash ref, it will only have one key which is the section name
- if (ref($section) eq 'HASH') {
- $section = [ each %$section ];
- # 3. it's a scalar
- } elsif (ref($section)) {
- $section = [ $section ];
- } else {
- $c->error("Error parsing section order config", 'crit');
- return PLUGIN_ERROR;
- }
- # Now we want the second element of our array ref to be a hash ref
- # of implementers... but it can start as
- # 1. there is no second part so we assume default
- if (!exists $section->[1]) {
- push @{$section}, { Default => undef };
- # 2. an array ref
- } elsif (ref($section->[1]) eq 'ARRAY') {
- my %tmp_hash = map { $_ => undef } @{$section->[1]};
- $section->[1] = \%tmp_hash;
- # 2. a scalar
- } elsif (!ref($section->[1])) {
- $section->[1] = { $section->[1] => undef }
- } else {
- $c->error("Error in section order ($section->[0]), invalid config", 'crit');
- return PLUGIN_ERROR;
- }
-
- # Now $section is an array ref of the secname and a hash ref of implementers
- # i.e. [ "Init", { YUM => undef, APT => undef } ]
-
- # HOOKME PKGMGR/<SECTION>
- $c->cprint("Starting section ($section->[0])", 2);
- $point = $registry->get_hook_point("PKGMGR/$section->[0]");
- (undef, $rc) = $point->run_hooks_until(PLUGIN_STOP, $c, $pic, $work, $section->[1]);
- if ($rc != PLUGIN_FINAL) {
- $c->error("Error in section ($section->[0])", 'crit');
- use Data::Dumper; print STDERR Dumper($pic);
-
- return PLUGIN_ERROR;
- }
+ $pic->{dryrun} = 1 if ( defined $DRYRUN );
}
+ $pc->{loaded} = {};
+ return _run_section( $c, $pc, 'PARSE/complete' );

- return PLUGIN_SUCCESS;
}

-sub post_tidy {
-}
+# run all configured hooks that run within the CLEAN phase
+sub _post_tidy {

-# Take a list of installed and to install and build a list
-# of to remove and missing, taking account of deps and new_deps
-sub calc_missing {
- my ($c, $instance_conf, undef, $section) = @_;
- my $s = $instance_conf->{store};
+ my $c = shift;
+ my $pc = $CONF;

- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ return _run_section( $c, $pc, 'CLEAN' );

- my $node;
- # Need to be installed
- foreach ($s->find_node('install')) {
- unless ($s->find_node('installed', 'name', $s->get_node_val('name', $_))) {
- $node = $s->create_node('missing');
- $s->copy_node($_, $node);
- }
- }
- return PLUGIN_FINAL;
}

-sub calc_remove {
- my ($c, $instance_conf, undef, $section) = @_;
- my $s = $instance_conf->{store};
- my $name;
+# Will go through all packagemanager instances (normally only one)
+# running any configured hooks for the phase passed along
+sub _run_section {
+ my ( $c, $pc, $phase ) = @_;

- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ # for every instance
+ foreach my $instance ( @{ $pc->{instances} } ) {

- foreach ($s->find_node('installed')) {
- $name = $s->get_node_val('name', $_);
- unless ($s->find_node('deps', 'name', $name) ||
- $s->find_node('install', 'name', $name) ||
- $s->find_node('new_deps', 'name', $name)) {
- $s->copy_node($_, $s->create_node('remove'));
- }
- }
- return PLUGIN_FINAL;
-}
+ # Get the instance config
+ my $pic = $pc->{instance_cfg}->{$instance};
+ return PLUGIN_SUCCESS unless ( exists $pic->{Order}->{$phase} );

-# For the list of packages that is to be kept on the system
-# work out what packages they need so we don't remove them
-# XXX it will not make sure all dpes are met. IF a dep is not
-# installed (which would mean something is broken it will neither
-# notice or report)
-sub resolve_deps {
- my ($c, $instance_conf, undef, $section) = @_;
+ my $registry = new Spine::Registry();

- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ # For every packagemanager section to run within this phase
+ foreach ( @{ $pic->{Order}->{$phase} } ) {
+ my ( $sec, @plugs ) = @{$_};

- # TODO: make this cleaner
- my $s = $instance_conf->{store};
+ # for every plugin within the pacakgemanager section
+ foreach my $plugin (@plugs) {
+ $c->cprint( "Starting $sec/$plugin", 3 );

- my @installed = $s->find_node('installed');
- my $pkg;
+ # Check if there is any instance config for the plugin, if not
+ # then create the hash so that plugins always have at least a
+ # blank hash.
+ $pic->{plugin_config}->{$plugin} = {}
+ unless exists $pic->{plugin_config}->{$plugin};
+
+ my $point;

- # build out a hash provides and packages names mapped to package
- # and a list of what packages depend on
- my %prov_lookup;
- my %dep_lookup;
- my %installed;
- foreach $pkg ($s->get_node_val([ 'name', 'provides', 'requires'], @installed)){
- $installed{$pkg->[0]} = undef;
- foreach (@{$pkg->[1]}) {
- unless (exists $prov_lookup{$_}) {
- $prov_lookup{$_} = [];
- }
- push @{$prov_lookup{$_}}, $pkg->[0];
- }
- $dep_lookup{$pkg->[0]} = $pkg->[2];
- }
+ # FIXME, this is horrid, need to implement a better design.
+ # We could define all the plugins within the spine config
+ # but that would be very messy looking...
+ # For each plugin we have to run atempt to load the plugin
+ # and register it's hook points.
+ unless ( exists $pc->{loaded}->{"$sec/$plugin"} ) {
+ $pc->{loaded}->{"$sec/$plugin"} =
+ $registry->load_plugin("PackageManager::$plugin");
+ $point = $registry->get_hook_point("PKGMGR/$sec/$plugin");
+ $point->register_hooks("PackageManager::$plugin");
+ } else {
+ $point = $registry->get_hook_point("PKGMGR/$sec/$plugin");
+ }

- my %missing = map { $_ => undef } $s->get_node_val('name', $s->find_node('missing'));
- my @pkgs = $s->get_node_val('name', $s->find_node('install'));
- my %install = map { $_ => undef } @pkgs;
- my %processed;
- while(@pkgs) {
- my @new_pkgs;
- foreach (@pkgs) {
- # We only do installed deps
- next if (exists $missing{$_});
- foreach (@{$dep_lookup{$_}}) {
- # This deals with deps where there is an '|' (OR)
- # XXX: used in DEB pkgs. Not sure if this should be here
- # maybe make it flexable...
- foreach (split(/\s*\|\s*/, $_)) {
- # have processed this one before.
- next if exists $processed{$_};
- if (exists $installed{$_}) {
- $s->copy_node($s->find_node('installed', 'name', $_),
- $s->create_node('deps'));
- push @new_pkgs, $_;
- $processed{$_} = undef;
- next;
- }
- foreach $pkg (@{$prov_lookup{$_}}) {
- # No point marking a dep for something in the install list
- next if exists $install{$pkg};
- $s->copy_node($s->find_node('installed', 'name', $pkg),
- $s->create_node('deps'));
- # use to resolve it's deps next run;
- push @new_pkgs, $pkg;
- $processed{$pkg} = undef;
- }
+ # Run all the hooks for this section/plugin (there is probably
+ # only one)
+ my $rc;
+ ( undef, $rc ) =
+ $point->run_hooks_until( PLUGIN_STOP, $c, $pic, $instance,
+ $pc );
+ # Since the user has said they want it to run in the conifg
+ # it is really bad if nothing implemented the hook point!
+ if ( $rc != PLUGIN_FINAL ) {
+ $c->error( "Error running ($instance, $sec, $plugin)",
+ 'crit' );
+ return PLUGIN_ERROR;
}
}
}
- @pkgs = @new_pkgs;
}
-
- return PLUGIN_FINAL;
+ return PLUGIN_SUCCESS;
}

-# Basic report of what is about to happen
-sub report {
- my ($c, $instance_conf, undef, $section) = @_;
- my $s = $instance_conf->{store};
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
-
- $c->cprint("Going to....");
- my @names;
- foreach my $report ([' update:', 'updates'],
- [' add:', 'missing'],
- [' add deps:', 'new_deps'],
- [' remove:', 'remove'],) {
-
-
- @names = $s->get_node_val('name', $s->find_node($report->[1]));
- next unless (@names > 0);
- $c->cprint(join(' ', $report->[0], @names));
- }
-
- return PLUGIN_FINAL;
-}
1;

# small package to be used in things like overlay templates
package Spine::Plugin::PackageManager::DataHelper;
use strict;
use Spine::Plugin::PackageManager;
+
sub new {
- my ($class, $c, $inst) = @_;
- return undef unless (defined $inst);
- my $self = bless { }, $class;
+ my ( $class, $c, $inst ) = @_;
+ return undef unless ( defined $inst );
+ my $self = bless {}, $class;
$self->{store} = Spine::Plugin::PackageManager::get_store($inst);
- return undef unless defined ($self->{store});
+ return undef unless defined( $self->{store} );
return $self;
}

@@ -429,6 +238,7 @@
# is fast and good to replace this...
package Spine::Plugin::PackageManager::Store;
use strict;
+
# XXX This package is slow but it's interface can stay the same and the
# implementation reworked.... At least you can scan through for every use of it
# and rework even if the api changes.
@@ -439,72 +249,71 @@
# without having to scan every store.

sub new {
- my ($class, $pkg) = @_;
+ my ( $class, $pkg ) = @_;

- return
- bless {
- store => {},
- }, $class;
+ return bless { store => {}, }, $class;
}

# create a node in a store
sub create_node {
my $self = shift;
- my ($store, @args) = @_;
-
+ my ( $store, @args ) = @_;
+
$self->{store}->{$store} = [] unless exists $self->{store}->{$store};
my $node = {};
- push @{$self->{store}->{$store}}, $node;
+ push @{ $self->{store}->{$store} }, $node;
$node = [ $self->{store}->{$store}, $node ];
- $self->set_node_val($node, @args);
+ $self->set_node_val( $node, @args );
return $node;
}

# add a node to a store, only to be used after a remove_node call
sub add_node {
my $self = shift;
- my ($store, $node, @args) = @_;
- if (defined $node->[0]) {
+ my ( $store, $node, @args ) = @_;
+ if ( defined $node->[0] ) {
+
# we don't allow nodes to be in two places
return undef;
}
$self->{store}->{$store} = [] unless exists $self->{store}->{$store};
- push @{$self->{store}->{$store}}, $node;
+ push @{ $self->{store}->{$store} }, $node;
$node = [ $self->{store}->{$store}, $node ];
- $self->set_node_val($node, @args);
+ $self->set_node_val( $node, @args );
return $node;
}

-# Fine either all nodes in a store,
+# Find either all nodes in a store,
# or all nodes in a <store> with a <key>
# or all nodes in a <store> with a <key> of <value> ... <key> <value>
# values of undef are take to mean as long as the key exists.
sub find_node {
my $self = shift;
- my ($store, @where) = @_;
+ my ( $store, @where ) = @_;

- return undef unless (exists $self->{store}->{$store});
+ return undef unless ( exists $self->{store}->{$store} );

- my (@result, $key, $value, $node);
- NODE: foreach $node (@{$self->{store}->{$store}}) {
- for (my $i = 0; $i < $#where ; $i = $i+2) {
- $key = $where[$i];
- $value = $where[$i+1];
- unless (exists $node->{$key} &&
- (!defined $value || $node->{$key} eq $value)) {
+ my ( @result, $key, $value, $node );
+ NODE: foreach $node ( @{ $self->{store}->{$store} } ) {
+ for ( my $i = 0 ; $i < $#where ; $i = $i + 2 ) {
+ $key = $where[$i];
+ $value = $where[ $i + 1 ];
+ unless ( exists $node->{$key}
+ && ( !defined $value || $node->{$key} eq $value ) )
+ {
next NODE;
}
}
push @result, [ $self->{store}->{$store}, $node ];
- }
+ }

- return wantarray ? @result : (exists $result[0] ? $result[0] : undef);
+ return wantarray ? @result : ( exists $result[0] ? $result[0] : undef );
}

# list the current store names
sub list_stores {
my $self = shift;
- return keys %{$self->{store}}
+ return keys %{ $self->{store} };
}

# remove a node, return the unconnected node so that
@@ -514,12 +323,13 @@
my (@nodes) = @_;

my @result;
- NODE: foreach my $node (@nodes) {
+ NODE: foreach my $node (@nodes) {
+
# since find_node can return undef it's worth checking.
next unless defined $node;
- for (my $i = 0 ; $i < @{$node->[0]} ; $i++) {
- if ($node->[1] == $node->[0]->[$i]) {
- splice(@{$node->[0]}, $i);
+ for ( my $i = 0 ; $i < @{ $node->[0] } ; $i++ ) {
+ if ( $node->[1] == $node->[0]->[$i] ) {
+ splice( @{ $node->[0] }, $i );
push @result, [ undef, $node->[1] ];
next NODE;
}
@@ -533,20 +343,20 @@
# shallow copy of a node to another
sub copy_node {
my $self = shift;
- my ($src, $dst) = @_;
- return %{$dst->[1]} = %{$src->[1]};
+ my ( $src, $dst ) = @_;
+ return %{ $dst->[1] } = %{ $src->[1] };
}

# set one or move value of a node
sub set_node_val {
my $self = shift;
- my ($node, @data) = @_;
+ my ( $node, @data ) = @_;

# since find_node can return undef it's worth checking.
- return 0 unless defined $node;
+ return 0 unless defined $node;

- my ($key, $value);
- while ($key = shift @data) {
+ my ( $key, $value );
+ while ( $key = shift @data ) {
my $value = shift @data;
$node->[1]->{$key} = $value;
}
@@ -559,13 +369,14 @@
# XXX: key is the first arg
sub get_node_val {
my $self = shift;
- my ($key, @nodes) = @_;
+ my ( $key, @nodes ) = @_;
my @result;
my $node;
foreach $node (@nodes) {
+
# since find_node can return undef it's worth checking.
next unless defined $node;
- if (ref($key)) {
+ if ( ref($key) ) {
my @sub_result;
foreach (@$key) {
push @sub_result, $node->[1]->{$_};

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/APT.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/APT.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/APT.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -39,28 +39,29 @@
description => $DESCRIPTION,
version => $VERSION,
hooks => {
- "PKGMGR/Init" => [ { name => 'APT Init',
+ "PKGMGR/Init/APT" => [ { name => 'APT Init',
code => \&init_apt } ],
- "PKGMGR/CheckUpdates" => [ { name => 'APT Check Update',
+ "PKGMGR/CheckUpdates/APT" => [ { name => 'APT Check Update',
code => \&check_update } ],
# Update installation
- "PKGMGR/Update" => [ { name => 'APT Update',
+ "PKGMGR/Update/APT" => [ { name => 'APT Update',
code => \&update } ],
# Work out the deps of what is to be installed and resolve
# virtual provides
- "PKGMGR/ResolveMissing" => [ { name => 'APT Resolve',
+ "PKGMGR/ResolveMissing/APT" => [ { name => 'APT Resolve',
code => \&_check_missing } ],
# install missing packages
- "PKGMGR/Install" => [ { name => 'APT Install',
+ "PKGMGR/Install/APT" => [ { name => 'APT Install',
code => \&install } ],
# remove packages
- "PKGMGR/Remove" => [ { name => 'APT Remove',
+ "PKGMGR/Remove/APT" => [ { name => 'APT Remove',
code => \&remove } ],
},

};

-our $PKGPLUGNAME = 'APT';
+use constant PKGPLUGNAME => 'APT';
+
our $DRYRUN = undef;

sub _report_stderr {
@@ -85,9 +86,11 @@
}

sub _create_pkg_name {
- my $node = shift;
+ my $item = shift;
+ return undef unless defined $item;
+ my $node = $item->[1];
my $name = $node->{name};
- if (exists $node->{version}) {
+ if (exists $node->{version} && defined $node->{version}) {
$name .= "#".$node->{version};
}
if (exists $node->{arch}) {
@@ -103,11 +106,7 @@
# Initialize the apt environment for this instance. Most of this code was
# stolen from the original package manager plugin.
sub init_apt {
- my ($c, $pic, undef, $section) = @_;
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ($c, $pic, undef) = @_;

if (exists $pic->{dryrun}) {
$DRYRUN=1;
@@ -118,10 +117,10 @@
aptget_args => [],
aptget_bin => 'apt-get',
);
- unless (defined $pic->{package_config}->{PKGPLUGNAME}) {
- $pic->{package_config}->{PKGPLUGNAME} = {};
+ unless (exists $pic->{plugin_config}->{PKGPLUGNAME}) {
+ $pic->{plugin_config}->{PKGPLUGNAME} = {};
}
- my $conf = $pic->{package_config}->{PKGPLUGNAME};
+ my $conf = $pic->{plugin_config}->{PKGPLUGNAME};
while (my ($key, $value) = each %default_conf) {
$conf->{$key} = $value unless exists $conf->{$key};
}
@@ -206,12 +205,9 @@
# FIXME lots of duplication of _install
sub _update {

- my ($checkrun, $c, $instance_conf, undef, $section) = @_;
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
- my $aptconf = $instance_conf->{package_config}->{PKGPLUGNAME};
+ my ($checkrun, $c, $instance_conf, undef) = @_;
+
+ my $aptconf = $instance_conf->{plugin_config}->{PKGPLUGNAME};
my $s = $instance_conf->{store};
# only carry on if there are any packages to resolve
my $ret;
@@ -238,14 +234,10 @@
}

sub _check_missing {
- my ($c, $instance_conf, undef, $section) = @_;
+ my ($c, $instance_conf) = @_;

- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
-
- my $aptconf = $instance_conf->{package_config}->{PKGPLUGNAME};
+
+ my $aptconf = $instance_conf->{plugin_config}->{PKGPLUGNAME};
my $s = $instance_conf->{store};
my @missing = $s->get_node_val('name',$s->find_node('missing', 'name'));

@@ -257,6 +249,7 @@

_report_stderr($c, $ret->{stderr});
if ($ret->{rc} != 0) {
+ $c->error('Could not run apt-get','warning');
return PLUGIN_ERROR;
}

@@ -334,18 +327,17 @@


sub _install {
- my ($checkrun, $c, $instance_conf, undef, $section) = @_;
+ my ($checkrun, $c, $instance_conf, undef) = @_;

- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
- my $aptconf = $instance_conf->{package_config}->{PKGPLUGNAME};
+
+ my $aptconf = $instance_conf->{plugin_config}->{PKGPLUGNAME};
my $s = $instance_conf->{store};
- my @missing = map { _create_pkg_name($_) } $s->find_node('missing', 'name');
- #my @missing = $s->get_node_val('name',$s->find_node('missing', 'name'));
- # only carry on if there are any packages to resolve
+
+ my @missing = $s->find_node('missing', 'name');
return PLUGIN_FINAL unless (@missing > 0);
+ @missing = map { _create_pkg_name($_) } @missing;
+
+
$c->cprint("Working out deps and provides for missing packages", 4);
my $ret;
if ($checkrun || exists $instance_conf->{dryrun}) {
@@ -365,13 +357,10 @@
my %missing = map { $_ => undef } @missing;
# Check out what the deps are and that we can find all the packages...
foreach (@{$ret->{stdout}}) {
-
- if (m/^Inst\s+([^\s]+)\s+\((?:[0-9]+:)?([^\s]+)\s+.*$/) {
+ if (m/^Selecting.*package\s+([^\s]+).\s*$/) {
my ($pkname, undef, undef) = _split_pkg_name($1);
if (exists $missing{$pkname}) {
$found{$pkname} = undef;
- } else {
- $s->create_node('new_deps', 'name', $pkname, 'version', $2) if $checkrun;
}
}
}
@@ -386,15 +375,11 @@
}

sub remove {
- my ($c, $instance_conf, undef, $section) = @_;
+ my ($c, $instance_conf, undef) = @_;

- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }

my $s = $instance_conf->{store};
- my $aptconf = $instance_conf->{package_config}->{PKGPLUGNAME};
+ my $aptconf = $instance_conf->{plugin_config}->{PKGPLUGNAME};

# only carry on if there is anything to remove
my @packages = $s->get_node_val('name', $s->find_node('remove', 'name'));
@@ -434,6 +419,85 @@
_install(undef, @_);
}

+# Actually handles the exec'ing and IO
+#sub _exec_apt
+#{
+# my $c = shift;
+# my $conf = shift;
+# my @cmdline = @_;
+# my $pid = -1;
+#
+# if (ref($_[0]) eq 'ARRAY')
+# {
+# # The plus sign is so that we actually call the shift function
+# @cmdline = @{ +shift };
+# }
+#
+# # NOTE: there is a split in the bellow lines because of an
+# # apt-get 'feature'.
+# # - If you pass arguments to apt-get as a single
+# # argv then open3 splits it and it works.
+# # - If you split them all out it also works.
+#
+# # NOTE: passing blank arguments causes strange apt-get errors
+# # like "E: Line 1 too long in source list" (it lies)
+# # rpounder Tue Aug 25 2009
+# #
+# my @fixed_cmdline;
+# foreach my $cmdpart (@{$conf->{aptget_args}}, @cmdline) {
+# push (@fixed_cmdline, split(' ', $cmdpart)) unless ($cmdpart eq '');
+# }
+#
+# my $exec_c = create_exec(inert => 1,
+# c => $c,
+# exec => exists $conf->{aptget-bin} ? $conf->{aptget-bin} : 'apt-get',
+# args => \@fixed_cmdline);
+#
+# unless ($exec_c->start())
+# {
+# $c->error('apt-get failed to run it seems', 'err');
+# return undef;
+# }
+#
+# $exec_c->closeinput();
+#
+# my @foo = $exec_c->readlines();
+# my $stdout = [@foo];
+#
+# @foo = $exec_c->readerrorlines();
+# my $stderr = [@foo];
+#
+# $exec_c->wait();
+#
+# # If there was an error, print it out
+# if ($exec_c->exitstatus() >> 8 != 0)
+# {
+# my $errormsg = extract_apt_error($c, $stderr);
+#
+# $c->error("apt-get $apt_func failed \[$errormsg\]", 'err');
+#
+# my $verb = $c->getval('c_verbosity');
+#
+ # if ($verb > 1)
+ # {
+ # foreach (@{$stdout})
+ # {
+ # $c->error("\t$_", 'err');
+ # }
+ # }
+#
+# 3 if ($verb > 2)
+ # {
+ # $c->error("failed command \[".join(" ", "apt-get", @cmdline)."\]", 'err');
+ # }
+#
+#
+ # return undef;
+#
+ # return $stdout;
+#}
+
+
sub run_apt {
my $conf = shift;
my @args = @_;
@@ -448,7 +512,7 @@
stdout => [],
stderr => [] };

- my $cmdline = join(' ', $conf->{aptget_bin}, @{$conf->{aptget_args}}, @args);
+ my $cmdline = join(' ', $conf->{aptget_bin}, @{$conf->{aptget_args} ? $conf->{aptget_args} : []}, @args);

# Reset our fh handles
my $stdin = new IO::Handle();
@@ -459,6 +523,7 @@
# IO::Handle objects and the command to run is pass in as an array,
# it won't exec the command line properly. However, if you join() it
# head of time, it'll run just fine.
+
eval { $pid = open3($stdin, $stdout, $stderr, $cmdline); };

# Siphon off output and error data so we can then waitpid() to reap

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/ConfBasic.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/ConfBasic.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/ConfBasic.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -1,7 +1,7 @@

# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai:

-# $Id: Skeleton.pm 22 2007-12-12 00:35:55Z ph...@ipom.com $
+# $Id$

#
# This program is free software; you can redistribute it and/or modify
@@ -25,37 +25,44 @@
use base qw(Spine::Plugin);
use Spine::Constants qw(:plugin);

-our ($VERSION, $DESCRIPTION, $MODULE);
+our ( $VERSION, $DESCRIPTION, $MODULE );
my $CPATH;

-$VERSION = sprintf("%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf( "%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/ );
$DESCRIPTION = "PackageManager::ConfBasic, basic config implementation";

-$MODULE = { author => 'oss...@ticketmaster.com',
+$MODULE = { author => 'oss...@ticketmaster.com',
description => $DESCRIPTION,
- version => $VERSION,
- hooks => { "PKGMGR/Config" => [ { name => 'pkgmrg_config',
- code => \&_process_config } ],
- },
- };
+ version => $VERSION,
+ hooks => {
+ "PKGMGR/Config/ConfBasic" => [
+ { name => 'pkgmrg_config',
+ code => \&_process_config
+ } ],
+ },
+};

-our $PLUGNAME = 'basic';

+# Parse the original packages type key (<PACKAGE>#<VERSION>.<ARCH>)
sub _process_config {
- my ($c, $pic, $instance) = @_;
+ my ( $c, $pic ) = @_;

- # Are we to deal with this?
- unless ($pic->{package_config}->{implementer} eq $PLUGNAME) {
- return PLUGIN_SUCCESS;
+ my $s = $pic->{store};
+
+ my $key_name = 'packages';
+
+ if ( $pic->{plugin_config}->{ConfBasic}->{'install-key'} ) {
+ $key_name = $pic->{plugin_config}->{ConfBasic}->{'install-key'};
}

- my $s = $pic->{store};
- foreach (@{$c->getvals('packages')}) {
+ foreach ( @{ $c->getvals('packages') } ) {
+
+ # This used to be the syntax passed to apt and still will be. Since
+ # later config plugins will probably be complex keys we split it out
+ # and leave it upto the APT/YUM/... implementation to work out how
+ # to deal with the data in the store.
m/^(.*?)(#.*)?(?:\.((?:(?:32|64)bit)|noarch))?$/;
- $s->create_node('install',
- 'name', $1,
- 'version', $2,
- 'arch', $3);
+ $s->create_node( 'install', 'name', $1, 'version', $2, 'arch', $3 );
}

return PLUGIN_FINAL;

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/DEB.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/DEB.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/DEB.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -1,7 +1,7 @@

# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai:

-# $Id: Skeleton.pm 22 2007-12-12 00:35:55Z ph...@ipom.com $
+# $Id$

#
# This program is free software; you can redistribute it and/or modify
@@ -24,61 +24,60 @@
package Spine::Plugin::PackageManager::DEB;
use base qw(Spine::Plugin);
use Spine::Constants qw(:plugin);
-use Spine::Util qw(getbin);
+use Spine::Util;

-our ($VERSION, $DESCRIPTION, $MODULE);
+our ( $VERSION, $DESCRIPTION, $MODULE );
my $CPATH;

-$VERSION = sprintf("%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf( "%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/ );
$DESCRIPTION = "PackageManager::DEB, DEB implementation";

-$MODULE = { author => 'oss...@ticketmaster.com',
- description => $DESCRIPTION,
- version => $VERSION,
- hooks => {
- "PKGMGR/Lookup" => [ { name => 'DEB LookupInstalled',
- code => \&_get_installed } ],
- },
+$MODULE = {
+ author => 'oss...@ticketmaster.com',
+ description => $DESCRIPTION,
+ version => $VERSION,
+ hooks => {
+ "PKGMGR/Lookup/DEB" => [ { name => 'DEB LookupInstalled',
+ code => \&_get_installed } ], },

};

-our $PKGPLUGNAME = 'DEB';

# Get information about the installed packages
sub _get_installed {
- my ($c, $instance_conf, undef, $section) = @_;
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ( $c, $instance_conf ) = @_;

# TODO: remove lameness, at least it's easy
- my $query_bin = getbin('dpkg-query', $c->getvals('dpkg-query_bin'));
- unless (defined $query_bin && -x $query_bin) {
+ my $query_bin = '/usr/bin/dpkg-query';
+ unless ( defined $query_bin && -x $query_bin ) {
$c->error('Could not find dpkg-query executable');
return PLUGIN_ERROR;
}
- my $output = `$query_bin --showformat='\${status}\t\${Package}\\t\${Architecture}\\t\${Version}\\t\${Provides}\\t\${Pre-Depends}\\t\${Depends}\\n' -W`;
- unless ($? eq 0) {
+
+ my $cmd =
+ "$query_bin --showformat='\${status}\t\${Package}\\t"
+ . "\${Architecture}\\t\${Version}\\t\${Provides}\\t"
+ . "\${Pre-Depends}\\t\${Depends}\\n' -W";
+ my $output = `$cmd`;
+
+ unless ( $? eq 0 ) {
$c->error('Error running dpkg-query');
return PLUGIN_ERROR;
}
my $s = $instance_conf->{store};

- foreach (split('\n', $output)) {
- my ($status, $name, $arch, $version, $provides, $pre_deps, $deps) = split('\t', $_);
- next unless $status =~ m/^install ok installed$/;
- $deps =~ s/\s+\([^\)]+\)//g;
- $pre_deps =~ s/\s+\([^\)]+\)//g;
- my @deps = split(/,\s*/, $pre_deps);
- push @deps, split(/,\s*/, $deps);
- my @provides = split(/,\s*/, $provides);
- $s->create_node('installed', 'name', $name,
- 'version', $version,
- 'arch', $arch,
- 'provides', \@provides,
- 'requires', \@deps);
+ foreach ( split( '\n', $output ) ) {
+ my ( $status, $name, $arch, $version, $provides, $pre_deps, $deps ) =
+ split( '\t', $_ );
+ next unless $status =~ m/^install ok installed$/;
+ $deps =~ s/\s+\([^\)]+\)//g;
+ $pre_deps =~ s/\s+\([^\)]+\)//g;
+ my @deps = split( /,\s*/, $pre_deps );
+ push @deps, split( /,\s*/, $deps );
+ my @provides = split( /,\s*/, $provides );
+ $s->create_node( 'installed', 'name', $name, 'version',
+ $version, 'arch', $arch, 'provides',
+ \@provides, 'requires', \@deps );
}

return PLUGIN_FINAL;

Added: spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/Default.pm
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/Default.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -0,0 +1,198 @@
+# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai:
+
+# $Id$
+
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# (C) Copyright Ticketmaster, Inc. 2007
+#
+
+use strict;
+
+package Spine::Plugin::PackageManager::Default;
+use base qw(Spine::Plugin);
+use Spine::Constants qw(:plugin);
+
+our ( $VERSION, $DESCRIPTION, $MODULE );
+my $CPATH;
+
+$VERSION = sprintf( "%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/ );
+$DESCRIPTION = "PackageManager::Default, some default packagemanager functions";
+
+$MODULE = { author => 'oss...@ticketmaster.com',
+ description => $DESCRIPTION,
+ version => $VERSION,
+ hooks => {
+ "PKGMGR/CalcMissing/Default" => [
+ { name => 'PackageManager CalcMissing',
+ code => \&calc_missing } ],
+ "PKGMGR/CalcRemove/Default" => [
+ { name => 'PackageManager CalcRemove',
+ code => \&calc_remove } ],
+ "PKGMGR/Report/Default" => [
+ { name => 'PackageManager Report',
+ code => \&report } ],
+ "PKGMGR/ResolveInstalled/Default" => [
+ { name => 'PackageManager ResolveInstaled',
+ code => \&resolve_deps } ], } };
+
+# Take a list of installed and to install and build a list
+# of to remove and missing, taking account of deps and new_deps
+sub calc_missing {
+ my ( $c, $instance_conf, undef, ) = @_;
+ my $s = $instance_conf->{store};
+
+ my $node;
+
+ # Need to be installed
+ foreach ( $s->find_node('install') ) {
+ unless (
+ $s->find_node( 'installed', 'name', $s->get_node_val( 'name', $_ )
+ ) )
+ {
+ $node = $s->create_node('missing');
+ $s->copy_node( $_, $node );
+ }
+ }
+ return PLUGIN_FINAL;
+}
+
+sub calc_remove {
+ my ( $c, $instance_conf, undef ) = @_;
+ my $s = $instance_conf->{store};
+ my $name;
+
+ foreach ( $s->find_node('installed') ) {
+ $name = $s->get_node_val( 'name', $_ );
+ unless ( $s->find_node( 'deps', 'name', $name )
+ || $s->find_node( 'install', 'name', $name )
+ || $s->find_node( 'new_deps', 'name', $name ) )
+ {
+ $s->copy_node( $_, $s->create_node('remove') );
+ }
+ }
+ return PLUGIN_FINAL;
+}
+
+# For the list of packages that is to be kept on the system
+# work out what packages they need so we don't remove them
+# XXX it will not make sure all dpes are met. IF a dep is not
+# installed (which would mean something is broken it will neither
+# notice or report)
+sub resolve_deps {
+ my ( $c, $instance_conf, undef ) = @_;
+
+ # TODO: make this cleaner
+ my $s = $instance_conf->{store};
+
+ my @installed = $s->find_node('installed');
+ my $pkg;
+
+ # build out a hash provides and packages names mapped to package
+ # and a list of what packages depend on
+ my %prov_lookup;
+ my %dep_lookup;
+ my %installed;
+ foreach $pkg (
+ $s->get_node_val( [ 'name', 'provides', 'requires' ], @installed ) )
+ {
+ $installed{ $pkg->[0] } = undef;
+ foreach ( @{ $pkg->[1] } ) {
+ unless ( exists $prov_lookup{$_} ) {
+ $prov_lookup{$_} = [];
+ }
+ push @{ $prov_lookup{$_} }, $pkg->[0];
+ }
+ $dep_lookup{ $pkg->[0] } = $pkg->[2];
+ }
+
+ my %missing =
+ map { $_ => undef } $s->get_node_val( 'name', $s->find_node('missing') );
+ my @pkgs = $s->get_node_val( 'name', $s->find_node('install') );
+ my %install = map { $_ => undef } @pkgs;
+ my %processed;
+ while (@pkgs) {
+ my @new_pkgs;
+ foreach (@pkgs) {
+
+ # We only do installed deps
+ next if ( exists $missing{$_} );
+ foreach ( @{ $dep_lookup{$_} } ) {
+
+ # This deals with deps where there is an '|' (OR)
+ # XXX: used in DEB pkgs. Not sure if this should be here
+ # maybe make it flexable...
+ foreach ( split( /\s*\|\s*/, $_ ) ) {
+
+ # have processed this one before.
+ next if exists $processed{$_};
+ if ( exists $installed{$_} ) {
+ $s->copy_node( $s->find_node( 'installed', 'name', $_ ),
+ $s->create_node('deps') );
+ push @new_pkgs, $_;
+ $processed{$_} = undef;
+ next;
+ }
+ foreach $pkg ( @{ $prov_lookup{$_} } ) {
+
+ # No point marking a dep for something in the install list
+ next if exists $install{$pkg};
+ $s->copy_node( $s->find_node( 'installed', 'name', $pkg
+ ),
+ $s->create_node('deps') );
+
+ # use to resolve it's deps next run;
+ push @new_pkgs, $pkg;
+ $processed{$pkg} = undef;
+ }
+ }
+ }
+ }
+ @pkgs = @new_pkgs;
+ }
+
+ return PLUGIN_FINAL;
+}
+
+# Basic report of what is about to happen
+sub report {
+ my ( $c, $instance_conf, undef ) = @_;
+ my $s = $instance_conf->{store};
+
+ $c->cprint("Going to....");
+ my @names;
+ foreach my $report ( [ ' update:', 'updates' ],
+ [ ' add:', 'missing' ],
+ [ 'add deps:', 'new_deps' ],
+ [ ' remove:', 'remove' ], )
+ {
+ my $list = join(
+ ' ',
+ $s->get_node_val( 'name',
+ $s->find_node( $report->[1] )
+ ) );
+
+ next unless ($list);
+
+ # Try not to have really long lines
+ while ($list =~ m/(.{1,55})(?:\s|$)/sog) {
+ $c->cprint($report->[0] . " " . $1);
+ $report->[0] =~ s/./ /g;
+ }
+ }
+
+ return PLUGIN_FINAL;
+}
+
+1;

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/RPM.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/RPM.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/RPM.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -1,7 +1,7 @@

# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai:

-# $Id: Skeleton.pm 22 2007-12-12 00:35:55Z ph...@ipom.com $
+# $Id$

#
# This program is free software; you can redistribute it and/or modify
@@ -26,45 +26,40 @@
use Spine::Constants qw(:plugin);
use Spine::RPM;

-our ($VERSION, $DESCRIPTION, $MODULE);
+our ( $VERSION, $DESCRIPTION, $MODULE );
my $CPATH;

-$VERSION = sprintf("%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf( "%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/ );
$DESCRIPTION = "PackageManager::RPM, RPM implementation";

-$MODULE = { author => 'oss...@ticketmaster.com',
- description => $DESCRIPTION,
- version => $VERSION,
- hooks => {
- "PKGMGR/ResolveInstalled" => [ { name => 'RPM ResolveInstaledDeps',
- code => \&_resolve_deps } ],
- "PKGMGR/Lookup" => [ { name => 'RPM ResolveInstaled',
- code => \&get_installed } ],
-
- },
+$MODULE = {
+ author => 'oss...@ticketmaster.com',
+ description => $DESCRIPTION,
+ version => $VERSION,
+ hooks => {
+ "PKGMGR/ResolveInstalled/RPM" => [
+ { name => 'RPM ResolveInstaledDeps',
+ code => \&_resolve_deps } ],
+ "PKGMGR/Lookup/RPM" => [
+ { name => 'RPM ResolveInstaled',
+ code => \&get_installed } ],

- };
+ },

-our $PKGPLUGNAME = 'RPM';
+};

sub _resolve_deps {
- my ($c, $instance_conf, undef, $section) = @_;
-
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ( $c, $instance_conf, undef ) = @_;

my $s = $instance_conf->{store};
- my @packages = $s->find_node('install', 'name');
- my @remove = Spine::RPM->new->keep($s->get_node_val('name', @packages));
- my %remove = map { $_ => undef } @remove;
-
- my @packages = $s->find_node('installed', 'name');
- foreach ($s->get_node_val('name', @packages)) {
- unless (exists $remove{$_}) {
- $s->create_node('deps', 'name', $_);
+ my @packages = $s->find_node( 'install', 'name' );
+ my @remove = Spine::RPM->new->keep( $s->get_node_val( 'name', @packages ) );
+ my %remove = map { $_ => undef } @remove;
+
+ my @packages = $s->find_node( 'installed', 'name' );
+ foreach ( $s->get_node_val( 'name', @packages ) ) {
+ unless ( exists $remove{$_} ) {
+ $s->create_node( 'deps', 'name', $_ );
}
}

@@ -72,27 +67,20 @@
}

sub get_installed {
- my ($c, $instance_conf, undef, $section) = @_;
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ( $c, $instance_conf, undef ) = @_;

my $s = $instance_conf->{store};

my $node;
- foreach (split(/\n/, `rpm -qa --qf "%{NAME}\t%{VERSION}\t%{ARCH}\n"`) ) {
- my ($name, $version, $arch) = split (/\t/, $_);
-
- $s->create_node('installed',
- 'name', $name,
- 'arch', $arch,
- 'version', $version);
+ foreach ( split( /\n/, `rpm -qa --qf "%{NAME}\t%{VERSION}\t%{ARCH}\n"` ) )
+ {
+ my ( $name, $version, $arch ) = split( /\t/, $_ );
+
+ $s->create_node( 'installed', 'name', $name, 'arch', $arch, 'version',
+ $version );
}

return PLUGIN_FINAL;
}

-
1;

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/YUM.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/YUM.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/PackageManager/YUM.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -1,7 +1,7 @@

# vim:shiftwidth=2:tabstop=8:expandtab:textwidth=78:softtabstop=4:ai:

-# $Id: Skeleton.pm 22 2007-12-12 00:35:55Z ph...@ipom.com $
+# $Id$

#
# This program is free software; you can redistribute it and/or modify
@@ -24,14 +24,9 @@
# I really really recommend installing the meta parser plugin for yum,
# it will speed things up a lot.
#
-# TODO: try to find a more direct YUM interface, or write a YUM plugin.
-# a lot of this parsing of output will be prone to fail.
# TODO: CheckUpdate should probably only check for deps, new_deps and install
# items. Will need to be run just before the report
# TODO: pull out the regexs for parsing YUM so that it is easier to update
-#
-# XXX: there is lots of storing of 'version' in this code. It's there so
-# if we do ever get pinning in YUM we can use it.

package Spine::Plugin::PackageManager::YUM;
use base qw(Spine::Plugin);
@@ -39,39 +34,53 @@
use IPC::Open3;
use Spine::Util qw(getbin);

-our ($VERSION, $DESCRIPTION, $MODULE);
+our ( $VERSION, $DESCRIPTION, $MODULE );
my $CPATH;

-$VERSION = sprintf("%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf( "%d.%02d", q$Revision: 22 $ =~ /(\d+)\.(\d+)/ );
$DESCRIPTION = "PackageManager::YUM, YUM implementation";

-$MODULE = { author => 'oss...@ticketmaster.com',
- description => $DESCRIPTION,
- version => $VERSION,
- hooks => {
- # Anything that we need to do at start up
- "PKGMGR/Init" => [ { name => 'YUM Init',
- code => \&init_yum } ],
- # Build a list of what needs to be updated
- "PKGMGR/CheckUpdates" => [ { name => 'YUM Check Update',
- code => \&check_updates } ],
- # Update installation
- "PKGMGR/Update" => [ { name => 'YUM Update',
- code => \&apply_updates } ],
- # Work out what is installed
- "PKGMGR/Lookup" => [ { name => 'YUM Lookup',
- code => \&get_installed } ],
- # Work out the deps of what is to be installed and resolve
- # virtual provides
- "PKGMGR/ResolveMissing" => [ { name => 'YUM Resolve',
- code => \&check_missing } ],
- # install missing packages
- "PKGMGR/Install" => [ { name => 'YUM Install',
- code => \&install } ],
- # remove packages
- "PKGMGR/Remove" => [ { name => 'YUM Remove',
- code => \&remove } ],
- },
+$MODULE = {
+ author => 'oss...@ticketmaster.com',
+ description => $DESCRIPTION,
+ version => $VERSION,
+ hooks => {
+
+ # Anything that we need to do at start up
+ "PKGMGR/Init/YUM" => [ {
+ name => 'YUM Init',
+ code => \&init_yum } ],
+
+ # Build a list of what needs to be updated
+ "PKGMGR/CheckUpdates/YUM" => [ {
+ name => 'YUM Check Update',
+ code => \&check_updates } ],
+
+ # Update installation
+ "PKGMGR/Update/YUM" => [ {
+ name => 'YUM Update',
+ code => \&apply_updates } ],
+
+ # Work out what is installed
+ "PKGMGR/Lookup/YUM" => [ {
+ name => 'YUM Lookup',
+ code => \&get_installed } ],
+
+ # Work out the deps of what is to be installed and resolve
+ # virtual provides
+ "PKGMGR/ResolveMissing/YUM" => [ {
+ name => 'YUM Resolve',
+ code => \&check_missing } ],
+
+ # install missing packages
+ "PKGMGR/Install/YUM" => [ {
+ name => 'YUM Install',
+ code => \&install } ],
+
+ # remove packages
+ "PKGMGR/Remove/YUM" => [ {
+ name => 'YUM Remove',
+ code => \&remove } ], },

};

@@ -79,21 +88,16 @@
our $YUM_BIN;

sub _report_stderr {
- my ($c, $stderr) = @_;
- foreach (@{$stderr}) {
- $c->error("$_", 'err');
+ my ( $c, $stderr ) = @_;
+ foreach ( @{$stderr} ) {
+ $c->error( "$_", 'err' );
}
}

sub init_yum {
- my ($c, $instance_conf, undef, $section) = @_;
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
-
- $YUM_BIN = getbin('yum', $c->getvals('yum_bin'));
- unless (defined $YUM_BIN && -x $YUM_BIN) {
+ my ( $c, $instance_conf ) = @_;
+ $YUM_BIN = getbin( 'yum', $c->getvals('yum_bin') );
+ unless ( defined $YUM_BIN && -x $YUM_BIN ) {
$c->error("Could not find an yum executable");
return PLUGIN_ERROR;
}
@@ -105,32 +109,26 @@
}

sub get_installed {
- my ($c, $instance_conf, undef, $section) = @_;
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ( $c, $instance_conf, undef ) = @_;

my $s = $instance_conf->{store};

# get yum to list the installed packages
- my $ret = run_yum(undef, "list installed");
+ my $ret = run_yum( undef, "list installed" );

- _report_stderr($c, $ret->{stderr});
- if ($ret->{rc} != 0) {
+ _report_stderr( $c, $ret->{stderr} );
+ if ( $ret->{rc} != 0 ) {
return PLUGIN_ERROR;
}

my $node;
- foreach (@{$ret->{stdout}}) {
+ foreach ( @{ $ret->{stdout} } ) {
chomp;
if (m/([^\s]*)\.([^\.\s]+)\s*([^\s]+)\s.*$/) {
+
# add the package into the installed store
- $s->create_node('installed',
- 'name', $1,
- 'arch', $2,
- 'version', $3);
+ $s->create_node( 'installed', 'name', $1, 'arch', $2, 'version',
+ $3 );
}
}

@@ -138,141 +136,147 @@
}

sub check_missing {
- my ($c, $instance_conf, undef, $section) = @_;
+ my ( $c, $instance_conf ) = @_;

- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my $s = $instance_conf->{store};
+ my @missing = $s->find_node( 'missing', 'name' );

- my $s = $instance_conf->{store};
- my @missing = $s->find_node('missing', 'name');
# only carry on if there are any packages to resolve
- return PLUGIN_FINAL unless (@missing > 0);
- $c->cprint("Working out deps and provides for missing packages", 4);
+ return PLUGIN_FINAL unless ( @missing > 0 );
+ $c->cprint( "Working out deps and provides for missing packages", 4 );
+
# XXX: not adding -y makes it like a dryrun...
# FIXME: the only way to work out provides is with debug, this isn't nice
- my $ret = run_yum("N\n", "-d 4 install", $s->get_node_val('name',@missing));
+ my $ret =
+ run_yum( "N\n", "-d 4 install", $s->get_node_val( 'name', @missing ) );

- _report_stderr($c, $ret->{stderr});
- if ($ret->{rc} != 0) {
+ _report_stderr( $c, $ret->{stderr} );
+ if ( $ret->{rc} != 0 ) {
return PLUGIN_ERROR;
}
-
+
my $node;
my $type = undef;
my %found;
- foreach (@{$ret->{stdout}}) {
+ foreach ( @{ $ret->{stdout} } ) {
+
# Find virtual provide and file provide items (-d 3 needed)
- if (m/^Matched\s+([^\s]+)\s+\-\s+([^\s]+)\.([^\s\.]+)\s+to require for\s+([^\s]+)\s*$/) {
- $c->cprint("$1 provides for: ($4)", 4);
- $node = $s->find_node('missing', 'name', $4);
+ if (m/^Matched\s+([^\s]+)\s+\-\s+([^\s]+)\.([^\s\.]+)\s+to require for\s+([^\s]+)\s*$/
+ )
+ {
+ $c->cprint( "$1 provides for: ($4)", 4 );
+ $node = $s->find_node( 'missing', 'name', $4 );
+
# Is the item resolved a missing package?
if ($node) {
- if ($s->find_node('installed', 'name', $1)) {
- # Translate items that are virtual and installed into install
- $s->create_node('install',
- 'name', $1,
- 'provides', $4,
- 'version', $2,
- 'arch', $3);
+ if ( $s->find_node( 'installed', 'name', $1 ) ) {
+
+ # Translate items that are virtual and installed into install
+ $s->create_node( 'install', 'name',
+ $1, 'provides',
+ $4, 'version',
+ $2, 'arch',
+ $3 );
next;
}
+
# The result is not installed so install it
$s->remove_node($node);
- $s->create_node('missing',
- 'name', $1,
- 'provides', $4,
- 'version', $2,
- 'arch', $3);
+ $s->create_node( 'missing', 'name', $1, 'provides',
+ $4, 'version', $2, 'arch',
+ $3 );
} else {
+
# It's not missing so it's a dep
- $s->create_node('new_dep',
- 'name', $1,
- 'version', $2,
- 'arch', $3);
+ $s->create_node( 'new_dep', 'name', $1, 'version', $2, 'arch',
+ $3 );
}
- } elsif (m/^-+>\s+Package\s+([^\s]+)\.([^\s\.]+)\s+[0-9]+:([^\s]*)\s+set to be updated/) {
+ } elsif (
+m/^-+>\s+Package\s+([^\s]+)\.([^\s\.]+)\s+[0-9]+:([^\s]*)\s+set to be updated/ )
+ {
+
# note that this package has been resolved.
$found{$1} = undef;
}
}

# check is there is anything we couldn't work out
- MISSING: foreach ($s->get_node_val('name', $s->find_node('missing', 'name'))) {
+ MISSING:
+ foreach ( $s->get_node_val( 'name', $s->find_node( 'missing', 'name' ) ) )
+ {
next if exists $found{$_};
- # XXX: I don't like this but if you have a virtual provides installed already
- # the install doesn't show you that this was the case in the install output
- # so we manually check if there is a virtual for this missing package...
- $c->cprint("Package ($_), checking if this is a virtual name", 4);
- my $ret = run_yum(undef, "-d 3 resolvedep", $s->get_node_val('name',@missing));
- _report_stderr($c, $ret->{stderr});
- if ($ret->{rc} != 0) {
- $c->error("Could not find package ($_)", 'crit');
+
+ # XXX: I don't like this but if you have a virtual provides installed already
+ # the install doesn't show you that this was the case in the install output
+ # so we manually check if there is a virtual for this missing package...
+ $c->cprint( "Package ($_), checking if this is a virtual name", 4 );
+ my $ret = run_yum( undef,
+ "-d 3 resolvedep",
+ $s->get_node_val( 'name', @missing ) );
+ _report_stderr( $c, $ret->{stderr} );
+ if ( $ret->{rc} != 0 ) {
+ $c->error( "Could not find package ($_)", 'crit' );
next MISSING;
}
- foreach (@{$ret->{stdout}}) {
- if (m/^Matched\s+([^\s]+)\s+\-\s+([^\s]+)\.([^\s\.]+)\s+to require for\s+([^\s]+)\s*$/) {
- $c->cprint("installed $1 provides for: ($4)", 4);
- $node = $s->find_node('missing', 'name', $4);
+ foreach ( @{ $ret->{stdout} } ) {
+ if (m/^Matched\s+([^\s]+)\s+\-\s+([^\s]+)\.([^\s\.]+)\s+to require for\s+([^\s]+)\s*$/
+ )
+ {
+ $c->cprint( "installed $1 provides for: ($4)", 4 );
+ $node = $s->find_node( 'missing', 'name', $4 );
$s->remove_node($node);
- $s->create_node('install',
- 'name', $1,
- 'provides', $4,
- 'version', $2,
- 'arch', $3);
+ $s->create_node( 'install', 'name', $1, 'provides',
+ $4, 'version', $2, 'arch',
+ $3 );
next MISSING;
}
}
- $c->error("Could not find package ($_)", 'crit');
+ $c->error( "Could not find package ($_)", 'crit' );
}

return PLUGIN_FINAL;
}

sub remove {
- my ($c, $instance_conf, undef, $section) = @_;
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ( $c, $instance_conf ) = @_;

my $s = $instance_conf->{store};

# only carry on if there is anything to remove
- my @packages = $s->get_node_val('name', $s->find_node('remove', 'name'));
- if (@packages > 0) {
- $c->cprint(join(' ', "Removing:", @packages), 4);
+ my @packages =
+ $s->get_node_val( 'name', $s->find_node( 'remove', 'name' ) );
+ if ( @packages > 0 ) {
+ $c->cprint( join( ' ', "Removing:", @packages ), 4 );
my $ret;
- if (exists $instance_conf->{dryrun}) {
- $ret = run_yum("N\n", "erase", @packages);
+ if ( exists $instance_conf->{dryrun} ) {
+ $ret = run_yum( "N\n", "erase", @packages );
} else {
- $ret = run_yum(undef, "-y erase", @packages);
+ $ret = run_yum( undef, "-y erase", @packages );
}

- _report_stderr($c, $ret->{stderr});
- if ($ret->{rc} != 0) {
+ _report_stderr( $c, $ret->{stderr} );
+ if ( $ret->{rc} != 0 ) {
return PLUGIN_ERROR;
}

- my (%removed, $line);
- foreach (@{$ret->{stdout}}) {
- if ($instance_conf->{dryrun}) {
+ my ( %removed, $line );
+ foreach ( @{ $ret->{stdout} } ) {
+ if ( $instance_conf->{dryrun} ) {
if (m/\s*([^\s]+)\s+.*\sinstalled\s/) {
$removed{$1} = undef;
}
next;
- } elsif (m/^Removed:(.*)$/ ) {
+ } elsif (m/^Removed:(.*)$/) {
$line = $1;
$line =~ s/\s*([^\s]+)\.[^\.]+\s*[^\s]+(?=\s|$)/\1 /g;
- %removed = map { $_ => undef } split(/\s+/, $line);
+ %removed = map { $_ => undef } split( /\s+/, $line );
}
}
+
# Work out what we didn't remove
foreach (@packages) {
- unless (exists $removed{$_}) {
- $c->error("Failed to remove ($_)", 'crit');
+ unless ( exists $removed{$_} ) {
+ $c->error( "Failed to remove ($_)", 'crit' );
}
}
}
@@ -281,110 +285,98 @@
}

sub install {
- my ($c, $instance_conf, undef, $section) = @_;
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
-
+ my ( $c, $instance_conf ) = @_;

my $s = $instance_conf->{store};
+
# Is there anything to install?
- my @packages = $s->get_node_val('name', $s->find_node('missing', 'name'));
- my (%installed, @deps);
- if (@packages > 0) {
- $c->cprint(join(' ', 'Installing:', @packages), 4);
+ my @packages =
+ $s->get_node_val( 'name', $s->find_node( 'missing', 'name' ) );
+ my ( %installed, @deps );
+ if ( @packages > 0 ) {
+ $c->cprint( join( ' ', 'Installing:', @packages ), 4 );
return PLUGIN_FINAL if exists $instance_conf->{dryrun};
+
# XXX: it will not report in anyway if you try to install something
# that does not exist, you have to check output....
- my $ret = run_yum(undef, "-y install", @packages);
+ my $ret = run_yum( undef, "-y install", @packages );

- _report_stderr($c, $ret->{stderr});
- if ($ret->{rc} != 0) {
+ _report_stderr( $c, $ret->{stderr} );
+ if ( $ret->{rc} != 0 ) {
return PLUGIN_ERROR;
}

# Detect what actually got installed
my ($line);
- foreach (@{$ret->{stdout}}) {
+ foreach ( @{ $ret->{stdout} } ) {
if (m/^Installed:(.+)$/) {
$line = $1;
$line =~ s/\s*([^\s]+)\.[^\.]+\s*[^\s]+(?=\s|$)/\1 /g;
- %installed = map { $_ => undef } split(/\s+/, $line);
- $c->cprint(join(' ', "Installed:", keys(%installed)), 4);
+ %installed = map { $_ => undef } split( /\s+/, $line );
+ $c->cprint( join( ' ', "Installed:", keys(%installed) ), 4 );
next;
}
if (m/^Dependency Installed:(.+)$/) {
$line = $1;
$line =~ s/\s*([^\s]+)\.[^\.]+\s*[^\s]+(?=\s|$)/\1 /g;
- @deps = split(/\s+/, $line);
- $c->cprint(join(' ', "Dependencies Installed:", @deps), 4);
+ @deps = split( /\s+/, $line );
+ $c->cprint( join( ' ', "Dependencies Installed:", @deps ), 4 );
}
}
}

# tell the user about anything that couldn't install
- foreach ($s->get_node_val('name', $s->find_node('missing', 'name'))) {
- next if (exists $installed{$_});
- $c->error("Unable to install ($_)", "crit");
+ foreach ( $s->get_node_val( 'name', $s->find_node( 'missing', 'name' ) ) ) {
+ next if ( exists $installed{$_} );
+ $c->error( "Unable to install ($_)", "crit" );
}

return PLUGIN_FINAL;
}

sub check_updates {
- my ($c, $instance_conf, undef, $section) = @_;
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ( $c, $instance_conf ) = @_;

my $s = $instance_conf->{store};
- my @packages = $s->get_node_val('name', $s->find_node('deps', 'name')),
- $s->get_node_val('name', $s->find_node('new_deps', 'name')),
- $s->get_node_val('name', $s->find_node('install', 'name'));
+ my @packages = $s->get_node_val( 'name', $s->find_node( 'deps', 'name' ) ),
+ $s->get_node_val( 'name', $s->find_node( 'new_deps', 'name' ) ),
+ $s->get_node_val( 'name', $s->find_node( 'install', 'name' ) );

#XXX: this will update everything if there are no packages. This is known
# and probably what you want if there is no package list at all....
- my $ret = run_yum(undef, "-y --obsoletes check-update", @packages);
-
+ my $ret = run_yum( undef, "-y --obsoletes check-update", @packages );
+
# A return of 0 means nothing to update
return PLUGIN_FINAL if $ret->{rc} == 0;

# A return of 100 just means that there are packages to update
# FIXME: seems to return 25600 outside of a shell???
- _report_stderr($c, $ret->{stderr});
- if ($ret->{rc} != 25600) {
+ _report_stderr( $c, $ret->{stderr} );
+ if ( $ret->{rc} != 25600 ) {
return PLUGIN_ERROR;
}

- foreach (@{$ret->{stdout}}) {
+ foreach ( @{ $ret->{stdout} } ) {
chomp;
- if (m/^([^\s]+)\.[^\.]+\s+([^\s]+)\s+updates/){
- $s->create_node('updates', 'name', $1);
+ if (m/^([^\s]+)\.[^\.]+\s+([^\s]+)\s+updates/) {
+ $s->create_node( 'updates', 'name', $1 );
}
}
return PLUGIN_FINAL;
}

sub apply_updates {
- my ($c, $instance_conf, undef, $section) = @_;
-
- # Are we to deal with this?
- unless (exists $section->{$PKGPLUGNAME}) {
- return PLUGIN_SUCCESS;
- }
+ my ( $c, $instance_conf ) = @_;

- my $s = $instance_conf->{store};
- my @packages = $s->get_node_val('name', $s->find_node('updates', 'name'));
- if (@packages > 0) {
- $c->cprint(join(' ', 'Updating:', @packages), 4);
+ my $s = $instance_conf->{store};
+ my @packages =
+ $s->get_node_val( 'name', $s->find_node( 'updates', 'name' ) );
+ if ( @packages > 0 ) {
+ $c->cprint( join( ' ', 'Updating:', @packages ), 4 );
return PLUGIN_FINAL if exists $instance_conf->{dryrun};
- my $ret = run_yum(undef, "-y update --obsoletes");
- _report_stderr($c, $ret->{stderr});
- if ($ret->{rc} != 0) {
+ my $ret = run_yum( undef, "-y update --obsoletes" );
+ _report_stderr( $c, $ret->{stderr} );
+ if ( $ret->{rc} != 0 ) {
return PLUGIN_ERROR;
}
}
@@ -394,24 +386,24 @@

sub run_yum {
my $input = shift;
- my @args = @_;
- my $pid = -1;
+ my @args = @_;
+ my $pid = -1;
+
+ if ( ref( $_[0] ) eq 'ARRAY' ) {

- if (ref($_[0]) eq 'ARRAY')
- {
# The plus sign is so that we actually call the shift function
@args = @{ +shift };
}
- my $ret = { rc => 127,
+ my $ret = { rc => 127,
stdout => [],
stderr => [] };

- unless (-x $YUM_BIN) {
+ unless ( -x $YUM_BIN ) {
$ret->{stderr} = "command not executable ($YUM_BIN)\n";
return $ret;
}

- my $cmdline = join(' ', $YUM_BIN, @args);
+ my $cmdline = join( ' ', $YUM_BIN, @args );

# Reset our fh handles
my $stdin = new IO::Handle();
@@ -422,20 +414,19 @@
# IO::Handle objects and the command to run is pass in as an array,
# it won't exec the command line properly. However, if you join() it
# head of time, it'll run just fine.
- eval { $pid = open3($stdin, $stdout, $stderr, $cmdline); };
+ eval { $pid = open3( $stdin, $stdout, $stderr, $cmdline ); };

# Siphon off output and error data so we can then waitpid() to reap
# the child process
print $stdin $input if defined $input;
$stdin->close();

- push @{$ret->{stdout}}, $stdout->getlines();
- push @{$ret->{stderr}}, $stderr->getlines();
+ push @{ $ret->{stdout} }, $stdout->getlines();
+ push @{ $ret->{stderr} }, $stderr->getlines();

- my $rc = waitpid($pid, 0);
+ my $rc = waitpid( $pid, 0 );

- if ($rc != $pid)
- {
+ if ( $rc != $pid ) {
$ret->{stderr} = ["failed to fork command ($cmdline)"];
return $ret;
}

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/Parselet/Operator.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/Parselet/Operator.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/Parselet/Operator.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -82,20 +82,20 @@
# i.e. _spine_replace() would be in the key as
# spine_replace().
$re = '_(_*' . CONTROL_PREFIX . '\w+\(.*\)\s*)';
- if ( $$line_ref =~ m/^$re$/o ) {
+ if ( $$line_ref =~ m/^$re$/ ) {
$$line_ref = $1;
return PLUGIN_SUCCESS;
}

# Detect legacy '=' operator and convert
- if ( $line_no == 1 && $$line_ref =~ m/^=\s*$/o ) {
+ if ( $line_no == 1 && $$line_ref =~ m/^=\s*$/ ) {
unshift @{ $data->{control} }, ["replace"];
$$line_ref = undef;
return PLUGIN_SUCCESS;
}

# Detect legacy '-' operator and convert
- if ( $$line_ref =~ m/^-(.*)/o ) {
+ if ( $$line_ref =~ m/^-(.*)/ ) {
push @{ $data->{control} }, [ "remove", $1 ];
$$line_ref = undef;
return PLUGIN_SUCCESS;
@@ -104,7 +104,7 @@
# Detect real control ops i.e. spine_replace()
# these will be processed by another plugin
$re = CONTROL_PREFIX . '(\w+)\((.*)\)\s*';
- if ( $$line_ref =~ m/^$re$/o ) {
+ if ( $$line_ref =~ m/^$re$/ ) {
push @{ $data->{control} }, [ $1, $2 ];
next;
}
@@ -121,7 +121,7 @@
# once people use the new format.
if ( ref($data->{obj}) eq "ARRAY"
&& exists $data->{obj}->[0]
- && $data->{obj}->[0] =~ m/^=\s*$/o )
+ && $data->{obj}->[0] =~ m/^=\s*$/ )
{
shift @{$data->{obj}};
$data->{control} = [] unless exists $data->{control};

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/RPMPackageManager.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/RPMPackageManager.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/RPMPackageManager.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -315,6 +315,9 @@
my $rval = 0;
my $rpm_bin = $c->getval('rpm_bin');
my $rpm_opts = $c->getval('rpm_opts') || '';
+ # RPM is stupid and thinks extra spaces are package names.
+ $rpm_opts =~ s/\s+//;
+ $rpm_opts =~ s/\s+$//;

# apt understands package.arch but RPM does not. The Spine RPM module
# uses the "name" tag from the installed RPM and compares that to the
@@ -342,13 +345,17 @@

unless ($c->getval('c_dryrun'))
{
- my @result = simple_exec(merge_error => 1,
- exec => 'rpm',
- args => ["-e",
- $rpm_opts,
- $remv],
- c => $c,
- inert => 0);
+ my $rpm_args = "-e $rpm_opts $remv";
+ if ( $rpm_opts =~ m// )
+ {
+ $rpm_args = "-e $remv";
+ }
+ my @result = simple_exec(merge_error => 1,
+ exec => 'rpm',
+ args => $rpm_args,
+ c => $c,
+ inert => 0);
+
if ($? > 0)
{
$c->error("package removal failed \[". join("",@result) . "\]", 'err');

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/RestartServices.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/RestartServices.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/RestartServices.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -39,8 +39,7 @@


use File::stat;
-use File::Touch;
-use Spine::Util qw(exec_initscript exec_command);
+use Spine::Util qw(exec_initscript simple_exec);

my $DRYRUN;

@@ -53,7 +52,6 @@
my $start_time = $c->getval('c_start_time');
my $startup = $c->getvals('startup');
my $restart_deps = $c->getvals('restart_deps');
- my $touch = File::Touch->new( no_create => 1 );
my $tmpdir = $c->getval('c_tmpdir');

$DRYRUN = $c->getval('c_dryrun');
@@ -121,16 +119,28 @@
if ($service)
{
$c->cprint("restarting service $service", 2);
- exec_initscript($c, $service, $command, 1)
- or $rval++;
+ unless ($DRYRUN)
+ {
+ exec_initscript($c, $service, $command, 1)
+ or $rval++;
+ }
}
else
{
$c->cprint("executing command $command", 2);
- exec_command($c, $command, 1)
- or $rval++;
+
+ # Work out what th command is vs arguments
+ $command =~ m/^([\S]+)(?:\s+(.*))?$/;
+ my ($cmd, $args) = ($1, $2);
+
+ simple_exec(exec => $cmd,
+ args => $args,
+ inert => 0,
+ quiet => 1,
+ c => $c,
+ merge_error => 1) or $rval++;
}
- $touch->touch(@{$rshash{$key}});
+ utime(time, time, @{$rshash{$key}});
}
}


Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemHarden.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemHarden.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemHarden.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -45,10 +45,12 @@
use Fcntl qw(:mode);

my @HARDEN;
+my $c;

sub system_harden
{
- my ($c, $root) = @_;
+ $c = shift;
+ my $root = shift;

my $rval = 0;
my $find_bin = $c->getval("find_bin");
@@ -58,18 +60,20 @@

unless ($c->check_exec($find_bin, $chmod_bin)) { return 1; }

+ $c->cprint(" searching for SUID/SGID files", 2);
+
find( { wanted => \&_find_wanted, no_chdir => 1 }, $overlay_root );

foreach my $file (@HARDEN)
{
next if $file =~ /^\Q$croot\E/;
- next if ( grep {/$file/} @{$c->getvals("privfiles")} );
+ next if ( grep {/$file/} @{$c->getvals("privfiles", 1)} );

$c->cprint("stripping suid/sgid bits from $file", 2);

next if ($c->getval('c_dryrun'));

- my $sb = stat($file);
+ my $sb = lstat($file);
my $result = chmod $sb->mode & ~(S_ISUID|S_ISGID), $file;

unless ($result == 1)
@@ -85,7 +89,7 @@
sub _find_wanted
{

- my $st = stat($_);
+ my $st = lstat($_);

# If the file isn't on the local filesystem, ignore it.
if (-d $_ and $st->dev != $File::Find::topdev)
@@ -94,8 +98,12 @@
return;
}

- # Need to test if it is a file first, otherwise $st->mode will be undef.
- if (-f $_ and ($st->mode & (S_ISUID|S_ISGID)))
+ # If its a link log a warning, else if its a file push it onto the list.
+ if (-l $_ and ($st->mode & (S_ISUID|S_ISGID)))
+ {
+ $c->cprint("skipping symlink ($_) found with SUID/SGID bit set", 2);
+ }
+ elsif (-f $_ and ($st->mode & (S_ISUID|S_ISGID)))
{
push @HARDEN, $_;
}

Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemInfo.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemInfo.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/SystemInfo.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -160,7 +160,7 @@
{
my $c = shift;
my $c_root = $c->getval('c_croot');
-
+ my $network_path = $c->getval('network_path') || 'network';
$c->print(3, 'examining local network');

# First lets get the IP address in DNS for our hostname.
@@ -184,15 +184,15 @@

# it will all fall apart if this in not there so lets
# make life easy for the user and let them know.
- if ( ! -d "${c_root}/network/" ) {
- $c->error("no \"$c_root/network\" config directory exists.", 'crit');
+ if ( ! -d "${c_root}/${network_path}/" ) {
+ $c->error("no \"$c_root/$network_path/\" config directory exists.", 'crit');
return PLUGIN_FATAL;
}

# Populate an ordered hierarchy of networks that our address is a member
# of

- foreach my $net (<${c_root}/network/*>)
+ foreach my $net (<${c_root}/${network_path}/*>)
{
next unless ($net !~ m/^(?:\d{1,3}\.){3}(?:\d{1,3})-\d{1,2}/);
$net = basename($net);
@@ -217,7 +217,7 @@

my $nobj = @nets[-1];
unless (ref($nobj) eq 'NetAddr::IP') {
- $c->error("unable to find a matching network within \"${c_root}/network/\"",
+ $c->error("unable to find a matching network within \"${c_root}/${network_path}/\"",
" for \"$c->{c_ip_address}\"",
'crit');
return PLUGIN_FATAL;
@@ -240,7 +240,7 @@
unless (defined $c->{c_subnet})
{
$c->error("error caculating subnet for \"$c->{c_ip_address}\" ".
- "using \"network/$nets[-1]\"", 'crit');
+ "using \"$network_path/$nets[-1]\"", 'crit');
return PLUGIN_FATAL;
}

@@ -507,7 +507,8 @@
}
else
{
- my @dmidecode_res = simple_exec(exec => 'dmidecode',
+ my @dmidecode_res = simple_exec(c => $c,
+ exec => 'dmidecode',
inert => 1);
return PLUGIN_FATAL unless ($? == 0);


Modified: spine/branches/spine_2_2-devel/lib/Spine/Plugin/Templates.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Plugin/Templates.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Plugin/Templates.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -124,8 +124,9 @@
}

# Pre-compile our regular expressions for templates to ignore
- if (defined($ignore) and scalar(@IGNORE) == 0) {
- @IGNORE = map qr/$_/o, @{$ignore};
+ if (defined($ignore) and scalar(@IGNORE) == 0)
+ {
+ @IGNORE = map qr/$_/, @{$ignore};
}
undef $ignore;

@@ -214,17 +215,13 @@
my $destdir;

# Create our template processing instance
- unless (defined($TT)) {
-
- #
- # NOTE!!
- #
+ unless (defined($TT))
+ {
# Do *NOT* under any circumstances add INTERPOLATE to the TT object
# instantiation. It blows up to all hell in all kinds of file formats,
# most notably /etc/bashrc.tt
#
# rtilder Thu Jan 11 12:04:08 PST 2007
- #
$TT = Template->new( { INCLUDE_PATH => $destdir,
EVAL_PERL => 1,
PRE_CHOMP => 1,
@@ -236,7 +233,8 @@

# If $output isn't a ref to a scalar then we output to a the template's
# full path name minus the ".tt" extension.
- unless (defined($output) and ref($output) eq 'SCALAR') {
+ unless (defined($output) and ref($output) eq 'SCALAR')
+ {
# Seems like a lot of work to get the full path and filename minus the
# '.tt' extension, but it should be 100% portable.
$destdir = dirname($template);
@@ -250,9 +248,13 @@
{
# If the user has decided they don't want the template
# from within the template we unlink (skip_template)
- if ($TT->error() =~ m/__SKIP__TEMPLATE__/) {
+ if ($TT->error() =~ m/__SKIP__TEMPLATE__/)
+ {
$c->cprint("Template has requested to be skipped, $template", 3);
- unlink($template);
+ if (! $QUICK)
+ {
+ unlink($template);
+ }
return PLUGIN_SUCCESS;
}

@@ -261,7 +263,10 @@
# from the overlay, and return PLUGIN_ERROR to move on instead
# of PLUGIN_FATAL and blowing up.
$c->error('could not process template: ' . $TT->error(), "err");
- unlink($template);
+ if (! $QUICK)
+ {
+ unlink($template);
+ }
return PLUGIN_ERROR;
}

@@ -284,22 +289,26 @@
{
my $c = shift;

- unless ($QUICK) {
+ unless ($QUICK)
+ {
return PLUGIN_SUCCESS;
}

# Make sure we don't save state
$::SAVE_STATE = 0;

- foreach my $template (@ARGV) {
+ foreach my $template (@ARGV)
+ {
my $output;

- unless (-f $template) {
+ unless (-f $template)
+ {
print "No such file \"$template\"\n";
next;
}

- unless (process_template($c, $template, \$output)) {
+ unless (process_template($c, $template, \$output))
+ {
$c->error("Failed to process template", 'err');
return PLUGIN_EXIT;
}

Modified: spine/branches/spine_2_2-devel/lib/Spine/Registry.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Registry.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Registry.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -163,7 +163,7 @@
}
}

- return SPINE_SUCCESS;
+ return $rc;
}



Modified: spine/branches/spine_2_2-devel/lib/Spine/Util.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Util.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Util.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -200,8 +200,10 @@
$tmpfh->close();
push @rsync_opts, "--exclude-from=$tmpfn"
}
-
+
+ my $inert = exists $args{Inert} ? $args{Inert} : 0;
my @result = simple_exec(c => $c,
+ inert => $inert,
exec => 'rsync',
merge_error => 1,
args => [@rsync_opts,
@@ -240,43 +242,21 @@
return 1;
}

-# wraper to Spine::Util::Exec::simple
+# wrapper to Spine::Util::Exec::simple
sub simple_exec {
return Spine::Util::Exec->simple(@_);
}

-# wraper to Spine::Util::Exec::new
+# wrapper to Spine::Util::Exec::new
sub create_exec {
return Spine::Util::Exec->new(@_);
}

-# wraper to Spine::Util::Exec::find_exec
+# wrapper to Spine::Util::Exec::find_exec
sub find_exec {
return Spine::Util::Exec->find_exec(@_);
}

-# DEPRECIATE: for support of old implementation (used in templates)
-sub exec_command {
- my ($c, $command, $report_error, $inert, $merror) = @_;
-
- # Work out what the command is vs arguments
- $command =~ m/^([\S]+)(?:\s+(.*))?$/;
- my ($cmd, $args) = ($1, $2);
-
- #TODO This should be uncommented in a few releases time
- #$c->error('use of depreciated "exec_command" please use "simple_exec"',
- # 'warning');
-
- return simple_exec(exec => $cmd,
- args => $args,
- inert => $inert,
- quiet => $report_error ? 0 : 1,
- c => $c,
- merge_error => defined $merror ? $merror : 1);
-
-}
-
-

sub octal_conv
{

Modified: spine/branches/spine_2_2-devel/lib/Spine/Util/Exec.pm
==============================================================================
--- spine/branches/spine_2_2-devel/lib/Spine/Util/Exec.pm Fri Nov 20 04:36:49 2009 (r303)
+++ spine/branches/spine_2_2-devel/lib/Spine/Util/Exec.pm Fri Nov 20 06:12:16 2009 (r304)
@@ -177,7 +177,7 @@
# can we run? if we are in dryrun and the command
# has not been described as inert then we will skip
# running.
- if ($self->{c}->getval('dryrun') &&
+ if ($self->{c}->getval('c_dryrun') &&
(! exists $self->{inert} ||
! $self->{inert} )) {
$self->{dryrun} = 1;
@@ -234,8 +234,13 @@
sub _readlines {
my $self = shift;
my $type = shift;
-
- return undef unless $self->{ready};
+
+ # If we are in dryrun we didn't run so just return undef.
+ # Also if we aren't ready yet, return undef.
+ if ( (exists $self->{dryrun} && $self->{dryrun}) || ! $self->{ready} )
+ {
+ return undef;
+ }

my @output = $self->{$type}->getlines();
if ($self->{$type}->error()) {

Copied and modified: spine/branches/spine_2_2-devel/spine-mgmt (from r254, spine/branches/spine_2_2-devel/spine-config)
==============================================================================
--- spine/branches/spine_2_2-devel/spine-config Wed Oct 7 07:29:53 2009 (r254, copy source)
+++ spine/branches/spine_2_2-devel/spine-mgmt Fri Nov 20 06:12:16 2009 (r304)
@@ -25,8 +25,8 @@
use strict;

# Allow users to override but putting at the end
-# rather then 'use lib q(/usr/lib/spine)'
-BEGIN { push @INC, q(/usr/lib/spine) }
+# rather then 'use lib q(/usr/lib/spine-mgmt)'
+BEGIN { push @INC, q(/usr/lib/spine-mgmt) }

my $perl_ver = sprintf "%vd", $^V;
my $error_count = 0;
@@ -44,26 +44,32 @@
use Spine::Util;
use POSIX qw(ctime);
use File::Spec::Functions;
+use Sys::Syslog;

use sigtrap 'handler' => \&ignore_signal, 'normal-signals';

use constant NODEFILE => '/etc/nodename';
-use constant LOCKFILE => '/var/run/spine.lock';
-use constant DEFAULT_CONFIGFILE => '/etc/spine-config.conf';
-use constant DEFAULT_CONFIGFILE_FALLBACK => '/etc/spine.conf';
+use constant LOCKFILE => '/var/run/spine-mgmt.lock';
+use constant DEFAULT_CONFIGFILE => '/etc/spine-mgmt/spine-mgmt.conf';
+use constant DEFAULT_CONFIGFILE_FALLBACK => ('/etc/spine-config.conf',\
+ '/etc/spine.conf');
use constant SPINE_PHASES => qw(PREPARE EMIT APPLY CLEAN);

use constant DEFAULT_CONFIG => {
spine => {
- StateDir => '/var/spine',
+ StateDir => '/var/spine-mgmt',
ConfigSource => 'ISO9660',
- Profile => 'StandardPlugins'
+ Profile => 'StandardPlugins',
+ Parser => 'pureTT',
+ SyslogIdent => 'spine-mgmt',
+ SyslogFacility => 'local3',
+ SyslogOptions => 'ndelay,pid',
},

DefaultPlugins => {
'DISCOVERY/populate' => 'DryRun SystemInfo',
'DISCOVERY/policy-selection' => 'DescendOrder',
- 'PARSE/complete' => 'Auth Interpolate',
+ 'PARSE/complete' => 'Interpolate',
},

FileSystem => {
@@ -72,24 +78,22 @@

ISO9660 => {
URL => 'http://repository/cgi-bin/rcrb.pl',
- Destination => '/var/spine/configballs',
+ Destination => '/var/spine-mgmt/configballs',
Timeout => 5
},

StandardPlugins => {
PREPARE => 'PrintData Templates Overlay',
- EMIT => 'Templates Auth',
- APPLY => 'Overlay RPMPackageManager TweakStartup'
- . ' RestartServices Finalize',
- CLEAN => 'Overlay RPMPackageManager SystemHarden'
+ EMIT => 'Templates',
+ APPLY => 'Overlay RestartServices Finalize',
+ CLEAN => 'Overlay'
},

FirstRun => {
- PREPARE => 'PrintData Overlay',
- EMIT => 'FirstRun Templates Auth',
- APPLY => 'Overlay RPMPackageManager TweakStartup'
- . ' Finalize',
- CLEAN => 'Overlay SystemHarden',
+ PREPARE => 'PrintData Templates Overlay',
+ EMIT => 'FirstRun Templates',
+ APPLY => 'Overlay Finalize',
+ CLEAN => 'Overlay',
}
};

@@ -125,49 +129,50 @@
#
Getopt::Long::Configure('pass_through');

-my $cfile = DEFAULT_CONFIGFILE;
-if (not -f $cfile)
-{
- $cfile = DEFAULT_CONFIGFILE_FALLBACK;
-}
-
my $profile = undef;
+my $conf_file = undef;
+my $quiet = undef;
my @actions = ();

-GetOptions('config-file=s' => \$cfile,
+GetOptions('config-file=s' => \$conf_file,
'action|plugin=s@' => \@actions,
+ 'quiet|q' => \$quiet,
'actiongroup|profile=s' => \$profile);

Getopt::Long::Configure('no_pass_through');

+my @cfiles = (DEFAULT_CONFIGFILE, DEFAULT_CONFIGFILE_FALLBACK);

-# Parse the config file
-$CONFIG = new Spine::ConfigFile(Filename => $cfile, Type => 'Ini');
-$CONFIG->{spine}->{Profile} = $profile if defined($profile);
+if (defined($conf_file))
+{
+ my @cfiles = ($conf_file);
+}

-if (not defined($CONFIG))
+foreach my $file (@cfiles)
{
- if ($cfile ne DEFAULT_CONFIGFILE)
+ if (-f $file)
{
- print STDERR $Spine::ConfigFile::ERROR;
- goto failure;
- }

- if (-f $cfile and (not -r $cfile))
- {
- print STDERR "Default config file $cfile exists but isn't readable.\n";
- goto failure;
+ print "spine-mgmt: Using config file at $file\n"
+ unless(defined($quiet));
+ $CONFIG = new Spine::ConfigFile(Filename => $file, Type => 'Ini');
+ if (not defined($CONFIG))
+ {
+ print STDERR $Spine::ConfigFile::ERROR;
+ goto failure;
+ }
+ last;
}
+}

- if (not -f DEFAULT_CONFIGFILE)
- {
- print STDERR "No config file found at default $cfile. "
- . "Using hardcoded defaults.\n";
-
- $CONFIG = DEFAULT_CONFIG;
- }
+if (not defined($CONFIG))
+{
+ print STDERR "spine-mgmt: No config file found. Using hardcoded defaults.\n";
+ $CONFIG = DEFAULT_CONFIG;
}

+$CONFIG->{spine}->{Profile} = $profile if defined($profile);
+

# Take care of our PluginPath if provided
if (defined($CONFIG->{spine}->{PluginPath}))
@@ -175,6 +180,18 @@
unshift @INC, split(/:/, $CONFIG->{spine}->{PluginPath});
}

+# Run openlog() once so any plugin can use it with the user-configured
+# facility, options, and program name (or the defaults).
+openlog($CONFIG->{spine}->{SyslogIdent} ?
+ $CONFIG->{spine}->{SyslogIdent} :
+ DEFAULT_CONFIG->{spine}->{SyslogIdent},
+ $CONFIG->{spine}->{SyslogFacility} ?
+ $CONFIG->{spine}->{SyslogFacility} :
+ DEFAULT_CONFIG->{spine}->{SyslogFacility},
+ $CONFIG->{spine}->{SyslogOptions} ?
+ $CONFIG->{spine}->{SyslogOptions} :
+ DEFAULT_CONFIG->{spine}->{SyslogOptions});
+
#
# If specific actions were requested, we don't use our profile,
# we build a new profile of just the actions the user wants.
@@ -360,7 +377,12 @@
}


-print 'spine_core: Using configuration: ', $source->source_info(), "\n";
+
+unless(defined($quiet))
+{
+ print 'spine-mgmt core: Using configuration: ',
+ $source->source_info(), "\n";
+}


# Determine the hostname.
@@ -391,16 +413,26 @@


# Announce what we're doing
-print 'spine: starting Spine v' . $VERSION . ' -- configuration release ',
- $source->release(), "\n";
-print "spine: initializing data for $hostname\n";
+unless(defined($quiet))
+{
+ print 'spine-mgmt: starting Spine v' . $VERSION .
+ ' -- configuration release ', $source->release(), "\n";
+
+ print "spine-mgmt: initializing data for $hostname\n";
+}
+
if ( ${%{$registry->get_options()}->{dryrun}} ) {
- print "spine: running in dryrun mode\n";
+ unless(defined($quiet))
+ {
+ print "spine-mgmt: running in dryrun mode\n";
+ }
+ syslog("info", "running in dryrun mode");
}

# Create the configuration object.
my $c = Spine::Data->new(hostname => $hostname,
verbosity => $verbosity,
+ quiet => $quiet,
source => $source,
release => $release,
config => $CONFIG);
@@ -409,7 +441,7 @@
#
# rtilder Tue Jun 27 12:23:39 PDT 2006
if (not defined($c)) {
- print STDERR 'spine initialization: Errors encountered parsing '
+ print STDERR 'spine-mgmt initialization: Errors encountered parsing '
. "data tree.\n";
goto failure;
}
@@ -418,7 +450,7 @@
# have had a critical parsing error.
if ($c->getval('c_failure'))
{
- print STDERR 'spine initialization: Errors encountered parsing '
+ print STDERR 'spine-mgmt initialization: Errors encountered parsing '
. "data tree.\n";
goto failure;
}
@@ -480,7 +512,8 @@
#
# rtilder Wed May 9 10:33:20 PDT 2007
#
- print STDOUT "\tAt least one plugin requested a clean exit.\n";
+ print STDOUT "\tAt least one plugin requested a clean exit.\n"
+ unless(defined($quiet));
last PHASE;
}
}
@@ -491,7 +524,10 @@
if ($SAVE_STATE)
{
# Store our config object to disk.
- print STDERR "Saving state...\n";
+ unless(defined($quiet))
+ {
+ print STDERR "Saving state...\n";
+ }
unless ($state->store())
{
$c->error('failed to write session object [' . $state->error . ']',
@@ -516,8 +552,17 @@
}
}

+# Figure out if we had lame keys and report the number.
+if ( defined $c->{c_lame_keys} )
+{
+ my $size = keys %{$c->{c_lame_keys}};
+ print "spine-mgmt: Encountered $size keys with lame TT syntax!\n"
+ unless(defined($quiet));
+}

finished:
+# Close syslog
+closelog();
# Release our exclusive lock and exit.
release_lock();
if ($error_count)
@@ -527,6 +572,8 @@
exit(0);

failure:
+# Close syslog
+closelog();
release_lock();
exit(1);

@@ -857,7 +904,7 @@
{
print STDERR (<<EOF);
Spine v$VERSION -- Configuration management system.
-Usage: spine [options]
+Usage: spine-mgmt [options]

--action <action>
Run the specified action(s). Actions are defined
@@ -873,7 +920,7 @@
--croot <directory>
Location of the configuration hierarchy.
By default, this path will be relative
- to the spine executable in config/.
+ to the spine-mgmt executable in config/.

--autofqdn
Attempt to determine the FQDN. Use this
@@ -913,7 +960,7 @@

--config-file <file>
The configuration file to use for this script.
- The default is /etc/spine.conf.
+ The default is /etc/spine-mgmt/spine-mgmt.conf.

--config-source <configuration source type>
The type of configuration source to use. Defined by
@@ -941,9 +988,9 @@

Examples:

- spine --profile apply_auth
- spine --action apply_overlay --action process_templates
- spine --croot /tmp/testconfig --hostname some.host.name.tld
+ spine-mgmt --profile apply_auth
+ spine-mgmt --action apply_overlay --action process_templates
+ spine-mgmt --croot /tmp/testconfig --hostname some.host.name.tld

Notes:


Copied and modified: spine/branches/spine_2_2-devel/spine-mgmt.conf (from r254, spine/branches/spine_2_2-devel/spine-config.conf)
==============================================================================
--- spine/branches/spine_2_2-devel/spine-config.conf Wed Oct 7 07:29:53 2009 (r254, copy source)
+++ spine/branches/spine_2_2-devel/spine-mgmt.conf Fri Nov 20 06:12:16 2009 (r304)
@@ -1,52 +1,99 @@
[spine]
ConfigSource = ISO9660
-StateDir = /var/spine
+StateDir = /var/spine-mgmt
Profile = StandardPlugins
+SyslogIdent = spine
+SyslogFacility = local3
+SyslogOptions = ndelay,pid

[ISO9660]
URL = http://repository/cgi-bin/rrcb.pl
-Destination = /var/spine/configballs
+Destination = /var/spine-mgmt/configballs
Timeout = 5

[DefaultPlugins]
DISCOVERY/populate = DryRun SystemInfo
DISCOVERY/policy-selection = DescendOrder
-PARSE/complete = Auth Interpolate
+PARSE/complete = Interpolate
PARSE/key = Parselet::Basic Parselet::Complex Parselet::Operator Parselet::Dynamic Templates
PARSE/key/line = Parselet::Operator
PARSE/key/complex = Parselet::JSON Parselet::YAML
PARSE/key/dynamic = Parselet::DNS

+# Basic safe run
[StandardPlugins]
#
# Templates here is for quicktemplate functionality
#
PREPARE = PrintData Templates Overlay
+EMIT = Templates
+APPLY = Overlay RestartServices Finalize
+CLEAN = Overlay
+
+#
+# Full profile with APT and all the features enabled
+#
+[FullWithAPT]
+DISCOVERY/populate = DryRun SystemInfo
+DISCOVERY/policy-selection = DescendOrder
+PARSE/complete = Auth Interpolate
+PREPARE = PrintData Templates Overlay
EMIT = Templates Auth
-APPLY = Overlay RPMPackageManager TweakStartup RestartServices Finalize
-CLEAN = Overlay RPMPackageManager SystemHarden
+APPLY = Overlay RPMPackageManager Overlay SystemHarden TweakStartup RestartServices Finalize
+CLEAN = Overlay RPMPackageManager

#
# The only difference between the StandardPlugins profile and the FirstBoot
# profile is that FirstBoot doesn't restart any services or delete any packages
#
[FirstBoot]
-PREPARE = PrintData Overlay
-EMIT = FirstRun Templates Auth
-APPLY = Overlay RPMPackageManager TweakStartup Finalize
-CLEAN = Overlay SystemHarden
+PREPARE = PrintData Templates Overlay
+EMIT = FirstRun Templates
+APPLY = Overlay Finalize
+CLEAN = Overlay

#
-# Actions
+# First boot profile that corresponds to the Full profile above
#
-[action_build_auth]
-EMIT = Auth
+[FirstBootFullWithAPT]
+DISCOVERY/populate = DryRun SystemInfo
+DISCOVERY/policy-selection = DescendOrder
+PARSE/complete = Auth Interpolate
+PREPARE = PrintData Templates Overlay
+EMIT = Templates Auth
+APPLY = Overlay RPMPackageManager Overlay SystemHarden TweakStartup Finalize
+CLEAN = Overlay

-[action_apply_auth]
-EMIT = Auth
-APPLY = Overlay
+#
+# Full profile with new PackageManager and all the features enabled
+#
+[FullWithPKGMGR]
+DISCOVERY/populate = DryRun SystemInfo
+DISCOVERY/policy-selection = DescendOrder
+PARSE/complete = Auth Interpolate PackageManager
+PARSE/initialize = PackageManager
+PREPARE = PrintData Templates Overlay
+EMIT = Templates Auth
+APPLY = Overlay PackageManager Overlay SystemHarden TweakStartup RestartServices Finalize
+CLEAN = Overlay PackageManager
+
+#
+# First boot profile that corresponds to the Full profile above
+#
+[FirstBootFullWithPKGMGR]
+DISCOVERY/populate = DryRun SystemInfo
+DISCOVERY/policy-selection = DescendOrder
+PARSE/complete = Auth Interpolate PackageManager
+PARSE/initialize = PackageManager
+PREPARE = PrintData Templates Overlay
+EMIT = Templates Auth
+APPLY = Overlay PackageManager Overlay SystemHarden TweakStartup Finalize
CLEAN = Overlay

+
+#
+# Actions
+#
[action_build_overlay]
PREPARE = Overlay

Reply all
Reply to author
Forward
0 new messages