commit - 5413554083a9dca6bbfb3e043e73e6325c3d53f6
commit + 3b56f81c2a7ba1f40a6b2f6a057b17501957e549
blob - af3e377b932594e963ec7aec92c47e3902eded4d
blob + 438b2c1c652543466e89365170c4e90dc7180947
--- bin/configNow.pl
+++ bin/configNow.pl
use File::Basename;
use File::Path qw(make_path);
-my $account = shift || 'blacklock';
-my @users = qw( izzyb nathan ashley );
+
+my $account = shift || die "Usage: $0 <account> <user1> <user2> <user3> <...>\n";
+my $users = \@ARGV;
+# Temporary hack to support custom Domains
+my $custDomain;
+$custDomain = 'bnsnet.ca' if ($account eq 'blacklock');
+
my $domain = 'user.planetofnix.com';
-my $custDomain = 'bnsnet.ca';
my %config=(
type=>'shell',
account => $account,
- users => \@users,
+ users => $users,
gitAuthor => $account,
gitEmail => $account . "@" . $domain,
- gitWorkDir => './configNow',
+ gitWorkDir => "./configNow/$account",
ipv4 => '38.87.162.191',
ipv6 => '2602:fccf:1:1191::',
domain => $domain,
StageDir => './stageNow',
DeployDir => './deployNow/',
Accounts => [ $account ], # List of accounts to deploy
-
);
my $shellConfig = new IRCNOW::ConfigNow( %config );
if ($shellConfig->stage_ready()) { # Verify stage repo is ready
+}
print "Deploying config Change.\n";
- $shellConfig->stage_pull($account => '../configNow');
+ $shellConfig->stage_pull($account => "../configNow/$account");
$shellConfig->stage_merge();
$shellConfig->stage_commit();
$shellConfig->deploy_system();
-}
+
# Get list of files changed in a diff
#$r->run(qw(git diff 0cd562e --name-only));
blob - /dev/null
blob + de69b88350a3ff90f95af40634cc1bc914793005 (mode 644)
--- /dev/null
+++ Templates/etc/acme-client.conf_HEAD
+#
+# $OpenBSD: acme-client.conf,v 1.1 2019/01/08 07:14:10 florian Exp $
+#
+authority letsencrypt {
+ api url "https://acme-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-privkey.pem"
+}
+
+authority letsencrypt-staging {
+ api url "https://acme-staging-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-staging-privkey.pem"
+}
+
+authority buypass {
+ api url "https://api.buypass.com/acme/directory"
+ account key "/etc/acme/buypass-privkey.pem"
+ contact "mailto:support@planetofnix.com"
+}
+
+authority buypass-test {
+ api url "https://api.test4.buypass.no/acme/directory"
+ account key "/etc/acme/buypass-test-privkey.pem"
+ contact "mailto:support@planetofnix.com"
+}
+
+
blob - /dev/null
blob + 27ffe761684ec54b98e8d08fbe80cdf5486d38df (mode 644)
--- /dev/null
+++ Templates/etc/prosody/prosody.cfg.lua_HEAD
+-- Prosody Example Configuration File
+--
+-- Information on configuring Prosody can be found on our
+-- website at https://prosody.im/doc/configure
+--
+-- Tip: You can check that the syntax of this file is correct
+-- when you have finished by running this command:
+-- prosodyctl check config
+-- If there are any errors, it will let you know what and where
+-- they are, otherwise it will keep quiet.
+--
+-- The only thing left to do is rename this file to remove the .dist ending, and fill in the
+-- blanks. Good luck, and happy Jabbering!
+
+
+---------- Server-wide settings ----------
+-- Settings in this section apply to the whole server and are the default settings
+-- for any virtual hosts
+
+-- This is a (by default, empty) list of accounts that are admins
+-- for the server. Note that you must create the accounts separately
+-- (see https://prosody.im/doc/creating_accounts for info)
+-- Example: admins = { "user1@example.com", "user2@example.net" }
+admins = {"izzyb@user.planetofnix.com"}
+support_contact = "izzyb@user.planetofnix.com"
+contact_info = {
+ abuse = { "mailto:abuse@planetofnix.com", "xmpp:izzyb@user.planetofnix.com" };
+ support = { "mailto:support@planetofnix.com", "xmpp:izzyb@user.planetofnix.com" };
+}
+-- Drop privileges
+prosody_user = "_prosody"
+prosody_group = "_prosody"
+
+-- Enable POSIX-only options
+pidfile = "/var/prosody/prosody.pid"
+
+-- This option allows you to specify additional locations where Prosody
+-- will search first for modules. For additional modules you can install, see
+-- the community module repository at https://modules.prosody.im/
+--plugin_paths = {}
+plugin_paths = { "/usr/local/lib/prosody/extras/" }
+-- This is the list of modules Prosody will load on startup.
+-- Documentation for bundled modules can be found at: https://prosody.im/doc/modules
+modules_enabled = {
+
+ -- Generally required
+ "disco"; -- Service discovery
+ "roster"; -- Allow users to have a roster. Recommended ;)
+ "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
+ "tls"; -- Add support for secure TLS on c2s/s2s connections
+
+ -- Not essential, but recommended
+ "blocklist"; -- Allow users to block communications with other users
+ "carbons"; -- Keep multiple online clients in sync
+ "dialback"; -- Support for verifying remote servers using DNS
+ "limits"; -- Enable bandwidth limiting for XMPP connections
+ "pep"; -- Allow users to store public and private data in their account
+ "private"; -- Legacy account storage mechanism (XEP-0049)
+ "smacks"; -- Stream management and resumption (XEP-0198)
+ "vcard4"; -- User profiles (stored in PEP)
+ "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard
+
+ -- Nice to have
+ "csi_simple"; -- Simple but effective traffic optimizations for mobile devices
+ "invites"; -- Create and manage invites
+ "invites_adhoc"; -- Allow admins/users to create invitations via their client
+ "invites_register"; -- Allows invited users to create accounts
+ "ping"; -- Replies to XMPP pings with pongs
+ "time"; -- Let others know the time here on this server
+ "uptime"; -- Report how long server has been running
+ "version"; -- Replies to server version requests
+ "mam"; -- Store recent messages to allow multi-device synchronization
+ --"turn_external"; -- Provide external STUN/TURN service for e.g. audio/video calls
+
+ -- Admin interfaces
+ "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
+ "admin_shell"; -- Allow secure administration via 'prosodyctl shell'
+
+ -- HTTP modules
+ "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP"
+ --IB Found on ircnow
+ --"http_files"; -- Serve static files from a directory over HTTP
+ --IB not on ircnow XXX
+ "http_openmetrics"; -- for exposing metrics to stats collectors
+ "websocket"; -- XMPP over WebSockets
+
+ -- Other specific functionality
+ "announce"; -- Send announcement to all online users
+ "groups"; -- Shared roster support
+ --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots.
+ --"mimicking"; -- Prevent address spoofing
+ --"motd"; -- Send a message to users when they log in
+ "proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use
+ --"s2s_bidi"; -- Bi-directional server-to-server (XEP-0288)
+ "server_contact_info"; -- Publish contact information for this service
+ --"tombstones"; -- Prevent registration of deleted accounts
+ "watchregistrations"; -- Alert admins of registrations
+ "welcome"; -- Welcome users who register accounts
+
+ -- Found on ircnow.org
+ "bookmarks2"; -- required for compliance
+ "cloud_notify"; -- Support push notifications
+ "csi"; -- Reduce network usage
+ "filter_chatstates"; -- filter chat states during inactivity
+ "smacks"; -- Improve experience on unstable networks
+ "filter_chatstates"; -- filter chat states during inactivity
+ "auto_accept_subscriptions"; -- Auto accept subscriptions
+ --"group_bookmarks"; -- Group bookmarks
+ --"deny_omemo"; -- Deny OMEMO
+ --"roster_allinall"; -- Add everyone in roster
+ --"block_registrations"; -- block registrations using regex
+ "support_contact"; -- support contact
+ --"captcha_registration";
+ --"throttle_unsolicited"; -- throttle unsolicited messages
+ --"bookmarks";
+ "lastactivity"; -- handy, mkf
+ --"firewall";
+
+
+}
+
+-- These modules are auto-loaded, but should you want
+-- to disable them then uncomment them here:
+modules_disabled = {
+ -- "offline"; -- Store offline messages
+ -- "c2s"; -- Handle client connections
+ -- "s2s"; -- Handle server-to-server connections
+ -- "posix"; -- POSIX functionality, sends server to background, etc.
+}
+
+
+-- Server-to-server authentication
+-- Require valid certificates for server-to-server connections?
+-- If false, other methods such as dialback (DNS) may be used instead.
+--IB changed to false to match ircnow.org
+s2s_secure_auth = false
+
+
+
+-- Some servers have invalid or self-signed certificates. You can list
+-- remote domains here that will not be required to authenticate using
+-- certificates. They will be authenticated using other methods instead,
+-- even when s2s_secure_auth is enabled.
+
+--s2s_insecure_domains = { "insecure.example" }
+
+-- Even if you disable s2s_secure_auth, you can still require valid
+-- certificates for some domains by specifying a list here.
+
+--s2s_secure_domains = { "jabber.org" }
+
+--IB Found on ircnow.org
+-- Force clients to use encrypted connections? This option will
+-- prevent clients from authenticating unless they are using encryption.
+
+c2s_require_encryption = true
+
+-- Force servers to use encrypted connections? This option will
+-- prevent servers from authenticating unless they are using encryption.
+
+s2s_require_encryption = true
+
+-- required for compliance, enables support in legacy clients
+legacy_ssl_ports = { 5223 }
+legacy_ssl_ssl = {
+ key = "/etc/prosody/certs/xmpp.user.planetofnix.com.key";
+ certificate = "/etc/prosody/certs/xmpp.user.planetofnix.com.fullchain.pem";
+}
+
+--IB ----------------
+
+
+-- Rate limits
+-- Enable rate limits for incoming client and server connections. These help
+-- protect from excessive resource consumption and denial-of-service attacks.
+
+limits = {
+ c2s = {
+ rate = "10kb/s";
+ };
+ s2sin = {
+ rate = "30kb/s";
+ };
+}
+
+-- Authentication
+-- Select the authentication backend to use. The 'internal' providers
+-- use Prosody's configured data storage to store the authentication data.
+-- For more information see https://prosody.im/doc/authentication
+
+authentication = "internal_hashed"
+
+-- Many authentication providers, including the default one, allow you to
+-- create user accounts via Prosody's admin interfaces. For details, see the
+-- documentation at https://prosody.im/doc/creating_accounts
+
+
+-- Storage
+-- Select the storage backend to use. By default Prosody uses flat files
+-- in its configured data directory, but it also supports more backends
+-- through modules. An "sql" backend is included by default, but requires
+-- additional dependencies. See https://prosody.im/doc/storage for more info.
+
+--storage = "sql" -- Default is "internal"
+
+-- For the "sql" backend, you can uncomment *one* of the below to configure:
+--sql = { driver = "SQLite3", database = "prosody.sqlite" } -- Default. 'database' is the filename.
+--sql = { driver = "MySQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" }
+--sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" }
+
+
+-- Archiving configuration
+-- If mod_mam is enabled, Prosody will store a copy of every message. This
+-- is used to synchronize conversations between multiple clients, even if
+-- they are offline. This setting controls how long Prosody will keep
+-- messages in the archive before removing them.
+
+archive_expires_after = "4w" -- Remove archived messages after 1 week
+
+-- You can also configure messages to be stored in-memory only. For more
+-- archiving options, see https://prosody.im/doc/modules/mod_mam
+
+
+-- Audio/video call relay (STUN/TURN)
+-- To ensure clients connected to the server can establish connections for
+-- low-latency media streaming (such as audio and video calls), it is
+-- recommended to run a STUN/TURN server for clients to use. If you do this,
+-- specify the details here so clients can discover it.
+-- Find more information at https://prosody.im/doc/turn
+
+-- Specify the address of the TURN service (you may use the same domain as XMPP)
+--turn_external_host = "turn.example.com"
+
+-- This secret must be set to the same value in both Prosody and the TURN server
+--turn_external_secret = "your-secret-turn-access-token"
+
+
+-- Logging configuration
+-- For advanced logging see https://prosody.im/doc/logging
+log = {
+ info = "/var/prosody/prosody.log"; -- Change 'info' to 'debug' for verbose logging
+ error = "/var/prosody/prosody.err";
+ -- "*syslog"; -- Uncomment this for logging to syslog
+ -- "*console"; -- Log to the console, useful for debugging when running in the foreground
+}
+-- Uncomment to enable statistics
+-- For more info see https://prosody.im/doc/statistics
+-- statistics = "internal"
+
+
+-- Certificates
+-- Every virtual host and component needs a certificate so that clients and
+-- servers can securely verify its identity. Prosody will automatically load
+-- certificates/keys from the directory specified here.
+-- For more information, including how to use 'prosodyctl' to auto-import certificates
+-- (from e.g. Let's Encrypt) see https://prosody.im/doc/certificates
+
+-- Location of directory to find certificates in (relative to main config file):
+certificates = "certs"
+
+--IB Found on ircnow.org
+-- HTTPS currently only supports a single certificate, specify it here:
+-- Expects to find the key in same name .key
+https_certificate = "/etc/prosody/certs/xmpp.user.planetofnix.com.crt"
+
+----------- Virtual hosts -----------
+-- You need to add a VirtualHost entry for each domain you wish Prosody to serve.
+-- Settings under each VirtualHost entry apply *only* to that host.
+--IB for shellname@user.plantofnix.com addresses
+VirtualHost "user.planetofnix.com"
+
+key = "/etc/prosody/certs/xmpp.user.planetofnix.com.key"
+certificate = "/etc/prosody/certs/xmpp.user.planetofnix.com.fullchain.pem"
+--IB Found on ircnow.org
+disco_items = {
+ { "xmpp.user.planetofnix.com" },
+}
+http_host = "xmpp.user.planetofnix.com"
+--http_default_host = "ircnow.org"
+http_upload_access = {"xmpp.user.planetofnix.com"};
+http_upload_file_size_limit = 200*1024*1024 -- 200MB
+http_upload_expire_after = 60 * 60 * 24 * 60 -- 60 days in sec
+
+----- Components ------
+-- You can specify components to add hosts that provide special services,
+-- like multi-user conferences, and transports.
+-- For more information on components, see https://prosody.im/doc/components
+
+---Set up a MUC (multi-user chat) room server on conference.example.com:
+Component "xmpp.user.planetofnix.com" "muc"
+--- Store MUC messages in an archive and allow users to access it
+modules_enabled = {
+ "muc_mam",
+ "vcard_muc", -- profile photos for groups
+ }
+
+---Set up an external component (default component port is 5347)
+--
+-- External components allow adding various services, such as gateways/
+-- transports to other networks like ICQ, MSN and Yahoo. For more info
+-- see: https://prosody.im/doc/components#adding_an_external_component
+--
+Component "xmpp.user.planetofnix.com"
+ component_secret = "redacted"
+
+Component "xmpp.user.planetofnix.com" "http_upload"
+
+
blob - /dev/null
blob + 28ad757f1207e3869b63b7f8cb1b2991bcb475ed (mode 644)
--- /dev/null
+++ Templates/var/nsd/zones/master/user.planetofnix.com_HEAD
+$ORIGIN user.planetofnix.com.
+user.planetofnix.com. 3600 SOA ns1.user.planetofnix.com. root.planetofnix.com. (
+ 2023083101 ; serial YYYYMMDDnn
+ 1800 ; refresh
+ 3600 ; retry
+ 86400 ; expire
+ 3600 ) ; minimum TTL
+ 3600 IN A 38.87.162.191
+ 3600 IN AAAA 2602:fccf:1:1191::
+ 3600 IN NS ns1
+ 3600 IN NS ns2
+ 3600 IN MX 10 mail
+ns1 3600 IN A 198.251.81.44
+ 3600 IN AAAA 2605:6400:10:69d::
+ns2 3600 IN A 198.251.81.44
+ 3600 IN AAAA 2605:6400:10:69d::
+mail 3600 IN A 38.87.162.191
+ 3600 IN AAAA 2602:fccf:1:1191::
+imap 3600 IN A 38.87.162.191
+ 3600 IN AAAA 2602:fccf:1:1191::
+pop 3600 IN A 38.87.162.191
+ 3600 IN AAAA 2602:fccf:1:1191::
+pop3 3600 IN A 38.87.162.191
+ 3600 IN AAAA 2602:fccf:1:1191::
+smtp 3600 IN A 38.87.162.191
+ 3600 IN AAAA 2602:fccf:1:1191::
+_adsp._domainkey 3600 IN TXT "dkim=discardable;"
+_mail._domainkey 3600 IN TXT "k=rsa; t-s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJkGACi9cbYFFUYZ8Kn/UfVuveop1v9FD1jQGwWkIO3s5DMo+1uhOwsMtHfpOFzfIZrQAwNP8g/X4Gi7QRt/OIPRgPM6qV1vhABCXFzisYd/3hiMpPigK1n+0iagKJdFbvSw8RDroPk4G/63nJsg4vbda1R+zNEKeZeUv3xgu/eQIDAQAB"
+xmpp 3600 IN A 38.87.162.191
+ 3600 IN AAAA 2602:fccf:1:1191::
+_xmpp-client._tcp 3600 IN SRV 0 5 5222 xmpp
+_xmpp-server._tcp 3600 IN SRV 0 5 5269 xmpp
+
blob - 2deb07066ae0be4666ae274b8a37d42ec46dad7b
blob + 44aa8bccf65653533ff64d8936004738a8f50322
--- lib/IRCNOW/ConfigNow.pm
+++ lib/IRCNOW/ConfigNow.pm
$self->mod_load('mail','IRCNOW::ConfigNow::Module::SmtpDove');
$self->mod_load('xmpp','IRCNOW::ConfigNow::Module::Prosody');
$self->mod_load('acme','IRCNOW::ConfigNow::Module::AcmeClient');
- $self->mod_load('custDomain','IRCNOW::ConfigNow::Module::CustDomain');
+ if (defined $vars->{custDomain}) {
+ $self->mod_load('custDomain','IRCNOW::ConfigNow::Module::CustDomain');
+ }
}
return $self;
}
sub write_file {
my $self = shift;
my $filename = shift;
- my $workDir=$self->{vars}->{gitWorkDir};
- $filename = "$workDir/$filename";
my $output = shift;
+ my $workDir = shift || $self->{vars}->{gitWorkDir} || die 'No work directory specified';
+ $filename = "$workDir/$filename";
my $path = dirname($filename);
-#print "Making Directory: $path\n";
make_path($path);
-print "Writing: $filename\n";
- #XXX add proper error handling
- open my $FH, ">>$filename";
+ open my $FH, ">>$filename" || die "failed to open $filename for appending";
print $FH $output;
close $FH;
}
+sub read_file {
+ my $self = shift;
+ my $filename = shift;
+ my $workDir = shift || $self->{vars}->{gitWorkDir} || die 'No work directory specified';
+ $filename = "$workDir/$filename";
+ my $output="";
+ open (my $FH, "<$filename") || die "failed to open $filename for reading";
+ while (<$FH>) {
+ $output.= $_;
+ }
+ close $FH;
+ return $output;
+}
+
# Delete specified file
sub delete_file {
my $self = shift;
my $filename = shift;
- my $workDir=$self->{vars}->{gitWorkDir};
+ my $workDir= shift || $self->{vars}->{gitWorkDir};
$filename = "$workDir/$filename";
-print "Deleting $filename\n";
unlink $filename;
}
}
# Output for $type = "custDomain"
if (exists $self->{vars}->{custDomain}) {
-warn "custDomain: $filename";
# generate output for type = 'custDomain'
my $out = $obj->output($filename, 'custDomain');
$output .= $out if defined $out;
my $config=$self->{vars};
my $dir = shift || $config->{gitWorkDir};
return $self->{$repo} if defined $self->{$repo};
- $self->{$repo} = Git::Repository->new(
+ my $r = Git::Repository->new(
work_tree => $dir,
{
env => {
},
},
);
- # Ready for changes.
- return $self->{$repo};
+ # don't save temp repos.
+ $self->{$repo} = $r unless ($repo eq 'tmp');
+ return $r;
}
sub repo_commit {
my $self=shift;
- my $r = $self->{repo};
- my $workDir = $self->{vars}->{gitWorkDir};
+ my $repo = shift || 'repo';
+ my $workDir = shift || $self->{vars}->{gitWorkDir};
+ my $r = $self->{$repo} || $self->repo_connect($repo,$workDir);
# Check status of untracked files.
my $update=0; # Flag for changes to commit
my @output = $r->run(qw(status -su));
} else {
print "... ignoring $1\n";
}
- } elsif ($file =~ /^\s+M\s+/) {
+ } elsif ($file =~ /^\s?[MA]\s+/) { # File modified or added thats already tracked
$update = 1;
}
}
# Initialize the config repo if it hasn't been created yet.
make_path($workDir);
make_path("$workDir/Accounts");
- make_path("$workDir/Stage");
+ make_path("$workDir/Templates");
+ make_path("$workDir/Staged");
+ # XXX cheap hack to copy template files - should do this without the system()
+ system("cp -av ./Templates/* $workDir/Templates/");
Git::Repository->run(init => $workDir);
}
$r = $self->repo_connect('stage_repo', $workDir);
sub stage_pull {
my $self=shift;
my ($account, $upstream) = @_;
- my $r = $self->{stage_repo};
my $account_repo="Accounts/$account";
- if (not -d $account_repo) {
+ if (not -d $self->{vars}->{StageDir} . "/$account_repo") {
# Don't have this account so clone it
- my @status = $r->run("submodule","add", $upstream,$account_repo);
- use Data::Dumper;
- print Dumper(@status);
- return 1;
+ my $r = $self->{stage_repo};
+ my @results = $r->run("submodule","add", $upstream, $account_repo);
+ } else {
+ my $r = $self->repo_connect('tmp',$self->{vars}->{StageDir} . "/$account_repo");
+ my @results = $r->run("pull");
}
}
+# Find any _HEAD templates for given file
+sub template_head {
+ my $self = shift;
+ my $filename=shift;
+ my $templates=$self->{vars}->{StageDir} . '/Templates';
+ my $output = "";
+ if (-e "$templates/$filename" . "_HEAD") {
+print "Reading: $templates/$filename" . "_HEAD\n";
+ open (my $FH, "<$templates/$filename" . "_HEAD");
+ while (<$FH>) {
+ $output.=$_;
+ }
+ close $FH;
+ }
+ return $output;
+}
+
+
+
+
sub stage_merge {
+ my $self = shift;
+ # # abort of the repo isn't ready
+ # return 0 unless $self->repo_ready();
+ # get the output for each module for this filename.
+ my $stagedDir=$self->{vars}->{StageDir} . "/Staged";
+ my $accountsDir = $self->{vars}->{StageDir} . "/Accounts";
+ for my $filename ($self->filenames()) {
+ #purge existing files before generation.
+ $self->delete_file($filename,$stagedDir);
+ # Output template header if one exists
+ my $output=$self->template_head($filename);
+ # Find configNow repos with content for this filename
+ opendir(my $DH, $accountsDir) || die "can't open directory $accountsDir: $!";
+ while (readdir $DH) {
+ next if $_ =~ /^\./;
+ if (-d "$accountsDir/$_" and -e "$accountsDir/$_/$filename") {
+ $output .= $self->read_file($filename, "$accountsDir/$_");
+ }
+ }
+ closedir $DH;
+ $self->write_file($filename, $output, $stagedDir)
+ }
+
+# my $out = $obj->output($filename,$type);
+# $output .= $out if defined $out;
+# # Output for $type . "users" if we have a user list
+# if (exists $self->{vars}->{users}) {
+# for my $user (@{$self->{vars}->{users}}) {
+# # set the username var to this user.
+# $self->{vars}->{username} = $user;
+# # generate output for $type . 'user'
+# my $out = $obj->output($filename,$type . "user");
+# $output .= $out if defined $out;
+# # delete the username so it doesn't bleed anywhere
+# delete $self->{vars}->{username};
+# }
+# }
+# # Output for $type = "custDomain"
+# if (exists $self->{vars}->{custDomain}) {
+#warn "custDomain: $filename";
+# # generate output for type = 'custDomain'
+# my $out = $obj->output($filename, 'custDomain');
+# $output .= $out if defined $out;
+# }
+# }
+# if (length($output)>0) { # Should we support empty files?
+# $self->write_file($filename,$output);
+# }
+# }
+# return 1;
}
+
+
+
+
sub stage_commit {
+ my $self = shift;
+print "stage_commit(): " . $self->{vars}->{StageDir} . "\n";
+ return $self->repo_commit('stage_repo',$self->{vars}->{StageDir});
+
+
}
+
+
sub deploy_system {
}