dos2unx
This commit is contained in:
parent
ca72570d12
commit
25296801b6
78
slack-dist/dist/Makefile
vendored
78
slack-dist/dist/Makefile
vendored
@ -1,39 +1,39 @@
|
|||||||
# Makefile for slack/src
|
# Makefile for slack/src
|
||||||
# $Id: Makefile 187 2008-03-03 02:00:18Z alan $
|
# $Id: Makefile 187 2008-03-03 02:00:18Z alan $
|
||||||
include Makefile.common
|
include Makefile.common
|
||||||
|
|
||||||
BACKENDS = slack-getroles slack-installfiles slack-runscript slack-sync slack-stage slack-rolediff
|
BACKENDS = slack-getroles slack-installfiles slack-runscript slack-sync slack-stage slack-rolediff
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|
||||||
install: install-bin install-conf install-lib install-man
|
install: install-bin install-conf install-lib install-man
|
||||||
|
|
||||||
install-bin: all
|
install-bin: all
|
||||||
$(MKDIR) $(DESTDIR)$(sbindir)
|
$(MKDIR) $(DESTDIR)$(sbindir)
|
||||||
$(INSTALL) slack $(DESTDIR)$(sbindir)
|
$(INSTALL) slack $(DESTDIR)$(sbindir)
|
||||||
$(MKDIR) $(DESTDIR)$(bindir)
|
$(MKDIR) $(DESTDIR)$(bindir)
|
||||||
$(INSTALL) slack-diff $(DESTDIR)$(bindir)
|
$(INSTALL) slack-diff $(DESTDIR)$(bindir)
|
||||||
$(MKDIR) $(DESTDIR)$(slack_libexecdir)
|
$(MKDIR) $(DESTDIR)$(slack_libexecdir)
|
||||||
@set -ex;\
|
@set -ex;\
|
||||||
for i in $(BACKENDS); do \
|
for i in $(BACKENDS); do \
|
||||||
$(INSTALL) $$i $(DESTDIR)$(slack_libexecdir); done
|
$(INSTALL) $$i $(DESTDIR)$(slack_libexecdir); done
|
||||||
$(INSTALL) -d -m $(PRIVDIRMODE) $(DESTDIR)$(slack_localstatedir)
|
$(INSTALL) -d -m $(PRIVDIRMODE) $(DESTDIR)$(slack_localstatedir)
|
||||||
$(INSTALL) -d -m $(PRIVDIRMODE) $(DESTDIR)$(slack_localcachedir)
|
$(INSTALL) -d -m $(PRIVDIRMODE) $(DESTDIR)$(slack_localcachedir)
|
||||||
|
|
||||||
install-conf: all
|
install-conf: all
|
||||||
$(MKDIR) $(DESTDIR)$(sysconfdir)
|
$(MKDIR) $(DESTDIR)$(sysconfdir)
|
||||||
$(INSTALL) -m 0644 slack.conf $(DESTDIR)$(sysconfdir)
|
$(INSTALL) -m 0644 slack.conf $(DESTDIR)$(sysconfdir)
|
||||||
|
|
||||||
install-lib: all
|
install-lib: all
|
||||||
$(MKDIR) $(DESTDIR)$(slack_libdir)
|
$(MKDIR) $(DESTDIR)$(slack_libdir)
|
||||||
$(INSTALL) -m 0644 Slack.pm $(DESTDIR)$(slack_libdir)
|
$(INSTALL) -m 0644 Slack.pm $(DESTDIR)$(slack_libdir)
|
||||||
|
|
||||||
install-man: all
|
install-man: all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
||||||
realclean: clean
|
realclean: clean
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
54
slack-dist/dist/Makefile.common
vendored
54
slack-dist/dist/Makefile.common
vendored
@ -1,27 +1,27 @@
|
|||||||
# Common code included in every Makefile
|
# Common code included in every Makefile
|
||||||
# $Id: Makefile.common 189 2008-04-21 00:52:56Z sundell $
|
# $Id: Makefile.common 189 2008-04-21 00:52:56Z sundell $
|
||||||
|
|
||||||
PACKAGE=slack
|
PACKAGE=slack
|
||||||
VERSION=0.15.2
|
VERSION=0.15.2
|
||||||
|
|
||||||
DESTDIR =
|
DESTDIR =
|
||||||
|
|
||||||
prefix = /
|
prefix = /
|
||||||
exec_prefix = /usr
|
exec_prefix = /usr
|
||||||
sysconfdir = ${prefix}/etc
|
sysconfdir = ${prefix}/etc
|
||||||
mandir = ${exec_prefix}/share/man
|
mandir = ${exec_prefix}/share/man
|
||||||
bindir = ${exec_prefix}/bin
|
bindir = ${exec_prefix}/bin
|
||||||
sbindir = ${exec_prefix}/sbin
|
sbindir = ${exec_prefix}/sbin
|
||||||
libdir = ${exec_prefix}/lib
|
libdir = ${exec_prefix}/lib
|
||||||
libexecdir = ${exec_prefix}/lib
|
libexecdir = ${exec_prefix}/lib
|
||||||
localstatedir = ${prefix}/var
|
localstatedir = ${prefix}/var
|
||||||
|
|
||||||
slack_libdir = ${libdir}/slack
|
slack_libdir = ${libdir}/slack
|
||||||
slack_libexecdir = ${libexecdir}/slack
|
slack_libexecdir = ${libexecdir}/slack
|
||||||
slack_localstatedir = ${localstatedir}/lib/slack
|
slack_localstatedir = ${localstatedir}/lib/slack
|
||||||
slack_localcachedir = ${localstatedir}/cache/slack
|
slack_localcachedir = ${localstatedir}/cache/slack
|
||||||
|
|
||||||
INSTALL = install
|
INSTALL = install
|
||||||
MKDIR = mkdir -p
|
MKDIR = mkdir -p
|
||||||
|
|
||||||
PRIVDIRMODE = 0700
|
PRIVDIRMODE = 0700
|
||||||
|
742
slack-dist/dist/Slack.pm
vendored
742
slack-dist/dist/Slack.pm
vendored
@ -1,371 +1,371 @@
|
|||||||
# $Id: Slack.pm 189 2008-04-21 00:52:56Z sundell $
|
# $Id: Slack.pm 189 2008-04-21 00:52:56Z sundell $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
|
|
||||||
package Slack;
|
package Slack;
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use strict;
|
use strict;
|
||||||
use Carp qw(cluck confess croak);
|
use Carp qw(cluck confess croak);
|
||||||
use File::Find;
|
use File::Find;
|
||||||
use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG);
|
use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG);
|
||||||
|
|
||||||
use base qw(Exporter);
|
use base qw(Exporter);
|
||||||
use vars qw($VERSION @EXPORT @EXPORT_OK $DEFAULT_CONFIG_FILE);
|
use vars qw($VERSION @EXPORT @EXPORT_OK $DEFAULT_CONFIG_FILE);
|
||||||
$VERSION = '0.15.2';
|
$VERSION = '0.15.2';
|
||||||
@EXPORT = qw();
|
@EXPORT = qw();
|
||||||
@EXPORT_OK = qw();
|
@EXPORT_OK = qw();
|
||||||
|
|
||||||
$DEFAULT_CONFIG_FILE = '/etc/slack.conf';
|
$DEFAULT_CONFIG_FILE = '/etc/slack.conf';
|
||||||
|
|
||||||
my $term;
|
my $term;
|
||||||
|
|
||||||
my @default_options = (
|
my @default_options = (
|
||||||
'help|h|?',
|
'help|h|?',
|
||||||
'version',
|
'version',
|
||||||
'verbose|v+',
|
'verbose|v+',
|
||||||
'quiet',
|
'quiet',
|
||||||
'config|C=s',
|
'config|C=s',
|
||||||
'source|s=s',
|
'source|s=s',
|
||||||
'rsh|e=s',
|
'rsh|e=s',
|
||||||
'cache|c=s',
|
'cache|c=s',
|
||||||
'stage|t=s',
|
'stage|t=s',
|
||||||
'root|r=s',
|
'root|r=s',
|
||||||
'dry-run|n',
|
'dry-run|n',
|
||||||
'backup|b',
|
'backup|b',
|
||||||
'backup-dir=s',
|
'backup-dir=s',
|
||||||
'hostname|H=s',
|
'hostname|H=s',
|
||||||
);
|
);
|
||||||
|
|
||||||
sub default_usage ($) {
|
sub default_usage ($) {
|
||||||
my ($synopsis) = @_;
|
my ($synopsis) = @_;
|
||||||
return <<EOF;
|
return <<EOF;
|
||||||
Usage: $synopsis
|
Usage: $synopsis
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h, -?, --help
|
-h, -?, --help
|
||||||
Print this help message and exit.
|
Print this help message and exit.
|
||||||
|
|
||||||
--version
|
--version
|
||||||
Print the version number and exit.
|
Print the version number and exit.
|
||||||
|
|
||||||
-v, --verbose
|
-v, --verbose
|
||||||
Be verbose.
|
Be verbose.
|
||||||
|
|
||||||
--quiet
|
--quiet
|
||||||
Don't be verbose (Overrides previous uses of --verbose)
|
Don't be verbose (Overrides previous uses of --verbose)
|
||||||
|
|
||||||
-C, --config FILE
|
-C, --config FILE
|
||||||
Use this config file instead of '$DEFAULT_CONFIG_FILE'.
|
Use this config file instead of '$DEFAULT_CONFIG_FILE'.
|
||||||
|
|
||||||
-s, --source DIR
|
-s, --source DIR
|
||||||
Source for slack files
|
Source for slack files
|
||||||
|
|
||||||
-e, --rsh COMMAND
|
-e, --rsh COMMAND
|
||||||
Remote shell for rsync
|
Remote shell for rsync
|
||||||
|
|
||||||
-c, --cache DIR
|
-c, --cache DIR
|
||||||
Local cache directory for slack files
|
Local cache directory for slack files
|
||||||
|
|
||||||
-t, --stage DIR
|
-t, --stage DIR
|
||||||
Local staging directory for slack files
|
Local staging directory for slack files
|
||||||
|
|
||||||
-r, --root DIR
|
-r, --root DIR
|
||||||
Root destination for slack files
|
Root destination for slack files
|
||||||
|
|
||||||
-n, --dry-run
|
-n, --dry-run
|
||||||
Don't write any files to disk -- just report what would have been done.
|
Don't write any files to disk -- just report what would have been done.
|
||||||
|
|
||||||
-b, --backup
|
-b, --backup
|
||||||
Make backups of existing files in ROOT that are overwritten.
|
Make backups of existing files in ROOT that are overwritten.
|
||||||
|
|
||||||
--backup-dir DIR
|
--backup-dir DIR
|
||||||
Put backups into this directory.
|
Put backups into this directory.
|
||||||
|
|
||||||
-H, --hostname HOST
|
-H, --hostname HOST
|
||||||
Pretend to be running on HOST, instead of the name given by
|
Pretend to be running on HOST, instead of the name given by
|
||||||
gethostname(2).
|
gethostname(2).
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
# Read options from a config file. Arguments:
|
# Read options from a config file. Arguments:
|
||||||
# file => config file to read
|
# file => config file to read
|
||||||
# opthash => hashref in which to store the options
|
# opthash => hashref in which to store the options
|
||||||
# verbose => whether to be verbose
|
# verbose => whether to be verbose
|
||||||
sub read_config (%) {
|
sub read_config (%) {
|
||||||
my %arg = @_;
|
my %arg = @_;
|
||||||
my ($config_fh);
|
my ($config_fh);
|
||||||
local $_;
|
local $_;
|
||||||
|
|
||||||
confess "Slack::read_config: no config file given"
|
confess "Slack::read_config: no config file given"
|
||||||
if not defined $arg{file};
|
if not defined $arg{file};
|
||||||
$arg{opthash} = {}
|
$arg{opthash} = {}
|
||||||
if not defined $arg{opthash};
|
if not defined $arg{opthash};
|
||||||
|
|
||||||
open($config_fh, '<', $arg{file})
|
open($config_fh, '<', $arg{file})
|
||||||
or confess "Could not open config file '$arg{file}': $!";
|
or confess "Could not open config file '$arg{file}': $!";
|
||||||
|
|
||||||
# Make this into a hash so we can quickly see if we're looking
|
# Make this into a hash so we can quickly see if we're looking
|
||||||
# for a particular option
|
# for a particular option
|
||||||
my %looking_for;
|
my %looking_for;
|
||||||
if (ref $arg{options} eq 'ARRAY') {
|
if (ref $arg{options} eq 'ARRAY') {
|
||||||
%looking_for = map { $_ => 1 } @{$arg{options}};
|
%looking_for = map { $_ => 1 } @{$arg{options}};
|
||||||
}
|
}
|
||||||
|
|
||||||
while(<$config_fh>) {
|
while(<$config_fh>) {
|
||||||
chomp;
|
chomp;
|
||||||
s/#.*//; # delete comments
|
s/#.*//; # delete comments
|
||||||
s/\s+$//; # delete trailing spaces
|
s/\s+$//; # delete trailing spaces
|
||||||
next if m/^$/; # skip empty lines
|
next if m/^$/; # skip empty lines
|
||||||
|
|
||||||
if (m/^[A-Z_]+=\S+/) {
|
if (m/^[A-Z_]+=\S+/) {
|
||||||
my ($key, $value) = split(/=/, $_, 2);
|
my ($key, $value) = split(/=/, $_, 2);
|
||||||
$key =~ tr/A-Z_/a-z-/;
|
$key =~ tr/A-Z_/a-z-/;
|
||||||
# Only set options we're looking for
|
# Only set options we're looking for
|
||||||
next if (%looking_for and not $looking_for{$key});
|
next if (%looking_for and not $looking_for{$key});
|
||||||
# Don't set options that are already set
|
# Don't set options that are already set
|
||||||
next if defined $arg{opthash}->{$key};
|
next if defined $arg{opthash}->{$key};
|
||||||
|
|
||||||
$arg{verbose} and print STDERR "Slack::read_config: Setting '$key' to '$value'\n";
|
$arg{verbose} and print STDERR "Slack::read_config: Setting '$key' to '$value'\n";
|
||||||
$arg{opthash}->{$key} = $value;
|
$arg{opthash}->{$key} = $value;
|
||||||
} else {
|
} else {
|
||||||
cluck "Slack::read_config: Garbage line '$_' in '$arg{file}' line $. ignored";
|
cluck "Slack::read_config: Garbage line '$_' in '$arg{file}' line $. ignored";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close($config_fh)
|
close($config_fh)
|
||||||
or confess "Slack::read_config: Could not close config file: $!";
|
or confess "Slack::read_config: Could not close config file: $!";
|
||||||
|
|
||||||
# The verbose option is treated specially in so many places that
|
# The verbose option is treated specially in so many places that
|
||||||
# we need to make sure it's defined.
|
# we need to make sure it's defined.
|
||||||
$arg{opthash}->{verbose} ||= 0;
|
$arg{opthash}->{verbose} ||= 0;
|
||||||
|
|
||||||
return $arg{opthash};
|
return $arg{opthash};
|
||||||
}
|
}
|
||||||
|
|
||||||
# Just get the exit code from a command that failed.
|
# Just get the exit code from a command that failed.
|
||||||
# croaks if anything weird happened.
|
# croaks if anything weird happened.
|
||||||
sub get_system_exit (@) {
|
sub get_system_exit (@) {
|
||||||
my @command = @_;
|
my @command = @_;
|
||||||
|
|
||||||
if (WIFEXITED($?)) {
|
if (WIFEXITED($?)) {
|
||||||
my $exit = WEXITSTATUS($?);
|
my $exit = WEXITSTATUS($?);
|
||||||
return $exit if $exit;
|
return $exit if $exit;
|
||||||
}
|
}
|
||||||
if (WIFSIGNALED($?)) {
|
if (WIFSIGNALED($?)) {
|
||||||
my $sig = WTERMSIG($?);
|
my $sig = WTERMSIG($?);
|
||||||
croak "'@command' caught sig $sig";
|
croak "'@command' caught sig $sig";
|
||||||
}
|
}
|
||||||
if ($!) {
|
if ($!) {
|
||||||
croak "Syserr on system '@command': $!";
|
croak "Syserr on system '@command': $!";
|
||||||
}
|
}
|
||||||
croak "Unknown error on '@command'";
|
croak "Unknown error on '@command'";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_system_exit (@) {
|
sub check_system_exit (@) {
|
||||||
my @command = @_;
|
my @command = @_;
|
||||||
my $exit = get_system_exit(@command);
|
my $exit = get_system_exit(@command);
|
||||||
# Exit is non-zero if get_system_exit() didn't croak.
|
# Exit is non-zero if get_system_exit() didn't croak.
|
||||||
croak "'@command' exited $exit";
|
croak "'@command' exited $exit";
|
||||||
}
|
}
|
||||||
|
|
||||||
# get options from the command line and the config file
|
# get options from the command line and the config file
|
||||||
# Arguments
|
# Arguments
|
||||||
# opthash => hashref in which to store options
|
# opthash => hashref in which to store options
|
||||||
# usage => usage statement
|
# usage => usage statement
|
||||||
# required_options => arrayref of options to require -- an exception
|
# required_options => arrayref of options to require -- an exception
|
||||||
# will be thrown if these options are not defined
|
# will be thrown if these options are not defined
|
||||||
# command_line_hash => store options specified on the command line here
|
# command_line_hash => store options specified on the command line here
|
||||||
sub get_options {
|
sub get_options {
|
||||||
my %arg = @_;
|
my %arg = @_;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
Getopt::Long::Configure('bundling');
|
Getopt::Long::Configure('bundling');
|
||||||
|
|
||||||
if (not defined $arg{opthash}) {
|
if (not defined $arg{opthash}) {
|
||||||
$arg{opthash} = {};
|
$arg{opthash} = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not defined $arg{usage}) {
|
if (not defined $arg{usage}) {
|
||||||
$arg{usage} = default_usage($0);
|
$arg{usage} = default_usage($0);
|
||||||
}
|
}
|
||||||
|
|
||||||
my @extra_options = (); # extra arguments to getoptions
|
my @extra_options = (); # extra arguments to getoptions
|
||||||
if (defined $arg{command_line_options}) {
|
if (defined $arg{command_line_options}) {
|
||||||
@extra_options = @{$arg{command_line_options}};
|
@extra_options = @{$arg{command_line_options}};
|
||||||
}
|
}
|
||||||
|
|
||||||
# Make a --quiet function that turns off verbosity
|
# Make a --quiet function that turns off verbosity
|
||||||
$arg{opthash}->{quiet} = sub { $arg{opthash}->{verbose} = 0; };
|
$arg{opthash}->{quiet} = sub { $arg{opthash}->{verbose} = 0; };
|
||||||
|
|
||||||
unless (GetOptions($arg{opthash},
|
unless (GetOptions($arg{opthash},
|
||||||
@default_options,
|
@default_options,
|
||||||
@extra_options,
|
@extra_options,
|
||||||
)) {
|
)) {
|
||||||
print STDERR $arg{usage};
|
print STDERR $arg{usage};
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
if ($arg{opthash}->{help}) {
|
if ($arg{opthash}->{help}) {
|
||||||
print $arg{usage};
|
print $arg{usage};
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($arg{opthash}->{version}) {
|
if ($arg{opthash}->{version}) {
|
||||||
print "slack version $VERSION\n";
|
print "slack version $VERSION\n";
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get rid of the quiet handler
|
# Get rid of the quiet handler
|
||||||
delete $arg{opthash}->{quiet};
|
delete $arg{opthash}->{quiet};
|
||||||
|
|
||||||
# If we've been given a hashref, save our options there at this
|
# If we've been given a hashref, save our options there at this
|
||||||
# stage, so the caller can see what was passed on the command line.
|
# stage, so the caller can see what was passed on the command line.
|
||||||
# Unfortunately, perl has no .replace function, so we iterate.
|
# Unfortunately, perl has no .replace function, so we iterate.
|
||||||
if (ref $arg{command_line_hash} eq 'HASH') {
|
if (ref $arg{command_line_hash} eq 'HASH') {
|
||||||
while (my ($k, $v) = each %{$arg{opthash}}) {
|
while (my ($k, $v) = each %{$arg{opthash}}) {
|
||||||
$arg{command_line_hash}->{$k} = $v;
|
$arg{command_line_hash}->{$k} = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use the default config file
|
# Use the default config file
|
||||||
if (not defined $arg{opthash}->{config}) {
|
if (not defined $arg{opthash}->{config}) {
|
||||||
$arg{opthash}->{config} = $DEFAULT_CONFIG_FILE;
|
$arg{opthash}->{config} = $DEFAULT_CONFIG_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
# We need to decide whether to be verbose about reading the config file
|
# We need to decide whether to be verbose about reading the config file
|
||||||
# Currently we just do it if global verbosity > 2
|
# Currently we just do it if global verbosity > 2
|
||||||
my $verbose_config = 0;
|
my $verbose_config = 0;
|
||||||
if (defined $arg{opthash}->{verbose}
|
if (defined $arg{opthash}->{verbose}
|
||||||
and $arg{opthash}->{verbose} > 2) {
|
and $arg{opthash}->{verbose} > 2) {
|
||||||
$verbose_config = 1;
|
$verbose_config = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read options from the config file, passing along the options we've
|
# Read options from the config file, passing along the options we've
|
||||||
# gotten so far
|
# gotten so far
|
||||||
read_config(
|
read_config(
|
||||||
file => $arg{opthash}->{config},
|
file => $arg{opthash}->{config},
|
||||||
opthash => $arg{opthash},
|
opthash => $arg{opthash},
|
||||||
verbose => $verbose_config,
|
verbose => $verbose_config,
|
||||||
);
|
);
|
||||||
|
|
||||||
# The "verbose" option gets compared a lot and needs to be defined
|
# The "verbose" option gets compared a lot and needs to be defined
|
||||||
$arg{opthash}->{verbose} ||= 0;
|
$arg{opthash}->{verbose} ||= 0;
|
||||||
|
|
||||||
# The "hostname" option is set specially if it's not defined
|
# The "hostname" option is set specially if it's not defined
|
||||||
if (not defined $arg{opthash}->{hostname}) {
|
if (not defined $arg{opthash}->{hostname}) {
|
||||||
use Sys::Hostname;
|
use Sys::Hostname;
|
||||||
$arg{opthash}->{hostname} = hostname;
|
$arg{opthash}->{hostname} = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
# We can require some options to be set
|
# We can require some options to be set
|
||||||
if (ref $arg{required_options} eq 'ARRAY') {
|
if (ref $arg{required_options} eq 'ARRAY') {
|
||||||
for my $option (@{$arg{required_options}}) {
|
for my $option (@{$arg{required_options}}) {
|
||||||
if (not defined $arg{opthash}->{$option}) {
|
if (not defined $arg{opthash}->{$option}) {
|
||||||
croak "Required option '$option' not given on command line or specified in config file!\n";
|
croak "Required option '$option' not given on command line or specified in config file!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $arg{opthash};
|
return $arg{opthash};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub prompt ($) {
|
sub prompt ($) {
|
||||||
my ($prompt) = @_;
|
my ($prompt) = @_;
|
||||||
if (not defined $term) {
|
if (not defined $term) {
|
||||||
require Term::ReadLine;
|
require Term::ReadLine;
|
||||||
$term = new Term::ReadLine 'slack'
|
$term = new Term::ReadLine 'slack'
|
||||||
}
|
}
|
||||||
|
|
||||||
$term->readline($prompt);
|
$term->readline($prompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Calls the callback on absolute pathnames of files in the source directory,
|
# Calls the callback on absolute pathnames of files in the source directory,
|
||||||
# and also on names of directories that don't exist in the destination
|
# and also on names of directories that don't exist in the destination
|
||||||
# directory (i.e. where $source/foo exists but $destination/foo does not).
|
# directory (i.e. where $source/foo exists but $destination/foo does not).
|
||||||
sub find_files_to_install ($$$) {
|
sub find_files_to_install ($$$) {
|
||||||
my ($source, $destination, $callback) = @_;
|
my ($source, $destination, $callback) = @_;
|
||||||
return find ({
|
return find ({
|
||||||
wanted => sub {
|
wanted => sub {
|
||||||
if (-l or not -d _) {
|
if (-l or not -d _) {
|
||||||
# Copy all files, links, etc
|
# Copy all files, links, etc
|
||||||
my $file = $File::Find::name;
|
my $file = $File::Find::name;
|
||||||
&$callback($file);
|
&$callback($file);
|
||||||
} elsif (-d _) {
|
} elsif (-d _) {
|
||||||
# For directories, we only want to copy it if it doesn't
|
# For directories, we only want to copy it if it doesn't
|
||||||
# exist in the destination yet.
|
# exist in the destination yet.
|
||||||
my $dir = $File::Find::name;
|
my $dir = $File::Find::name;
|
||||||
# We know the root directory will exist (we make it above),
|
# We know the root directory will exist (we make it above),
|
||||||
# so skip the base of the source
|
# so skip the base of the source
|
||||||
(my $short_source = $source) =~ s#/$##;
|
(my $short_source = $source) =~ s#/$##;
|
||||||
return if $dir eq $short_source;
|
return if $dir eq $short_source;
|
||||||
|
|
||||||
# Strip the $source from the path,
|
# Strip the $source from the path,
|
||||||
# so we can build the destination dir from it.
|
# so we can build the destination dir from it.
|
||||||
my $subdir = $dir;
|
my $subdir = $dir;
|
||||||
($subdir =~ s#^$source##)
|
($subdir =~ s#^$source##)
|
||||||
or croak "sub failed: $source|$subdir";
|
or croak "sub failed: $source|$subdir";
|
||||||
|
|
||||||
if (not -d "$destination/$subdir") {
|
if (not -d "$destination/$subdir") {
|
||||||
&$callback($dir);
|
&$callback($dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
$source,
|
$source,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Runs rsync with the necessary redirection to its filehandles
|
# Runs rsync with the necessary redirection to its filehandles
|
||||||
sub wrap_rsync (@) {
|
sub wrap_rsync (@) {
|
||||||
my @command = @_;
|
my @command = @_;
|
||||||
my ($pid);
|
my ($pid);
|
||||||
|
|
||||||
if ($pid = fork) {
|
if ($pid = fork) {
|
||||||
# Parent
|
# Parent
|
||||||
} elsif (defined $pid) {
|
} elsif (defined $pid) {
|
||||||
# Child
|
# Child
|
||||||
open(STDIN, "<", "/dev/null")
|
open(STDIN, "<", "/dev/null")
|
||||||
or die "Could not redirect STDIN from /dev/null\n";
|
or die "Could not redirect STDIN from /dev/null\n";
|
||||||
# This redirection is necessary because rsync sends
|
# This redirection is necessary because rsync sends
|
||||||
# verbose output to STDOUT
|
# verbose output to STDOUT
|
||||||
open(STDOUT, ">&STDERR")
|
open(STDOUT, ">&STDERR")
|
||||||
or die "Could not redirect STDOUT to STDERR\n";
|
or die "Could not redirect STDOUT to STDERR\n";
|
||||||
exec(@command);
|
exec(@command);
|
||||||
die "Could not exec '@command': $!\n";
|
die "Could not exec '@command': $!\n";
|
||||||
} else {
|
} else {
|
||||||
die "Could not fork: $!\n";
|
die "Could not fork: $!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $kid = waitpid($pid, 0);
|
my $kid = waitpid($pid, 0);
|
||||||
if ($kid != $pid) {
|
if ($kid != $pid) {
|
||||||
die "waitpid returned $kid\n";
|
die "waitpid returned $kid\n";
|
||||||
} elsif ($?) {
|
} elsif ($?) {
|
||||||
Slack::check_system_exit(@command);
|
Slack::check_system_exit(@command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Runs rsync with the necessary redirection to its filehandles, but also
|
# Runs rsync with the necessary redirection to its filehandles, but also
|
||||||
# returns an FH to stdin and a PID.
|
# returns an FH to stdin and a PID.
|
||||||
sub wrap_rsync_fh (@) {
|
sub wrap_rsync_fh (@) {
|
||||||
my @command = @_;
|
my @command = @_;
|
||||||
my ($fh, $pid);
|
my ($fh, $pid);
|
||||||
|
|
||||||
if ($pid = open($fh, "|-")) {
|
if ($pid = open($fh, "|-")) {
|
||||||
# Parent
|
# Parent
|
||||||
} elsif (defined $pid) {
|
} elsif (defined $pid) {
|
||||||
# Child
|
# Child
|
||||||
# This redirection is necessary because rsync sends
|
# This redirection is necessary because rsync sends
|
||||||
# verbose output to STDOUT
|
# verbose output to STDOUT
|
||||||
open(STDOUT, ">&STDERR")
|
open(STDOUT, ">&STDERR")
|
||||||
or die "Could not redirect STDOUT to STDERR\n";
|
or die "Could not redirect STDOUT to STDERR\n";
|
||||||
exec(@command);
|
exec(@command);
|
||||||
die "Could not exec '@command': $!\n";
|
die "Could not exec '@command': $!\n";
|
||||||
} else {
|
} else {
|
||||||
die "Could not fork: $!\n";
|
die "Could not fork: $!\n";
|
||||||
}
|
}
|
||||||
return($fh, $pid);
|
return($fh, $pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
658
slack-dist/dist/slack
vendored
658
slack-dist/dist/slack
vendored
@ -1,329 +1,329 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack 180 2008-01-19 08:26:19Z alan $
|
# $Id: slack 180 2008-01-19 08:26:19Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
|
|
||||||
# This script is in charge of copying files from the (possibly remote)
|
# This script is in charge of copying files from the (possibly remote)
|
||||||
# master directory to a local cache, using rsync
|
# master directory to a local cache, using rsync
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Find;
|
use File::Find;
|
||||||
use POSIX; # for strftime
|
use POSIX; # for strftime
|
||||||
|
|
||||||
use constant LIBEXEC_DIR => '/usr/lib/slack';
|
use constant LIBEXEC_DIR => '/usr/lib/slack';
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
sub run_backend(@);
|
sub run_backend(@);
|
||||||
sub run_conditional_backend($@);
|
sub run_conditional_backend($@);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
# Arguments to pass to each backends (initialized to a hash of empty arrays)
|
# Arguments to pass to each backends (initialized to a hash of empty arrays)
|
||||||
my %backend_flags = ( map { $_ => [] }
|
my %backend_flags = ( map { $_ => [] }
|
||||||
qw(getroles sync stage preview preinstall fixfiles installfiles postinstall)
|
qw(getroles sync stage preview preinstall fixfiles installfiles postinstall)
|
||||||
);
|
);
|
||||||
|
|
||||||
my @roles;
|
my @roles;
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir("/")
|
chdir("/")
|
||||||
or die "Could not chdir /: $!";
|
or die "Could not chdir /: $!";
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options] [<role>...]");
|
my $usage = Slack::default_usage("$PROG [options] [<role>...]");
|
||||||
$usage .= <<EOF;
|
$usage .= <<EOF;
|
||||||
|
|
||||||
--preview MODE
|
--preview MODE
|
||||||
Do a diff of scripts and files before running them.
|
Do a diff of scripts and files before running them.
|
||||||
MODE can be one of 'simple' or 'prompt'.
|
MODE can be one of 'simple' or 'prompt'.
|
||||||
|
|
||||||
--no-files
|
--no-files
|
||||||
Don't install any files in ROOT, but tell rsync to print what
|
Don't install any files in ROOT, but tell rsync to print what
|
||||||
it would do.
|
it would do.
|
||||||
|
|
||||||
--no-scripts
|
--no-scripts
|
||||||
Don't run scripts.
|
Don't run scripts.
|
||||||
|
|
||||||
--no-sync
|
--no-sync
|
||||||
Skip the slack-sync step. (useful if you're pushing stuff into
|
Skip the slack-sync step. (useful if you're pushing stuff into
|
||||||
the CACHE outside of slack)
|
the CACHE outside of slack)
|
||||||
|
|
||||||
--role-list
|
--role-list
|
||||||
Role list for slack-getroles
|
Role list for slack-getroles
|
||||||
|
|
||||||
--libexec-dir DIR
|
--libexec-dir DIR
|
||||||
Look for backend scripts in this directory.
|
Look for backend scripts in this directory.
|
||||||
|
|
||||||
--diff PROG
|
--diff PROG
|
||||||
Use this diff program for previews
|
Use this diff program for previews
|
||||||
|
|
||||||
--sleep TIME
|
--sleep TIME
|
||||||
Randomly sleep between 1 and TIME seconds before starting
|
Randomly sleep between 1 and TIME seconds before starting
|
||||||
operations
|
operations
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
# So we can distinguish stuff on the command line from config file stuff
|
# So we can distinguish stuff on the command line from config file stuff
|
||||||
my %command_line_opt = ();
|
my %command_line_opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
command_line_options => [
|
command_line_options => [
|
||||||
'preview=s',
|
'preview=s',
|
||||||
'role-list=s',
|
'role-list=s',
|
||||||
'no-scripts|noscripts',
|
'no-scripts|noscripts',
|
||||||
'no-files|nofiles',
|
'no-files|nofiles',
|
||||||
'no-sync|nosync',
|
'no-sync|nosync',
|
||||||
'libexec-dir=s',
|
'libexec-dir=s',
|
||||||
'diff=s',
|
'diff=s',
|
||||||
'sleep=i',
|
'sleep=i',
|
||||||
],
|
],
|
||||||
required_options => [ qw(source cache stage root) ],
|
required_options => [ qw(source cache stage root) ],
|
||||||
command_line_hash => \%command_line_opt,
|
command_line_hash => \%command_line_opt,
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
);
|
);
|
||||||
|
|
||||||
# Special options
|
# Special options
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
$opt{'no-scripts'} = 1;
|
$opt{'no-scripts'} = 1;
|
||||||
$opt{'no-files'} = 1;
|
$opt{'no-files'} = 1;
|
||||||
}
|
}
|
||||||
if ($opt{'no-scripts'}) {
|
if ($opt{'no-scripts'}) {
|
||||||
for my $action (qw(fixfiles preinstall postinstall)) {
|
for my $action (qw(fixfiles preinstall postinstall)) {
|
||||||
push @{$backend_flags{$action}},
|
push @{$backend_flags{$action}},
|
||||||
'--dry-run';
|
'--dry-run';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($opt{'no-files'}) {
|
if ($opt{'no-files'}) {
|
||||||
push @{$backend_flags{installfiles}},
|
push @{$backend_flags{installfiles}},
|
||||||
'--dry-run';
|
'--dry-run';
|
||||||
}
|
}
|
||||||
# propagate verbosity - 1 to all backends
|
# propagate verbosity - 1 to all backends
|
||||||
if (defined $command_line_opt{'verbose'} and
|
if (defined $command_line_opt{'verbose'} and
|
||||||
$command_line_opt{'verbose'} > 1) {
|
$command_line_opt{'verbose'} > 1) {
|
||||||
for my $action (keys %backend_flags) {
|
for my $action (keys %backend_flags) {
|
||||||
push @{$backend_flags{$action}},
|
push @{$backend_flags{$action}},
|
||||||
('--verbose') x ($command_line_opt{'verbose'} - 1);
|
('--verbose') x ($command_line_opt{'verbose'} - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# propagate these flags to all the backends
|
# propagate these flags to all the backends
|
||||||
for my $option (qw(config root cache stage source hostname rsh)) {
|
for my $option (qw(config root cache stage source hostname rsh)) {
|
||||||
if ($command_line_opt{$option}) {
|
if ($command_line_opt{$option}) {
|
||||||
for my $action (keys %backend_flags) {
|
for my $action (keys %backend_flags) {
|
||||||
push @{$backend_flags{$action}},
|
push @{$backend_flags{$action}},
|
||||||
"--$option=$command_line_opt{$option}";
|
"--$option=$command_line_opt{$option}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# getroles also can take 'role-list'
|
# getroles also can take 'role-list'
|
||||||
if ($command_line_opt{'role-list'}) {
|
if ($command_line_opt{'role-list'}) {
|
||||||
push @{$backend_flags{'getroles'}},
|
push @{$backend_flags{'getroles'}},
|
||||||
"--role-list=$command_line_opt{'role-list'}";
|
"--role-list=$command_line_opt{'role-list'}";
|
||||||
}
|
}
|
||||||
|
|
||||||
# The libexec dir defaults to this if it wasn't specified
|
# The libexec dir defaults to this if it wasn't specified
|
||||||
# on the command line or in a config file.
|
# on the command line or in a config file.
|
||||||
if (not defined $opt{'libexec-dir'}) {
|
if (not defined $opt{'libexec-dir'}) {
|
||||||
$opt{'libexec-dir'} = LIBEXEC_DIR;
|
$opt{'libexec-dir'} = LIBEXEC_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Pass diff option along to slack-rolediff
|
# Pass diff option along to slack-rolediff
|
||||||
if ($opt{'diff'}) {
|
if ($opt{'diff'}) {
|
||||||
push @{$backend_flags{preview}},
|
push @{$backend_flags{preview}},
|
||||||
"--diff=$opt{'diff'}";
|
"--diff=$opt{'diff'}";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Preview takes an optional argument. If no argument is given,
|
# Preview takes an optional argument. If no argument is given,
|
||||||
# it gets "" from getopt.
|
# it gets "" from getopt.
|
||||||
if (defined $opt{'preview'}) {
|
if (defined $opt{'preview'}) {
|
||||||
if (not grep /^$opt{'preview'}$/, qw(simple prompt)) {
|
if (not grep /^$opt{'preview'}$/, qw(simple prompt)) {
|
||||||
die "Unknown preview mode '$opt{'preview'}'!";
|
die "Unknown preview mode '$opt{'preview'}'!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# The backup option defaults to on if it wasn't specified
|
# The backup option defaults to on if it wasn't specified
|
||||||
# on the command line or in a config file
|
# on the command line or in a config file
|
||||||
if (not defined $opt{backup}) {
|
if (not defined $opt{backup}) {
|
||||||
$opt{backup} = 1;
|
$opt{backup} = 1;
|
||||||
}
|
}
|
||||||
# Figure out a place to put backups
|
# Figure out a place to put backups
|
||||||
if ($opt{backup} and $opt{'backup-dir'}) {
|
if ($opt{backup} and $opt{'backup-dir'}) {
|
||||||
push @{$backend_flags{installfiles}},
|
push @{$backend_flags{installfiles}},
|
||||||
'--backup',
|
'--backup',
|
||||||
'--backup-dir='.
|
'--backup-dir='.
|
||||||
$opt{'backup-dir'}.
|
$opt{'backup-dir'}.
|
||||||
"/".
|
"/".
|
||||||
strftime('%F-%T', localtime(time))
|
strftime('%F-%T', localtime(time))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Random sleep, helpful when called from cron.
|
# Random sleep, helpful when called from cron.
|
||||||
if ($opt{sleep}) {
|
if ($opt{sleep}) {
|
||||||
my $secs = int(rand($opt{sleep})) + 1;
|
my $secs = int(rand($opt{sleep})) + 1;
|
||||||
$opt{verbose} and print STDERR "$PROG: sleep $secs\n";
|
$opt{verbose} and print STDERR "$PROG: sleep $secs\n";
|
||||||
sleep($secs);
|
sleep($secs);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get a list of roles to install from slack-getroles {{{
|
# Get a list of roles to install from slack-getroles {{{
|
||||||
if (not @ARGV) {
|
if (not @ARGV) {
|
||||||
my @command = ($opt{'libexec-dir'}.'/slack-getroles',
|
my @command = ($opt{'libexec-dir'}.'/slack-getroles',
|
||||||
@{$backend_flags{'getroles'}});
|
@{$backend_flags{'getroles'}});
|
||||||
$opt{verbose} and print STDERR "$PROG: getroles\n";
|
$opt{verbose} and print STDERR "$PROG: getroles\n";
|
||||||
($opt{verbose} > 2) and print STDERR "$PROG: Calling '@command' to get a list of roles for this host.\n";
|
($opt{verbose} > 2) and print STDERR "$PROG: Calling '@command' to get a list of roles for this host.\n";
|
||||||
my ($roles_pid, $roles_fh);
|
my ($roles_pid, $roles_fh);
|
||||||
if ($roles_pid = open($roles_fh, "-|")) {
|
if ($roles_pid = open($roles_fh, "-|")) {
|
||||||
# Parent
|
# Parent
|
||||||
} elsif (defined $roles_pid) {
|
} elsif (defined $roles_pid) {
|
||||||
# Child
|
# Child
|
||||||
exec(@command);
|
exec(@command);
|
||||||
die "Could not exec '@command': $!\n";
|
die "Could not exec '@command': $!\n";
|
||||||
} else {
|
} else {
|
||||||
die "Could not fork to run '@command': $!\n";
|
die "Could not fork to run '@command': $!\n";
|
||||||
}
|
}
|
||||||
@roles = split(/\s+/, join(" ", <$roles_fh>));
|
@roles = split(/\s+/, join(" ", <$roles_fh>));
|
||||||
unless (close($roles_fh)) {
|
unless (close($roles_fh)) {
|
||||||
Slack::check_system_exit(@command);
|
Slack::check_system_exit(@command);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@roles = @ARGV;
|
@roles = @ARGV;
|
||||||
}
|
}
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Check role name syntax {{{
|
# Check role name syntax {{{
|
||||||
for my $role (@roles) {
|
for my $role (@roles) {
|
||||||
# Roles MUST begin with a letter. All else is reserved.
|
# Roles MUST begin with a letter. All else is reserved.
|
||||||
if ($role !~ m/^[a-zA-Z]/) {
|
if ($role !~ m/^[a-zA-Z]/) {
|
||||||
die "Role '$role' does not begin with a letter!";
|
die "Role '$role' does not begin with a letter!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
$opt{verbose} and print STDERR "$PROG: installing roles: @roles\n";
|
$opt{verbose} and print STDERR "$PROG: installing roles: @roles\n";
|
||||||
|
|
||||||
unless ($opt{'no-sync'}) {
|
unless ($opt{'no-sync'}) {
|
||||||
# sync all the roles down at once
|
# sync all the roles down at once
|
||||||
$opt{verbose} and print STDERR "$PROG: sync @roles\n";
|
$opt{verbose} and print STDERR "$PROG: sync @roles\n";
|
||||||
run_backend('slack-sync',
|
run_backend('slack-sync',
|
||||||
@{$backend_flags{sync}}, @roles);
|
@{$backend_flags{sync}}, @roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
ROLE: for my $role (@roles) {
|
ROLE: for my $role (@roles) {
|
||||||
# stage
|
# stage
|
||||||
$opt{verbose} and print STDERR "$PROG: stage files $role\n";
|
$opt{verbose} and print STDERR "$PROG: stage files $role\n";
|
||||||
run_backend('slack-stage',
|
run_backend('slack-stage',
|
||||||
@{$backend_flags{stage}}, '--subdir=files', $role);
|
@{$backend_flags{stage}}, '--subdir=files', $role);
|
||||||
|
|
||||||
if ($opt{preview}) {
|
if ($opt{preview}) {
|
||||||
if ($opt{preview} eq 'simple') {
|
if ($opt{preview} eq 'simple') {
|
||||||
$opt{verbose} and print STDERR "$PROG: preview $role\n";
|
$opt{verbose} and print STDERR "$PROG: preview $role\n";
|
||||||
# Here, we run the backend in no-prompt mode.
|
# Here, we run the backend in no-prompt mode.
|
||||||
run_conditional_backend(0, 'slack-rolediff',
|
run_conditional_backend(0, 'slack-rolediff',
|
||||||
@{$backend_flags{preview}}, $role);
|
@{$backend_flags{preview}}, $role);
|
||||||
# ...and we skip further action in the ROLE after showing the diff.
|
# ...and we skip further action in the ROLE after showing the diff.
|
||||||
next ROLE;
|
next ROLE;
|
||||||
} elsif ($opt{preview} eq 'prompt') {
|
} elsif ($opt{preview} eq 'prompt') {
|
||||||
$opt{verbose} and print STDERR "$PROG: preview scripts $role\n";
|
$opt{verbose} and print STDERR "$PROG: preview scripts $role\n";
|
||||||
# Here, we want to prompt and just do the scripts, since
|
# Here, we want to prompt and just do the scripts, since
|
||||||
# we need to run preinstall and fixfiles before doing the files.
|
# we need to run preinstall and fixfiles before doing the files.
|
||||||
run_conditional_backend(1, 'slack-rolediff',
|
run_conditional_backend(1, 'slack-rolediff',
|
||||||
@{$backend_flags{preview}}, '--subdir=scripts', $role);
|
@{$backend_flags{preview}}, '--subdir=scripts', $role);
|
||||||
} else {
|
} else {
|
||||||
# Should get caught in option processing, above
|
# Should get caught in option processing, above
|
||||||
die "Unknown preview mode!\n";
|
die "Unknown preview mode!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$opt{verbose} and print STDERR "$PROG: stage scripts $role\n";
|
$opt{verbose} and print STDERR "$PROG: stage scripts $role\n";
|
||||||
run_backend('slack-stage',
|
run_backend('slack-stage',
|
||||||
@{$backend_flags{stage}}, '--subdir=scripts', $role);
|
@{$backend_flags{stage}}, '--subdir=scripts', $role);
|
||||||
|
|
||||||
# preinstall
|
# preinstall
|
||||||
$opt{verbose} and print STDERR "$PROG: preinstall $role\n";
|
$opt{verbose} and print STDERR "$PROG: preinstall $role\n";
|
||||||
run_backend('slack-runscript',
|
run_backend('slack-runscript',
|
||||||
@{$backend_flags{preinstall}}, 'preinstall', $role);
|
@{$backend_flags{preinstall}}, 'preinstall', $role);
|
||||||
|
|
||||||
# fixfiles
|
# fixfiles
|
||||||
$opt{verbose} and print STDERR "$PROG: fixfiles $role\n";
|
$opt{verbose} and print STDERR "$PROG: fixfiles $role\n";
|
||||||
run_backend('slack-runscript',
|
run_backend('slack-runscript',
|
||||||
@{$backend_flags{fixfiles}}, 'fixfiles', $role);
|
@{$backend_flags{fixfiles}}, 'fixfiles', $role);
|
||||||
|
|
||||||
# preview files
|
# preview files
|
||||||
if ($opt{preview} and $opt{preview} eq 'prompt') {
|
if ($opt{preview} and $opt{preview} eq 'prompt') {
|
||||||
$opt{verbose} and print STDERR "$PROG: preview files $role\n";
|
$opt{verbose} and print STDERR "$PROG: preview files $role\n";
|
||||||
run_conditional_backend(1, 'slack-rolediff',
|
run_conditional_backend(1, 'slack-rolediff',
|
||||||
@{$backend_flags{preview}}, '--subdir=files', $role);
|
@{$backend_flags{preview}}, '--subdir=files', $role);
|
||||||
}
|
}
|
||||||
|
|
||||||
# installfiles
|
# installfiles
|
||||||
$opt{verbose} and print STDERR "$PROG: install $role\n";
|
$opt{verbose} and print STDERR "$PROG: install $role\n";
|
||||||
run_backend('slack-installfiles',
|
run_backend('slack-installfiles',
|
||||||
@{$backend_flags{installfiles}}, $role);
|
@{$backend_flags{installfiles}}, $role);
|
||||||
|
|
||||||
# postinstall
|
# postinstall
|
||||||
$opt{verbose} and print STDERR "$PROG: postinstall $role\n";
|
$opt{verbose} and print STDERR "$PROG: postinstall $role\n";
|
||||||
run_backend('slack-runscript',
|
run_backend('slack-runscript',
|
||||||
@{$backend_flags{postinstall}}, 'postinstall', $role);
|
@{$backend_flags{postinstall}}, 'postinstall', $role);
|
||||||
}
|
}
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
sub run_backend (@) {
|
sub run_backend (@) {
|
||||||
my ($backend, @args) = @_;
|
my ($backend, @args) = @_;
|
||||||
# If we weren't given an explicit path, prepend the libexec dir
|
# If we weren't given an explicit path, prepend the libexec dir
|
||||||
unless ($backend =~ m#^/#) {
|
unless ($backend =~ m#^/#) {
|
||||||
$backend = $opt{'libexec-dir'} . '/' . $backend;
|
$backend = $opt{'libexec-dir'} . '/' . $backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Assemble our command line
|
# Assemble our command line
|
||||||
my (@command) = ($backend, @args);
|
my (@command) = ($backend, @args);
|
||||||
($opt{verbose} > 2) and print STDERR "$PROG: Calling '@command'\n";
|
($opt{verbose} > 2) and print STDERR "$PROG: Calling '@command'\n";
|
||||||
unless (system(@command) == 0) {
|
unless (system(@command) == 0) {
|
||||||
Slack::check_system_exit(@command);
|
Slack::check_system_exit(@command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run_conditional_backend ($@) {
|
sub run_conditional_backend ($@) {
|
||||||
my ($prompt, $backend, @args) = @_;
|
my ($prompt, $backend, @args) = @_;
|
||||||
# If we weren't given an explicit path, prepend the libexec dir
|
# If we weren't given an explicit path, prepend the libexec dir
|
||||||
unless ($backend =~ m#^/#) {
|
unless ($backend =~ m#^/#) {
|
||||||
$backend = $opt{'libexec-dir'} . '/' . $backend;
|
$backend = $opt{'libexec-dir'} . '/' . $backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Assemble our command line
|
# Assemble our command line
|
||||||
my (@command) = ($backend, @args);
|
my (@command) = ($backend, @args);
|
||||||
($opt{verbose} > 2) and print STDERR "$PROG: Calling '@command'\n";
|
($opt{verbose} > 2) and print STDERR "$PROG: Calling '@command'\n";
|
||||||
unless (system(@command) == 0) {
|
unless (system(@command) == 0) {
|
||||||
my $exit = Slack::get_system_exit(@command);
|
my $exit = Slack::get_system_exit(@command);
|
||||||
|
|
||||||
if ($exit == 1) {
|
if ($exit == 1) {
|
||||||
# exit 1 means a difference found or something normal that requires
|
# exit 1 means a difference found or something normal that requires
|
||||||
# a prompt before continuing.
|
# a prompt before continuing.
|
||||||
if ($prompt) {
|
if ($prompt) {
|
||||||
exit 1 unless Slack::prompt("Continue? [yN] ") eq 'y';
|
exit 1 unless Slack::prompt("Continue? [yN] ") eq 'y';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
# any other non-successful exit is a serious error.
|
# any other non-successful exit is a serious error.
|
||||||
die "'@command' exited $exit";
|
die "'@command' exited $exit";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1028
slack-dist/dist/slack-diff
vendored
1028
slack-dist/dist/slack-diff
vendored
File diff suppressed because it is too large
Load Diff
322
slack-dist/dist/slack-getroles
vendored
322
slack-dist/dist/slack-getroles
vendored
@ -1,161 +1,161 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack-getroles 180 2008-01-19 08:26:19Z alan $
|
# $Id: slack-getroles 180 2008-01-19 08:26:19Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
|
|
||||||
# This script is in charge of copying files from the (possibly remote)
|
# This script is in charge of copying files from the (possibly remote)
|
||||||
# master directory to a local cache, using rsync
|
# master directory to a local cache, using rsync
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
|
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
my @rsync = ('rsync',
|
my @rsync = ('rsync',
|
||||||
'--links',
|
'--links',
|
||||||
'--times',
|
'--times',
|
||||||
);
|
);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
sub sync_list ();
|
sub sync_list ();
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir("/")
|
chdir("/")
|
||||||
or die "Could not chdir /: $!";
|
or die "Could not chdir /: $!";
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options]");
|
my $usage = Slack::default_usage("$PROG [options]");
|
||||||
$usage .= <<EOF;
|
$usage .= <<EOF;
|
||||||
|
|
||||||
--role-list
|
--role-list
|
||||||
Role list location (can be relative to SOURCE)
|
Role list location (can be relative to SOURCE)
|
||||||
|
|
||||||
--remote-role-list
|
--remote-role-list
|
||||||
Role list is remote and should be copied down with rsync
|
Role list is remote and should be copied down with rsync
|
||||||
(implied by certain forms of role list or SOURCE)
|
(implied by certain forms of role list or SOURCE)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Option defaults
|
# Option defaults
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
command_line_options => [
|
command_line_options => [
|
||||||
'role-list=s',
|
'role-list=s',
|
||||||
'remote-role-list',
|
'remote-role-list',
|
||||||
],
|
],
|
||||||
required_options => [ qw(role-list hostname) ],
|
required_options => [ qw(role-list hostname) ],
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
);
|
);
|
||||||
|
|
||||||
# Prepare for backups
|
# Prepare for backups
|
||||||
if ($opt{backup} and $opt{'backup-dir'}) {
|
if ($opt{backup} and $opt{'backup-dir'}) {
|
||||||
# Make sure backup directory exists
|
# Make sure backup directory exists
|
||||||
unless (-d $opt{'backup-dir'}) {
|
unless (-d $opt{'backup-dir'}) {
|
||||||
($opt{verbose} > 0) and print STDERR "Creating backup directory '$opt{'backup-dir'}'\n";
|
($opt{verbose} > 0) and print STDERR "Creating backup directory '$opt{'backup-dir'}'\n";
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
eval { mkpath($opt{'backup-dir'}); };
|
eval { mkpath($opt{'backup-dir'}); };
|
||||||
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
||||||
}
|
}
|
||||||
# Pass options along to rsync
|
# Pass options along to rsync
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
push @rsync, '--dry-run';
|
push @rsync, '--dry-run';
|
||||||
}
|
}
|
||||||
# Pass options along to rsync
|
# Pass options along to rsync
|
||||||
if ($opt{'verbose'} > 1) {
|
if ($opt{'verbose'} > 1) {
|
||||||
push @rsync, '--verbose';
|
push @rsync, '--verbose';
|
||||||
}
|
}
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# See if role-list is actually relative to source, and pre-pend source
|
# See if role-list is actually relative to source, and pre-pend source
|
||||||
# if need be.
|
# if need be.
|
||||||
unless ($opt{'role-list'} =~ m#^/# or
|
unless ($opt{'role-list'} =~ m#^/# or
|
||||||
$opt{'role-list'} =~ m#^\./# or
|
$opt{'role-list'} =~ m#^\./# or
|
||||||
$opt{'role-list'} =~ m#^[\w@\.-]+:#) {
|
$opt{'role-list'} =~ m#^[\w@\.-]+:#) {
|
||||||
if (not defined $opt{source}) {
|
if (not defined $opt{source}) {
|
||||||
die "Relative path to role-list given, but source not defined!\n\n$usage\n";
|
die "Relative path to role-list given, but source not defined!\n\n$usage\n";
|
||||||
}
|
}
|
||||||
$opt{'role-list'} = $opt{source} . '/' . $opt{'role-list'};
|
$opt{'role-list'} = $opt{source} . '/' . $opt{'role-list'};
|
||||||
}
|
}
|
||||||
|
|
||||||
# auto-detect remote role list
|
# auto-detect remote role list
|
||||||
if ($opt{'role-list'} =~ m#^[\w@\.-]+:#) {
|
if ($opt{'role-list'} =~ m#^[\w@\.-]+:#) {
|
||||||
$opt{'remote-role-list'} = 1;
|
$opt{'remote-role-list'} = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Copy a remote list locally
|
# Copy a remote list locally
|
||||||
if ($opt{'remote-role-list'}) {
|
if ($opt{'remote-role-list'}) {
|
||||||
# We need a cache directory if the role list is not local
|
# We need a cache directory if the role list is not local
|
||||||
if (not defined $opt{cache}) {
|
if (not defined $opt{cache}) {
|
||||||
die "Remote path to role-list given, but cache not defined!\n\n$usage\n";
|
die "Remote path to role-list given, but cache not defined!\n\n$usage\n";
|
||||||
}
|
}
|
||||||
# Look at source type, and add options if necessary
|
# Look at source type, and add options if necessary
|
||||||
if ($opt{'rsh'} or $opt{'role-list'} =~ m/^[\w@\.-]+::/) {
|
if ($opt{'rsh'} or $opt{'role-list'} =~ m/^[\w@\.-]+::/) {
|
||||||
# This is tunnelled rsync, and so needs an extra option
|
# This is tunnelled rsync, and so needs an extra option
|
||||||
if ($opt{'rsh'}) {
|
if ($opt{'rsh'}) {
|
||||||
push @rsync, '-e', $opt{'rsh'};
|
push @rsync, '-e', $opt{'rsh'};
|
||||||
} else {
|
} else {
|
||||||
push @rsync, '-e', 'ssh';
|
push @rsync, '-e', 'ssh';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sync_list();
|
sync_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read in the roles list
|
# Read in the roles list
|
||||||
my @roles = ();
|
my @roles = ();
|
||||||
my $host_found = 0;
|
my $host_found = 0;
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Reading '$opt{'role-list'}'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Reading '$opt{'role-list'}'\n";
|
||||||
open(ROLES, "<", $opt{'role-list'})
|
open(ROLES, "<", $opt{'role-list'})
|
||||||
or die "Could not open '$opt{'role-list'}' for reading: $!\n";
|
or die "Could not open '$opt{'role-list'}' for reading: $!\n";
|
||||||
while(<ROLES>) {
|
while(<ROLES>) {
|
||||||
s/#.*//; # Strip comments
|
s/#.*//; # Strip comments
|
||||||
chomp;
|
chomp;
|
||||||
if (s/^$opt{hostname}:\s*//) {
|
if (s/^$opt{hostname}:\s*//) {
|
||||||
$host_found++;
|
$host_found++;
|
||||||
push @roles, split();
|
push @roles, split();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(ROLES)
|
close(ROLES)
|
||||||
or die "Could not close '$opt{'role-list'}': $!\n";
|
or die "Could not close '$opt{'role-list'}': $!\n";
|
||||||
if (not $host_found) {
|
if (not $host_found) {
|
||||||
die "Host '$opt{hostname}' not found in '$opt{'role-list'}'!\n";
|
die "Host '$opt{hostname}' not found in '$opt{'role-list'}'!\n";
|
||||||
}
|
}
|
||||||
print join("\n", @roles), "\n";
|
print join("\n", @roles), "\n";
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
sub sync_list () {
|
sub sync_list () {
|
||||||
my $source = $opt{'role-list'};
|
my $source = $opt{'role-list'};
|
||||||
my $destination = $opt{cache} . "/_role_list";
|
my $destination = $opt{cache} . "/_role_list";
|
||||||
unless (-d $opt{cache}) {
|
unless (-d $opt{cache}) {
|
||||||
eval { mkpath($opt{cache}); };
|
eval { mkpath($opt{cache}); };
|
||||||
die "Could not mkpath '$opt{cache}': $@\n" if $@;
|
die "Could not mkpath '$opt{cache}': $@\n" if $@;
|
||||||
}
|
}
|
||||||
# All this to run an rsync command
|
# All this to run an rsync command
|
||||||
my @command = (@rsync, $source, $destination);
|
my @command = (@rsync, $source, $destination);
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Calling '@command'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Calling '@command'\n";
|
||||||
Slack::wrap_rsync(@command);
|
Slack::wrap_rsync(@command);
|
||||||
$opt{'role-list'} = $destination;
|
$opt{'role-list'} = $destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
298
slack-dist/dist/slack-installfiles
vendored
298
slack-dist/dist/slack-installfiles
vendored
@ -1,149 +1,149 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack-installfiles 180 2008-01-19 08:26:19Z alan $
|
# $Id: slack-installfiles 180 2008-01-19 08:26:19Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
#
|
#
|
||||||
# This script is in charge of copying files from the local stage to the root
|
# This script is in charge of copying files from the local stage to the root
|
||||||
# of the local filesystem
|
# of the local filesystem
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
|
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
my @rsync = ('rsync',
|
my @rsync = ('rsync',
|
||||||
'--relative',
|
'--relative',
|
||||||
'--times',
|
'--times',
|
||||||
'--perms',
|
'--perms',
|
||||||
'--group',
|
'--group',
|
||||||
'--owner',
|
'--owner',
|
||||||
'--links',
|
'--links',
|
||||||
'--devices',
|
'--devices',
|
||||||
'--sparse',
|
'--sparse',
|
||||||
'--no-implied-dirs', # SO GOOD!
|
'--no-implied-dirs', # SO GOOD!
|
||||||
'--files-from=-',
|
'--files-from=-',
|
||||||
'--from0',
|
'--from0',
|
||||||
);
|
);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
sub install_files ($);
|
sub install_files ($);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir("/")
|
chdir("/")
|
||||||
or die "Could not chdir /: $!";
|
or die "Could not chdir /: $!";
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
||||||
# Option defaults
|
# Option defaults
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
required_options => [ qw(root stage) ],
|
required_options => [ qw(root stage) ],
|
||||||
);
|
);
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Arguments are required
|
# Arguments are required
|
||||||
die "No roles given!\n\n$usage" unless @ARGV;
|
die "No roles given!\n\n$usage" unless @ARGV;
|
||||||
|
|
||||||
unless (-d $opt{root}) {
|
unless (-d $opt{root}) {
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
eval {
|
eval {
|
||||||
mkpath($opt{root});
|
mkpath($opt{root});
|
||||||
# We have a tight umask, and a root of mode 0700 would be undesirable
|
# We have a tight umask, and a root of mode 0700 would be undesirable
|
||||||
# in most cases.
|
# in most cases.
|
||||||
chmod(0755, $opt{root});
|
chmod(0755, $opt{root});
|
||||||
};
|
};
|
||||||
die "Could not mkpath destination directory '$opt{root}': $@\n" if $@;
|
die "Could not mkpath destination directory '$opt{root}': $@\n" if $@;
|
||||||
}
|
}
|
||||||
warn "WARNING[$PROG]: Created destination directory '".$opt{root}."'\n";
|
warn "WARNING[$PROG]: Created destination directory '".$opt{root}."'\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prepare for backups
|
# Prepare for backups
|
||||||
if ($opt{backup} and $opt{'backup-dir'}) {
|
if ($opt{backup} and $opt{'backup-dir'}) {
|
||||||
# Make sure backup directory exists
|
# Make sure backup directory exists
|
||||||
unless (-d $opt{'backup-dir'}) {
|
unless (-d $opt{'backup-dir'}) {
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Creating backup directory '$opt{'backup-dir'}'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Creating backup directory '$opt{'backup-dir'}'\n";
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
eval { mkpath($opt{'backup-dir'}); };
|
eval { mkpath($opt{'backup-dir'}); };
|
||||||
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
||||||
}
|
}
|
||||||
# Pass options along to rsync
|
# Pass options along to rsync
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
push @rsync, '--dry-run';
|
push @rsync, '--dry-run';
|
||||||
}
|
}
|
||||||
if ($opt{'verbose'} > 1) {
|
if ($opt{'verbose'} > 1) {
|
||||||
push @rsync, '--verbose';
|
push @rsync, '--verbose';
|
||||||
}
|
}
|
||||||
|
|
||||||
# copy over the new files
|
# copy over the new files
|
||||||
for my $role (@ARGV) {
|
for my $role (@ARGV) {
|
||||||
install_files($role);
|
install_files($role);
|
||||||
}
|
}
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
# This subroutine takes care of actually installing the files for a role
|
# This subroutine takes care of actually installing the files for a role
|
||||||
sub install_files ($) {
|
sub install_files ($) {
|
||||||
my ($role) = @_;
|
my ($role) = @_;
|
||||||
# final / is important for rsync
|
# final / is important for rsync
|
||||||
my $source = $opt{stage} . "/roles/" . $role . "/files/";
|
my $source = $opt{stage} . "/roles/" . $role . "/files/";
|
||||||
my $destination = $opt{root} . "/";
|
my $destination = $opt{root} . "/";
|
||||||
my @command = (@rsync, $source, $destination);
|
my @command = (@rsync, $source, $destination);
|
||||||
|
|
||||||
if (not -d $source) {
|
if (not -d $source) {
|
||||||
($opt{verbose} > 0) and
|
($opt{verbose} > 0) and
|
||||||
print STDERR "$PROG: No files to install -- '$source' does not exist\n";
|
print STDERR "$PROG: No files to install -- '$source' does not exist\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Try to give some sensible message here
|
# Try to give some sensible message here
|
||||||
if ($opt{verbose} > 0) {
|
if ($opt{verbose} > 0) {
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
print STDERR "$PROG: Dry-run syncing '$source' to '$destination'\n";
|
print STDERR "$PROG: Dry-run syncing '$source' to '$destination'\n";
|
||||||
} else {
|
} else {
|
||||||
print STDERR "$PROG: Syncing '$source' to '$destination'\n";
|
print STDERR "$PROG: Syncing '$source' to '$destination'\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my ($fh) = Slack::wrap_rsync_fh(@command);
|
my ($fh) = Slack::wrap_rsync_fh(@command);
|
||||||
|
|
||||||
select((select($fh), $|=1)[0]); # Turn on autoflush
|
select((select($fh), $|=1)[0]); # Turn on autoflush
|
||||||
|
|
||||||
my $callback = sub {
|
my $callback = sub {
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
($file =~ s#^$source##)
|
($file =~ s#^$source##)
|
||||||
or die "sub failed: $source|$file";
|
or die "sub failed: $source|$file";
|
||||||
print $fh "$file\0";
|
print $fh "$file\0";
|
||||||
};
|
};
|
||||||
|
|
||||||
# This will print files to be synced to the $fh
|
# This will print files to be synced to the $fh
|
||||||
Slack::find_files_to_install($source, $destination, $callback);
|
Slack::find_files_to_install($source, $destination, $callback);
|
||||||
|
|
||||||
# Close fh, waitpid, and check return value
|
# Close fh, waitpid, and check return value
|
||||||
unless (close($fh)) {
|
unless (close($fh)) {
|
||||||
Slack::check_system_exit(@command);
|
Slack::check_system_exit(@command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
292
slack-dist/dist/slack-rolediff
vendored
292
slack-dist/dist/slack-rolediff
vendored
@ -1,146 +1,146 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack-rolediff 125 2006-09-27 07:50:07Z alan $
|
# $Id: slack-rolediff 125 2006-09-27 07:50:07Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2006 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2006 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
#
|
#
|
||||||
# This script provides a preview of scripts or files about to be installed.
|
# This script provides a preview of scripts or files about to be installed.
|
||||||
# Basically, it calls diff -- its smarts are in knowing where things are.
|
# Basically, it calls diff -- its smarts are in knowing where things are.
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Find;
|
use File::Find;
|
||||||
|
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
my @diff = ('slack-diff',
|
my @diff = ('slack-diff',
|
||||||
'-uN',
|
'-uN',
|
||||||
);
|
);
|
||||||
|
|
||||||
# directories to compare
|
# directories to compare
|
||||||
my %subdir = (
|
my %subdir = (
|
||||||
files => 1,
|
files => 1,
|
||||||
scripts => 1,
|
scripts => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
sub diff ($$;@);
|
sub diff ($$;@);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir("/")
|
chdir("/")
|
||||||
or die "Could not chdir /: $!";
|
or die "Could not chdir /: $!";
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
||||||
$usage .= <<EOF;
|
$usage .= <<EOF;
|
||||||
|
|
||||||
--subdir DIR
|
--subdir DIR
|
||||||
Check this subdir only. Possible values for DIR are 'files' and
|
Check this subdir only. Possible values for DIR are 'files' and
|
||||||
'scripts'.
|
'scripts'.
|
||||||
|
|
||||||
--diff PROG
|
--diff PROG
|
||||||
Use this program to do diffs. [@diff]
|
Use this program to do diffs. [@diff]
|
||||||
EOF
|
EOF
|
||||||
# Option defaults
|
# Option defaults
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
command_line_options => [
|
command_line_options => [
|
||||||
'subdir=s',
|
'subdir=s',
|
||||||
'diff=s',
|
'diff=s',
|
||||||
],
|
],
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
required_options => [ qw(cache stage root) ],
|
required_options => [ qw(cache stage root) ],
|
||||||
);
|
);
|
||||||
|
|
||||||
# Arguments are required
|
# Arguments are required
|
||||||
die "No roles given!\n\n$usage" unless @ARGV;
|
die "No roles given!\n\n$usage" unless @ARGV;
|
||||||
|
|
||||||
# We only allow certain values for this option
|
# We only allow certain values for this option
|
||||||
if ($opt{subdir}) {
|
if ($opt{subdir}) {
|
||||||
unless ($opt{subdir} eq 'files' or $opt{subdir} eq 'scripts') {
|
unless ($opt{subdir} eq 'files' or $opt{subdir} eq 'scripts') {
|
||||||
die "--subdir option must be 'files' or 'scripts'\n\n$usage";
|
die "--subdir option must be 'files' or 'scripts'\n\n$usage";
|
||||||
}
|
}
|
||||||
# Only do this subdir
|
# Only do this subdir
|
||||||
%subdir = ( $opt{subdir} => 1 );
|
%subdir = ( $opt{subdir} => 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
# Let people override our diff. Split on spaces so they can pass args.
|
# Let people override our diff. Split on spaces so they can pass args.
|
||||||
if ($opt{diff}) {
|
if ($opt{diff}) {
|
||||||
@diff = split(/\s+/, $opt{diff});
|
@diff = split(/\s+/, $opt{diff});
|
||||||
}
|
}
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
my $exit = 0;
|
my $exit = 0;
|
||||||
# Do the diffs
|
# Do the diffs
|
||||||
for my $full_role (@ARGV) {
|
for my $full_role (@ARGV) {
|
||||||
# Split the full role (e.g. google.foogle.woogle) into components
|
# Split the full role (e.g. google.foogle.woogle) into components
|
||||||
my @role = split(/\./, $full_role);
|
my @role = split(/\./, $full_role);
|
||||||
|
|
||||||
if ($subdir{scripts}) {
|
if ($subdir{scripts}) {
|
||||||
# Then we compare the cache vs the stage
|
# Then we compare the cache vs the stage
|
||||||
my $old = $opt{stage} . "/roles/" . $full_role . "/scripts";
|
my $old = $opt{stage} . "/roles/" . $full_role . "/scripts";
|
||||||
my $new = $opt{cache} . "/roles/" . $role[0] . "/scripts";
|
my $new = $opt{cache} . "/roles/" . $role[0] . "/scripts";
|
||||||
# For scripts, we don't care so much about mode and owner (since those are
|
# For scripts, we don't care so much about mode and owner (since those are
|
||||||
# inherited in the CACHE from the SOURCE), so --noperms.
|
# inherited in the CACHE from the SOURCE), so --noperms.
|
||||||
$exit |= diff($old, $new, '--noperms');
|
$exit |= diff($old, $new, '--noperms');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($subdir{files}) {
|
if ($subdir{files}) {
|
||||||
# Then we compare the stage vs the root
|
# Then we compare the stage vs the root
|
||||||
my $old = $opt{root};
|
my $old = $opt{root};
|
||||||
my $new = $opt{stage} . "/roles/" . $full_role . "/files";
|
my $new = $opt{stage} . "/roles/" . $full_role . "/files";
|
||||||
# For files, we don't care about files that exist in $old but not $new
|
# For files, we don't care about files that exist in $old but not $new
|
||||||
$exit |= diff($old, $new, '--unidirectional-new-file');
|
$exit |= diff($old, $new, '--unidirectional-new-file');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit $exit;
|
exit $exit;
|
||||||
|
|
||||||
sub diff ($$;@) {
|
sub diff ($$;@) {
|
||||||
my ($old, $new, @options) = @_;
|
my ($old, $new, @options) = @_;
|
||||||
|
|
||||||
my @command = (@diff, @options);
|
my @command = (@diff, @options);
|
||||||
|
|
||||||
# return if there's nothing to do
|
# return if there's nothing to do
|
||||||
return 0 if (not -d $old and not -d $new);
|
return 0 if (not -d $old and not -d $new);
|
||||||
|
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Previewing with '@command'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Previewing with '@command'\n";
|
||||||
|
|
||||||
my $return = 0;
|
my $return = 0;
|
||||||
my $callback = sub {
|
my $callback = sub {
|
||||||
my ($new_file) = @_;
|
my ($new_file) = @_;
|
||||||
my $old_file = $new_file;
|
my $old_file = $new_file;
|
||||||
($old_file =~ s#^$new#$old#)
|
($old_file =~ s#^$new#$old#)
|
||||||
or die "sub failed: $new|$new_file";
|
or die "sub failed: $new|$new_file";
|
||||||
if (system(@command, $old_file, $new_file) != 0) {
|
if (system(@command, $old_file, $new_file) != 0) {
|
||||||
$return |= Slack::get_system_exit(@command);
|
$return |= Slack::get_system_exit(@command);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
# We have to use this function, rather than recursive mode for slack-diff,
|
# We have to use this function, rather than recursive mode for slack-diff,
|
||||||
# because otherwise we'll print a bunch of bogus stuff about directories
|
# because otherwise we'll print a bunch of bogus stuff about directories
|
||||||
# that exist in $ROOT and therefore aren't being synced.
|
# that exist in $ROOT and therefore aren't being synced.
|
||||||
Slack::find_files_to_install($new, $old, $callback);
|
Slack::find_files_to_install($new, $old, $callback);
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
222
slack-dist/dist/slack-runscript
vendored
222
slack-dist/dist/slack-runscript
vendored
@ -1,111 +1,111 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack-runscript 118 2006-09-25 18:35:17Z alan $
|
# $Id: slack-runscript 118 2006-09-25 18:35:17Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2006 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2006 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
#
|
#
|
||||||
# This script is in charge of running scripts out of the local stage
|
# This script is in charge of running scripts out of the local stage
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Find;
|
use File::Find;
|
||||||
|
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
# Export these options to the environment of the script
|
# Export these options to the environment of the script
|
||||||
my @export_options = qw(root stage hostname verbose);
|
my @export_options = qw(root stage hostname verbose);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir('/')
|
chdir('/')
|
||||||
or die "Could not chdir '/': $!";
|
or die "Could not chdir '/': $!";
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options] <action> <role> [<role>...]");
|
my $usage = Slack::default_usage("$PROG [options] <action> <role> [<role>...]");
|
||||||
# Option defaults
|
# Option defaults
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
required_options => \@export_options,
|
required_options => \@export_options,
|
||||||
);
|
);
|
||||||
|
|
||||||
my $action = shift || die "No script to run!\n\n$usage";
|
my $action = shift || die "No script to run!\n\n$usage";
|
||||||
# Arguments are required
|
# Arguments are required
|
||||||
die "No roles given!\n\n$usage" unless @ARGV;
|
die "No roles given!\n\n$usage" unless @ARGV;
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Start with a clean environment
|
# Start with a clean environment
|
||||||
%ENV = (
|
%ENV = (
|
||||||
PATH => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
|
PATH => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
|
||||||
);
|
);
|
||||||
# Export certain variables to the environment. These are guaranteed to
|
# Export certain variables to the environment. These are guaranteed to
|
||||||
# be set because we require them in get_options above.
|
# be set because we require them in get_options above.
|
||||||
for my $option (@export_options) {
|
for my $option (@export_options) {
|
||||||
my $env_var = $option;
|
my $env_var = $option;
|
||||||
$env_var =~ tr/a-z-/A-Z_/;
|
$env_var =~ tr/a-z-/A-Z_/;
|
||||||
$ENV{$env_var} = $opt{$option};
|
$ENV{$env_var} = $opt{$option};
|
||||||
}
|
}
|
||||||
# We want to decrement the verbose value for the child if it's set.
|
# We want to decrement the verbose value for the child if it's set.
|
||||||
$ENV{VERBOSE}-- if $ENV{VERBOSE};
|
$ENV{VERBOSE}-- if $ENV{VERBOSE};
|
||||||
|
|
||||||
# Run the script for each role given, if it exists and is executable
|
# Run the script for each role given, if it exists and is executable
|
||||||
for my $role (@ARGV) {
|
for my $role (@ARGV) {
|
||||||
my $script_to_run = "$opt{stage}/roles/$role/scripts/$action";
|
my $script_to_run = "$opt{stage}/roles/$role/scripts/$action";
|
||||||
unless (-x $script_to_run) {
|
unless (-x $script_to_run) {
|
||||||
if (-e _) {
|
if (-e _) {
|
||||||
# A helpful warning
|
# A helpful warning
|
||||||
warn "WARNING[$PROG]: Skipping '$script_to_run' because it's not executable\n";
|
warn "WARNING[$PROG]: Skipping '$script_to_run' because it's not executable\n";
|
||||||
} elsif ($opt{verbose} > 0) {
|
} elsif ($opt{verbose} > 0) {
|
||||||
print STDERR "$PROG: Skipping '$script_to_run' because it doesn't exist\n";
|
print STDERR "$PROG: Skipping '$script_to_run' because it doesn't exist\n";
|
||||||
}
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my $dir;
|
my $dir;
|
||||||
if ($action eq 'fixfiles') {
|
if ($action eq 'fixfiles') {
|
||||||
$dir = "$opt{stage}/roles/$role/files";
|
$dir = "$opt{stage}/roles/$role/files";
|
||||||
} else {
|
} else {
|
||||||
$dir = "$opt{stage}/roles/$role/scripts";
|
$dir = "$opt{stage}/roles/$role/scripts";
|
||||||
}
|
}
|
||||||
my @command = ($script_to_run , $role);
|
my @command = ($script_to_run , $role);
|
||||||
|
|
||||||
# It's OK to chdir even if we're not going to run the script.
|
# It's OK to chdir even if we're not going to run the script.
|
||||||
# Might as well see if it works.
|
# Might as well see if it works.
|
||||||
chdir($dir)
|
chdir($dir)
|
||||||
or die "Could not chdir '$dir': $!\n";
|
or die "Could not chdir '$dir': $!\n";
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
($opt{verbose} > 0)
|
($opt{verbose} > 0)
|
||||||
and print STDERR "$PROG: Not calling '@command' in '$dir' ".
|
and print STDERR "$PROG: Not calling '@command' in '$dir' ".
|
||||||
"because --dry-run specified.\n";
|
"because --dry-run specified.\n";
|
||||||
} else {
|
} else {
|
||||||
($opt{verbose} > 0)
|
($opt{verbose} > 0)
|
||||||
and print STDERR "$PROG: Calling '@command' in '$dir'.\n";
|
and print STDERR "$PROG: Calling '@command' in '$dir'.\n";
|
||||||
unless (system("script /root/slackLog -a -f -c @command") == 0) {
|
unless (system("script /root/slackLog -a -f -c @command") == 0) {
|
||||||
Slack::check_system_exit(@command);
|
Slack::check_system_exit(@command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chdir('/')
|
chdir('/')
|
||||||
or die "Could not chdir '/': $!\n"
|
or die "Could not chdir '/': $!\n"
|
||||||
}
|
}
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
|
222
slack-dist/dist/slack-runscript.orig
vendored
222
slack-dist/dist/slack-runscript.orig
vendored
@ -1,111 +1,111 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack-runscript 118 2006-09-25 18:35:17Z alan $
|
# $Id: slack-runscript 118 2006-09-25 18:35:17Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2006 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2006 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
#
|
#
|
||||||
# This script is in charge of running scripts out of the local stage
|
# This script is in charge of running scripts out of the local stage
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Find;
|
use File::Find;
|
||||||
|
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
# Export these options to the environment of the script
|
# Export these options to the environment of the script
|
||||||
my @export_options = qw(root stage hostname verbose);
|
my @export_options = qw(root stage hostname verbose);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir('/')
|
chdir('/')
|
||||||
or die "Could not chdir '/': $!";
|
or die "Could not chdir '/': $!";
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options] <action> <role> [<role>...]");
|
my $usage = Slack::default_usage("$PROG [options] <action> <role> [<role>...]");
|
||||||
# Option defaults
|
# Option defaults
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
required_options => \@export_options,
|
required_options => \@export_options,
|
||||||
);
|
);
|
||||||
|
|
||||||
my $action = shift || die "No script to run!\n\n$usage";
|
my $action = shift || die "No script to run!\n\n$usage";
|
||||||
# Arguments are required
|
# Arguments are required
|
||||||
die "No roles given!\n\n$usage" unless @ARGV;
|
die "No roles given!\n\n$usage" unless @ARGV;
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Start with a clean environment
|
# Start with a clean environment
|
||||||
%ENV = (
|
%ENV = (
|
||||||
PATH => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
|
PATH => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
|
||||||
);
|
);
|
||||||
# Export certain variables to the environment. These are guaranteed to
|
# Export certain variables to the environment. These are guaranteed to
|
||||||
# be set because we require them in get_options above.
|
# be set because we require them in get_options above.
|
||||||
for my $option (@export_options) {
|
for my $option (@export_options) {
|
||||||
my $env_var = $option;
|
my $env_var = $option;
|
||||||
$env_var =~ tr/a-z-/A-Z_/;
|
$env_var =~ tr/a-z-/A-Z_/;
|
||||||
$ENV{$env_var} = $opt{$option};
|
$ENV{$env_var} = $opt{$option};
|
||||||
}
|
}
|
||||||
# We want to decrement the verbose value for the child if it's set.
|
# We want to decrement the verbose value for the child if it's set.
|
||||||
$ENV{VERBOSE}-- if $ENV{VERBOSE};
|
$ENV{VERBOSE}-- if $ENV{VERBOSE};
|
||||||
|
|
||||||
# Run the script for each role given, if it exists and is executable
|
# Run the script for each role given, if it exists and is executable
|
||||||
for my $role (@ARGV) {
|
for my $role (@ARGV) {
|
||||||
my $script_to_run = "$opt{stage}/roles/$role/scripts/$action";
|
my $script_to_run = "$opt{stage}/roles/$role/scripts/$action";
|
||||||
unless (-x $script_to_run) {
|
unless (-x $script_to_run) {
|
||||||
if (-e _) {
|
if (-e _) {
|
||||||
# A helpful warning
|
# A helpful warning
|
||||||
warn "WARNING[$PROG]: Skipping '$script_to_run' because it's not executable\n";
|
warn "WARNING[$PROG]: Skipping '$script_to_run' because it's not executable\n";
|
||||||
} elsif ($opt{verbose} > 0) {
|
} elsif ($opt{verbose} > 0) {
|
||||||
print STDERR "$PROG: Skipping '$script_to_run' because it doesn't exist\n";
|
print STDERR "$PROG: Skipping '$script_to_run' because it doesn't exist\n";
|
||||||
}
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my $dir;
|
my $dir;
|
||||||
if ($action eq 'fixfiles') {
|
if ($action eq 'fixfiles') {
|
||||||
$dir = "$opt{stage}/roles/$role/files";
|
$dir = "$opt{stage}/roles/$role/files";
|
||||||
} else {
|
} else {
|
||||||
$dir = "$opt{stage}/roles/$role/scripts";
|
$dir = "$opt{stage}/roles/$role/scripts";
|
||||||
}
|
}
|
||||||
my @command = ($script_to_run, $role);
|
my @command = ($script_to_run, $role);
|
||||||
|
|
||||||
# It's OK to chdir even if we're not going to run the script.
|
# It's OK to chdir even if we're not going to run the script.
|
||||||
# Might as well see if it works.
|
# Might as well see if it works.
|
||||||
chdir($dir)
|
chdir($dir)
|
||||||
or die "Could not chdir '$dir': $!\n";
|
or die "Could not chdir '$dir': $!\n";
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
($opt{verbose} > 0)
|
($opt{verbose} > 0)
|
||||||
and print STDERR "$PROG: Not calling '@command' in '$dir' ".
|
and print STDERR "$PROG: Not calling '@command' in '$dir' ".
|
||||||
"because --dry-run specified.\n";
|
"because --dry-run specified.\n";
|
||||||
} else {
|
} else {
|
||||||
($opt{verbose} > 0)
|
($opt{verbose} > 0)
|
||||||
and print STDERR "$PROG: Calling '@command' in '$dir'.\n";
|
and print STDERR "$PROG: Calling '@command' in '$dir'.\n";
|
||||||
unless (system(@command) == 0) {
|
unless (system(@command) == 0) {
|
||||||
Slack::check_system_exit(@command);
|
Slack::check_system_exit(@command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chdir('/')
|
chdir('/')
|
||||||
or die "Could not chdir '/': $!\n"
|
or die "Could not chdir '/': $!\n"
|
||||||
}
|
}
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
|
556
slack-dist/dist/slack-stage
vendored
556
slack-dist/dist/slack-stage
vendored
@ -1,278 +1,278 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack-stage 180 2008-01-19 08:26:19Z alan $
|
# $Id: slack-stage 180 2008-01-19 08:26:19Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
#
|
#
|
||||||
# This script is in charge of copying files from the local cache
|
# This script is in charge of copying files from the local cache
|
||||||
# directory to the local stage, building a unified single tree onstage
|
# directory to the local stage, building a unified single tree onstage
|
||||||
# from the multiple trees that are the role + subroles in the cache
|
# from the multiple trees that are the role + subroles in the cache
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Find;
|
use File::Find;
|
||||||
|
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
my @rsync = ('rsync',
|
my @rsync = ('rsync',
|
||||||
'--recursive',
|
'--recursive',
|
||||||
'--times',
|
'--times',
|
||||||
'--ignore-times',
|
'--ignore-times',
|
||||||
'--perms',
|
'--perms',
|
||||||
'--sparse',
|
'--sparse',
|
||||||
);
|
);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
sub check_stage ();
|
sub check_stage ();
|
||||||
sub sync_role ($$@);
|
sub sync_role ($$@);
|
||||||
sub apply_default_perms_to_role ($$);
|
sub apply_default_perms_to_role ($$);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir("/")
|
chdir("/")
|
||||||
or die "Could not chdir /: $!";
|
or die "Could not chdir /: $!";
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
||||||
$usage .= <<EOF;
|
$usage .= <<EOF;
|
||||||
|
|
||||||
--subdir DIR
|
--subdir DIR
|
||||||
Sync this subdir only. Possible values for DIR are 'files' and
|
Sync this subdir only. Possible values for DIR are 'files' and
|
||||||
'scripts'.
|
'scripts'.
|
||||||
EOF
|
EOF
|
||||||
# Option defaults
|
# Option defaults
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
command_line_options => [
|
command_line_options => [
|
||||||
'subdir=s',
|
'subdir=s',
|
||||||
],
|
],
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
required_options => [ qw(cache stage) ],
|
required_options => [ qw(cache stage) ],
|
||||||
);
|
);
|
||||||
|
|
||||||
# Arguments are required
|
# Arguments are required
|
||||||
die "No roles given!\n\n$usage" unless @ARGV;
|
die "No roles given!\n\n$usage" unless @ARGV;
|
||||||
|
|
||||||
# We only allow certain values for this option
|
# We only allow certain values for this option
|
||||||
if ($opt{subdir}) {
|
if ($opt{subdir}) {
|
||||||
unless ($opt{subdir} eq 'files' or $opt{subdir} eq 'scripts') {
|
unless ($opt{subdir} eq 'files' or $opt{subdir} eq 'scripts') {
|
||||||
die "--subdir option must be 'files' or 'scripts'\n\n$usage";
|
die "--subdir option must be 'files' or 'scripts'\n\n$usage";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$opt{subdir} = '';
|
$opt{subdir} = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prepare for backups
|
# Prepare for backups
|
||||||
if ($opt{backup} and $opt{'backup-dir'}) {
|
if ($opt{backup} and $opt{'backup-dir'}) {
|
||||||
# Make sure backup directory exists
|
# Make sure backup directory exists
|
||||||
unless (-d $opt{'backup-dir'}) {
|
unless (-d $opt{'backup-dir'}) {
|
||||||
($opt{verbose} > 0) and print STDERR "Creating backup directory '$opt{'backup-dir'}'\n";
|
($opt{verbose} > 0) and print STDERR "Creating backup directory '$opt{'backup-dir'}'\n";
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
eval { mkpath($opt{'backup-dir'}); };
|
eval { mkpath($opt{'backup-dir'}); };
|
||||||
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
||||||
}
|
}
|
||||||
|
|
||||||
# Pass options along to rsync
|
# Pass options along to rsync
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
push @rsync, '--dry-run';
|
push @rsync, '--dry-run';
|
||||||
}
|
}
|
||||||
# Pass options along to rsync
|
# Pass options along to rsync
|
||||||
if ($opt{'verbose'} > 1) {
|
if ($opt{'verbose'} > 1) {
|
||||||
push @rsync, '--verbose';
|
push @rsync, '--verbose';
|
||||||
}
|
}
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# copy over the new files
|
# copy over the new files
|
||||||
for my $full_role (@ARGV) {
|
for my $full_role (@ARGV) {
|
||||||
# Split the full role (e.g. google.foogle.woogle) into components
|
# Split the full role (e.g. google.foogle.woogle) into components
|
||||||
my @role_parts = split(/\./, $full_role);
|
my @role_parts = split(/\./, $full_role);
|
||||||
die "Internal error: Expect at least one role part" if not @role_parts;
|
die "Internal error: Expect at least one role part" if not @role_parts;
|
||||||
# Reassemble parts one at a time onto @role and sync as we go,
|
# Reassemble parts one at a time onto @role and sync as we go,
|
||||||
# so we do "google", then "google.foogle", then "google.foogle.woogle"
|
# so we do "google", then "google.foogle", then "google.foogle.woogle"
|
||||||
my @role = ();
|
my @role = ();
|
||||||
# Make sure we've got the right perms before we copy stuff down
|
# Make sure we've got the right perms before we copy stuff down
|
||||||
check_stage();
|
check_stage();
|
||||||
|
|
||||||
# For the base role, do both files and scripts.
|
# For the base role, do both files and scripts.
|
||||||
push @role, shift @role_parts;
|
push @role, shift @role_parts;
|
||||||
for my $subdir(qw(files scripts)) {
|
for my $subdir(qw(files scripts)) {
|
||||||
if (not $opt{subdir} or $opt{subdir} eq $subdir) {
|
if (not $opt{subdir} or $opt{subdir} eq $subdir) {
|
||||||
($opt{verbose} > 1)
|
($opt{verbose} > 1)
|
||||||
and print STDERR "$PROG: Calling sync_role for $full_role, @role\n";
|
and print STDERR "$PROG: Calling sync_role for $full_role, @role\n";
|
||||||
# @role here will have one element, so sync_role will use --delete
|
# @role here will have one element, so sync_role will use --delete
|
||||||
sync_role($full_role, $subdir, @role)
|
sync_role($full_role, $subdir, @role)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# For all subroles, just do the files.
|
# For all subroles, just do the files.
|
||||||
# (If we wanted script subroles to work like files, we'd get rid of this
|
# (If we wanted script subroles to work like files, we'd get rid of this
|
||||||
# distinction and simplify the code.)
|
# distinction and simplify the code.)
|
||||||
if (not $opt{subdir} or $opt{subdir} eq 'files') {
|
if (not $opt{subdir} or $opt{subdir} eq 'files') {
|
||||||
while (@role_parts) {
|
while (@role_parts) {
|
||||||
push @role, shift @role_parts;
|
push @role, shift @role_parts;
|
||||||
($opt{verbose} > 1)
|
($opt{verbose} > 1)
|
||||||
and print STDERR "$PROG: Calling sync_role for $full_role, @role\n";
|
and print STDERR "$PROG: Calling sync_role for $full_role, @role\n";
|
||||||
sync_role($full_role, 'files', @role);
|
sync_role($full_role, 'files', @role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for my $subdir (qw(files scripts)) {
|
for my $subdir (qw(files scripts)) {
|
||||||
apply_default_perms_to_role($full_role, $subdir)
|
apply_default_perms_to_role($full_role, $subdir)
|
||||||
if (not $opt{subdir} or $opt{subdir} eq $subdir);
|
if (not $opt{subdir} or $opt{subdir} eq $subdir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
# Make sure the stage directory exists and is mode 0700, to protect files
|
# Make sure the stage directory exists and is mode 0700, to protect files
|
||||||
# underneath in transit
|
# underneath in transit
|
||||||
sub check_stage () {
|
sub check_stage () {
|
||||||
my $stage = $opt{stage} . "/roles";
|
my $stage = $opt{stage} . "/roles";
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
if (not -d $stage) {
|
if (not -d $stage) {
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Creating '$stage'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Creating '$stage'\n";
|
||||||
eval { mkpath($stage); };
|
eval { mkpath($stage); };
|
||||||
die "Could not mkpath cache dir '$stage': $@\n" if $@;
|
die "Could not mkpath cache dir '$stage': $@\n" if $@;
|
||||||
}
|
}
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Checking perms on '$stage'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Checking perms on '$stage'\n";
|
||||||
if ($> != 0) {
|
if ($> != 0) {
|
||||||
warn "WARNING[$PROG]: Not superuser; unable to chown files\n";
|
warn "WARNING[$PROG]: Not superuser; unable to chown files\n";
|
||||||
} else {
|
} else {
|
||||||
chown(0, 0, $stage)
|
chown(0, 0, $stage)
|
||||||
or die "Could not chown 0:0 '$stage': $!\n";
|
or die "Could not chown 0:0 '$stage': $!\n";
|
||||||
}
|
}
|
||||||
chmod(0700, $stage)
|
chmod(0700, $stage)
|
||||||
or die "Could not chmod 0700 '$stage': $!\n";
|
or die "Could not chmod 0700 '$stage': $!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Copy the files for a role from CACHE to STAGE
|
# Copy the files for a role from CACHE to STAGE
|
||||||
sub sync_role ($$@) {
|
sub sync_role ($$@) {
|
||||||
my ($full_role, $subdir, @role) = @_;
|
my ($full_role, $subdir, @role) = @_;
|
||||||
my @this_rsync = @rsync;
|
my @this_rsync = @rsync;
|
||||||
|
|
||||||
# If we were only given one role part, we're in the base role
|
# If we were only given one role part, we're in the base role
|
||||||
my $in_base_role = (scalar @role == 1);
|
my $in_base_role = (scalar @role == 1);
|
||||||
|
|
||||||
# For the base role, delete any files that don't exist in the cache.
|
# For the base role, delete any files that don't exist in the cache.
|
||||||
# Not for the subrole (otherwise we'll delete all files not in
|
# Not for the subrole (otherwise we'll delete all files not in
|
||||||
# the subrole, which may be most of them!)
|
# the subrole, which may be most of them!)
|
||||||
if ($in_base_role) {
|
if ($in_base_role) {
|
||||||
push @this_rsync, "--delete";
|
push @this_rsync, "--delete";
|
||||||
}
|
}
|
||||||
|
|
||||||
# (a) => a/files
|
# (a) => a/files
|
||||||
# (a,b,c) => a/files.b.c
|
# (a,b,c) => a/files.b.c
|
||||||
my $src_path = $role[0].'/'.join(".", $subdir, @role[1 .. $#role]);
|
my $src_path = $role[0].'/'.join(".", $subdir, @role[1 .. $#role]);
|
||||||
# This one's a little simpler:
|
# This one's a little simpler:
|
||||||
my $dst_path = $full_role.'/'.$subdir;
|
my $dst_path = $full_role.'/'.$subdir;
|
||||||
|
|
||||||
# final / is important for rsync
|
# final / is important for rsync
|
||||||
my $source = $opt{cache} . "/roles/" . $src_path . "/";
|
my $source = $opt{cache} . "/roles/" . $src_path . "/";
|
||||||
my $destination = $opt{stage} . "/roles/" . $dst_path . "/";
|
my $destination = $opt{stage} . "/roles/" . $dst_path . "/";
|
||||||
if (not -d $destination and -d $source) {
|
if (not -d $destination and -d $source) {
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Creating '$destination'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Creating '$destination'\n";
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
eval { mkpath($destination); };
|
eval { mkpath($destination); };
|
||||||
die "Could not mkpath stage dir '$destination': $@\n" if $@;
|
die "Could not mkpath stage dir '$destination': $@\n" if $@;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# We no longer require the source to exist
|
# We no longer require the source to exist
|
||||||
if (not -d $source) {
|
if (not -d $source) {
|
||||||
# but we need to remove the destination if the source
|
# but we need to remove the destination if the source
|
||||||
# doesn't exist and we're in the base role
|
# doesn't exist and we're in the base role
|
||||||
if ($in_base_role) {
|
if ($in_base_role) {
|
||||||
rmtree($destination);
|
rmtree($destination);
|
||||||
# rmtree() doesn't throw exceptions or give a return value useful
|
# rmtree() doesn't throw exceptions or give a return value useful
|
||||||
# for detecting failure, so we just check after the fact.
|
# for detecting failure, so we just check after the fact.
|
||||||
die "Could not rmtree '$destination' when '$source' missing\n"
|
die "Could not rmtree '$destination' when '$source' missing\n"
|
||||||
if -e $destination;
|
if -e $destination;
|
||||||
}
|
}
|
||||||
# if we continue, rsync will fail because source is missing,
|
# if we continue, rsync will fail because source is missing,
|
||||||
# so we don't.
|
# so we don't.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# All this to run an rsync command
|
# All this to run an rsync command
|
||||||
my @command = (@this_rsync, $source, $destination);
|
my @command = (@this_rsync, $source, $destination);
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Syncing $src_path with '@command'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Syncing $src_path with '@command'\n";
|
||||||
Slack::wrap_rsync(@command);
|
Slack::wrap_rsync(@command);
|
||||||
}
|
}
|
||||||
|
|
||||||
# This just takes the base role, and chowns/chmods everything under it to
|
# This just takes the base role, and chowns/chmods everything under it to
|
||||||
# give it some sensible permissions. Basically, the only thing we preserve
|
# give it some sensible permissions. Basically, the only thing we preserve
|
||||||
# about the original permissions is the executable bit, since that's the
|
# about the original permissions is the executable bit, since that's the
|
||||||
# only thing source code controls systems like CVS, RCS, Perforce seem to
|
# only thing source code controls systems like CVS, RCS, Perforce seem to
|
||||||
# preserve.
|
# preserve.
|
||||||
sub apply_default_perms_to_role ($$) {
|
sub apply_default_perms_to_role ($$) {
|
||||||
my ($role, $subdir) = @_;
|
my ($role, $subdir) = @_;
|
||||||
my $destination = $opt{stage} . "/roles/" . $role;
|
my $destination = $opt{stage} . "/roles/" . $role;
|
||||||
|
|
||||||
if ($subdir) {
|
if ($subdir) {
|
||||||
$destination .= '/' . $subdir;
|
$destination .= '/' . $subdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
# If the destination doesn't exist, it's probably because the source didn't
|
# If the destination doesn't exist, it's probably because the source didn't
|
||||||
return if not -d $destination;
|
return if not -d $destination;
|
||||||
|
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Setting default perms on $destination\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Setting default perms on $destination\n";
|
||||||
if ($> != 0) {
|
if ($> != 0) {
|
||||||
warn "WARNING[$PROG]: Not superuser; won't be able to chown files\n";
|
warn "WARNING[$PROG]: Not superuser; won't be able to chown files\n";
|
||||||
}
|
}
|
||||||
# Use File::Find to recurse the directory
|
# Use File::Find to recurse the directory
|
||||||
find({
|
find({
|
||||||
# The "wanted" subroutine is called for every directory entry
|
# The "wanted" subroutine is called for every directory entry
|
||||||
wanted => sub {
|
wanted => sub {
|
||||||
return if $opt{'dry-run'};
|
return if $opt{'dry-run'};
|
||||||
($opt{verbose} > 2) and print STDERR "$File::Find::name\n";
|
($opt{verbose} > 2) and print STDERR "$File::Find::name\n";
|
||||||
if (-l) {
|
if (-l) {
|
||||||
# symlinks shouldn't be in here,
|
# symlinks shouldn't be in here,
|
||||||
# since we dereference when copying
|
# since we dereference when copying
|
||||||
warn "WARNING[$PROG]: Skipping symlink at $File::Find::name: $!\n";
|
warn "WARNING[$PROG]: Skipping symlink at $File::Find::name: $!\n";
|
||||||
return;
|
return;
|
||||||
} elsif (-f _) { # results of last stat saved in the "_"
|
} elsif (-f _) { # results of last stat saved in the "_"
|
||||||
if (-x _) {
|
if (-x _) {
|
||||||
chmod 0555, $_
|
chmod 0555, $_
|
||||||
or die "Could not chmod 0555 $File::Find::name: $!";
|
or die "Could not chmod 0555 $File::Find::name: $!";
|
||||||
} else {
|
} else {
|
||||||
chmod 0444, $_
|
chmod 0444, $_
|
||||||
or die "Could not chmod 0444 $File::Find::name: $!";
|
or die "Could not chmod 0444 $File::Find::name: $!";
|
||||||
}
|
}
|
||||||
} elsif (-d _) {
|
} elsif (-d _) {
|
||||||
chmod 0755, $_
|
chmod 0755, $_
|
||||||
or die "Could not chmod 0755 $File::Find::name: $!";
|
or die "Could not chmod 0755 $File::Find::name: $!";
|
||||||
} else {
|
} else {
|
||||||
warn "WARNING[$PROG]: Unknown file type at $File::Find::name: $!\n";
|
warn "WARNING[$PROG]: Unknown file type at $File::Find::name: $!\n";
|
||||||
}
|
}
|
||||||
return if $> != 0; # skip chowning if not superuser
|
return if $> != 0; # skip chowning if not superuser
|
||||||
chown 0, 0, $_
|
chown 0, 0, $_
|
||||||
or die "Could not chown 0:0 $File::Find::name: $!";
|
or die "Could not chown 0:0 $File::Find::name: $!";
|
||||||
},
|
},
|
||||||
# end of wanted function
|
# end of wanted function
|
||||||
},
|
},
|
||||||
# way down here, we have the directory to traverse with File::Find
|
# way down here, we have the directory to traverse with File::Find
|
||||||
$destination,
|
$destination,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
338
slack-dist/dist/slack-sync
vendored
338
slack-dist/dist/slack-sync
vendored
@ -1,169 +1,169 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
# $Id: slack-sync 180 2008-01-19 08:26:19Z alan $
|
# $Id: slack-sync 180 2008-01-19 08:26:19Z alan $
|
||||||
# vim:sw=2
|
# vim:sw=2
|
||||||
# vim600:fdm=marker
|
# vim600:fdm=marker
|
||||||
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
# Copyright (C) 2004-2008 Alan Sundell <alan@sundell.net>
|
||||||
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
# All Rights Reserved. This program comes with ABSOLUTELY NO WARRANTY.
|
||||||
# See the file COPYING for details.
|
# See the file COPYING for details.
|
||||||
#
|
#
|
||||||
# This script is in charge of copying files from the (possibly remote)
|
# This script is in charge of copying files from the (possibly remote)
|
||||||
# master directory to a local cache, using rsync
|
# master directory to a local cache, using rsync
|
||||||
|
|
||||||
require 5.006;
|
require 5.006;
|
||||||
use warnings FATAL => qw(all);
|
use warnings FATAL => qw(all);
|
||||||
use strict;
|
use strict;
|
||||||
use sigtrap qw(die untrapped normal-signals
|
use sigtrap qw(die untrapped normal-signals
|
||||||
stack-trace any error-signals);
|
stack-trace any error-signals);
|
||||||
|
|
||||||
use File::Path;
|
use File::Path;
|
||||||
|
|
||||||
use constant LIB_DIR => '/usr/lib/slack';
|
use constant LIB_DIR => '/usr/lib/slack';
|
||||||
use lib LIB_DIR;
|
use lib LIB_DIR;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
|
||||||
my @rsync = ('rsync',
|
my @rsync = ('rsync',
|
||||||
'--cvs-exclude',
|
'--cvs-exclude',
|
||||||
'--recursive',
|
'--recursive',
|
||||||
'--links',
|
'--links',
|
||||||
'--copy-links',
|
'--copy-links',
|
||||||
'--times',
|
'--times',
|
||||||
'--perms',
|
'--perms',
|
||||||
'--sparse',
|
'--sparse',
|
||||||
'--delete',
|
'--delete',
|
||||||
'--files-from=-',
|
'--files-from=-',
|
||||||
'--from0',
|
'--from0',
|
||||||
);
|
);
|
||||||
|
|
||||||
(my $PROG = $0) =~ s#.*/##;
|
(my $PROG = $0) =~ s#.*/##;
|
||||||
|
|
||||||
sub check_cache ($);
|
sub check_cache ($);
|
||||||
sub rsync_source ($$@);
|
sub rsync_source ($$@);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Environment
|
# Environment
|
||||||
# Helpful prefix to die messages
|
# Helpful prefix to die messages
|
||||||
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
$SIG{__DIE__} = sub { die "FATAL[$PROG]: @_"; };
|
||||||
# Set a reasonable umask
|
# Set a reasonable umask
|
||||||
umask 077;
|
umask 077;
|
||||||
# Get out of wherever (possibly NFS-mounted) we were
|
# Get out of wherever (possibly NFS-mounted) we were
|
||||||
chdir("/")
|
chdir("/")
|
||||||
or die "Could not chdir /: $!";
|
or die "Could not chdir /: $!";
|
||||||
# Autoflush on STDERR
|
# Autoflush on STDERR
|
||||||
select((select(STDERR), $|=1)[0]);
|
select((select(STDERR), $|=1)[0]);
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Config and option parsing {{{
|
# Config and option parsing {{{
|
||||||
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
my $usage = Slack::default_usage("$PROG [options] <role> [<role>...]");
|
||||||
# Option defaults
|
# Option defaults
|
||||||
my %opt = ();
|
my %opt = ();
|
||||||
Slack::get_options(
|
Slack::get_options(
|
||||||
opthash => \%opt,
|
opthash => \%opt,
|
||||||
usage => $usage,
|
usage => $usage,
|
||||||
required_options => [ qw(source cache) ],
|
required_options => [ qw(source cache) ],
|
||||||
);
|
);
|
||||||
|
|
||||||
# Arguments are required
|
# Arguments are required
|
||||||
die "No roles given!\n\n$usage" unless @ARGV;
|
die "No roles given!\n\n$usage" unless @ARGV;
|
||||||
|
|
||||||
# Prepare for backups
|
# Prepare for backups
|
||||||
if ($opt{backup} and $opt{'backup-dir'}) {
|
if ($opt{backup} and $opt{'backup-dir'}) {
|
||||||
# Make sure backup directory exists
|
# Make sure backup directory exists
|
||||||
unless (-d $opt{'backup-dir'}) {
|
unless (-d $opt{'backup-dir'}) {
|
||||||
($opt{verbose} > 0) and print STDERR "Creating backup directory '$opt{'backup-dir'}'\n";
|
($opt{verbose} > 0) and print STDERR "Creating backup directory '$opt{'backup-dir'}'\n";
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
eval { mkpath($opt{'backup-dir'}); };
|
eval { mkpath($opt{'backup-dir'}); };
|
||||||
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
die "Could not mkpath backup dir '$opt{'backup-dir'}': $@\n" if $@;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
push(@rsync, "--backup", "--backup-dir=$opt{'backup-dir'}");
|
||||||
}
|
}
|
||||||
# Look at source type, and add options if necessary
|
# Look at source type, and add options if necessary
|
||||||
if ($opt{'rsh'} or $opt{source} =~ m/^[\w@\.-]+::/) {
|
if ($opt{'rsh'} or $opt{source} =~ m/^[\w@\.-]+::/) {
|
||||||
# This is tunnelled rsync, and so needs an extra option
|
# This is tunnelled rsync, and so needs an extra option
|
||||||
if ($opt{'rsh'}) {
|
if ($opt{'rsh'}) {
|
||||||
push @rsync, '-e', $opt{'rsh'};
|
push @rsync, '-e', $opt{'rsh'};
|
||||||
} else {
|
} else {
|
||||||
push @rsync, '-e', 'ssh';
|
push @rsync, '-e', 'ssh';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Pass options along to rsync
|
# Pass options along to rsync
|
||||||
if ($opt{'dry-run'}) {
|
if ($opt{'dry-run'}) {
|
||||||
push @rsync, '--dry-run';
|
push @rsync, '--dry-run';
|
||||||
}
|
}
|
||||||
# Pass options along to rsync
|
# Pass options along to rsync
|
||||||
if ($opt{'verbose'} > 1) {
|
if ($opt{'verbose'} > 1) {
|
||||||
push @rsync, '--verbose';
|
push @rsync, '--verbose';
|
||||||
}
|
}
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
my @roles = ();
|
my @roles = ();
|
||||||
|
|
||||||
{
|
{
|
||||||
# This hash is just to avoid calling rsync twice if two subroles are
|
# This hash is just to avoid calling rsync twice if two subroles are
|
||||||
# installed. We only care since it's remote, and therefore slow.
|
# installed. We only care since it's remote, and therefore slow.
|
||||||
my %roles_to_sync = ();
|
my %roles_to_sync = ();
|
||||||
|
|
||||||
# copy over the new files
|
# copy over the new files
|
||||||
for my $full_role (@ARGV) {
|
for my $full_role (@ARGV) {
|
||||||
# Get the first element of the role name (the base role)
|
# Get the first element of the role name (the base role)
|
||||||
# e.g., from "google.foogle.woogle", get "google"
|
# e.g., from "google.foogle.woogle", get "google"
|
||||||
my $base_role = (split /\./, $full_role, 2)[0];
|
my $base_role = (split /\./, $full_role, 2)[0];
|
||||||
|
|
||||||
$roles_to_sync{$base_role} = 1;
|
$roles_to_sync{$base_role} = 1;
|
||||||
}
|
}
|
||||||
@roles = keys %roles_to_sync;
|
@roles = keys %roles_to_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $cache = $opt{cache} . "/roles/";
|
my $cache = $opt{cache} . "/roles/";
|
||||||
# Make sure we've got the right perms before we copy stuff down
|
# Make sure we've got the right perms before we copy stuff down
|
||||||
check_cache($cache);
|
check_cache($cache);
|
||||||
|
|
||||||
rsync_source(
|
rsync_source(
|
||||||
$opt{source} . '/roles/',
|
$opt{source} . '/roles/',
|
||||||
$cache,
|
$cache,
|
||||||
@roles,
|
@roles,
|
||||||
);
|
);
|
||||||
|
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
# Make sure the cache directory exists and is mode 0700, to protect files
|
# Make sure the cache directory exists and is mode 0700, to protect files
|
||||||
# underneath in transit
|
# underneath in transit
|
||||||
sub check_cache ($) {
|
sub check_cache ($) {
|
||||||
my ($cache) = @_;
|
my ($cache) = @_;
|
||||||
if (not $opt{'dry-run'}) {
|
if (not $opt{'dry-run'}) {
|
||||||
if (not -d $cache) {
|
if (not -d $cache) {
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Creating '$cache'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Creating '$cache'\n";
|
||||||
eval { mkpath($cache); };
|
eval { mkpath($cache); };
|
||||||
die "Could not mkpath cache dir '$cache': $@\n" if $@;
|
die "Could not mkpath cache dir '$cache': $@\n" if $@;
|
||||||
}
|
}
|
||||||
($opt{verbose} > 0) and print STDERR "$PROG: Checking perms on '$cache'\n";
|
($opt{verbose} > 0) and print STDERR "$PROG: Checking perms on '$cache'\n";
|
||||||
if ($> != 0) {
|
if ($> != 0) {
|
||||||
warn "WARNING[$PROG]: Not superuser; unable to chown files\n";
|
warn "WARNING[$PROG]: Not superuser; unable to chown files\n";
|
||||||
} else {
|
} else {
|
||||||
chown(0, 0, $cache)
|
chown(0, 0, $cache)
|
||||||
or die "Could not chown 0:0 '$cache': $!\n";
|
or die "Could not chown 0:0 '$cache': $!\n";
|
||||||
}
|
}
|
||||||
chmod(0700, $cache)
|
chmod(0700, $cache)
|
||||||
or die "Could not chmod 0700 '$cache': $!\n";
|
or die "Could not chmod 0700 '$cache': $!\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Pull down roles from an rsync source
|
# Pull down roles from an rsync source
|
||||||
sub rsync_source($$@) {
|
sub rsync_source($$@) {
|
||||||
my ($source, $destination, @roles) = @_;
|
my ($source, $destination, @roles) = @_;
|
||||||
my @command = (@rsync, $source, $destination);
|
my @command = (@rsync, $source, $destination);
|
||||||
|
|
||||||
($opt{verbose} > 0)
|
($opt{verbose} > 0)
|
||||||
and print STDERR "$PROG: Syncing cache with '@command'\n";
|
and print STDERR "$PROG: Syncing cache with '@command'\n";
|
||||||
|
|
||||||
my ($fh) = Slack::wrap_rsync_fh(@command);
|
my ($fh) = Slack::wrap_rsync_fh(@command);
|
||||||
|
|
||||||
# Shove the roles down its throat
|
# Shove the roles down its throat
|
||||||
print $fh join("\0", @roles), "\0";
|
print $fh join("\0", @roles), "\0";
|
||||||
|
|
||||||
# Close fh, waitpid, and check return value
|
# Close fh, waitpid, and check return value
|
||||||
unless (close($fh)) {
|
unless (close($fh)) {
|
||||||
Slack::check_system_exit(@command);
|
Slack::check_system_exit(@command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user