Skip to content

Commit

Permalink
changes for macOS Startup (#358)
Browse files Browse the repository at this point in the history
These changes are proposed as a solution to issue #356 and maybe issue #322.

1. Change znapzend startup behavior to die if no zfs snap or backup sets are found.
2. Update init directory to add a launchd template and modify README.md to explain use.
3. Update main README.md to mention XCode command-line tools requirement.
  • Loading branch information
Randy Wilkey authored and oetiker committed May 15, 2018
1 parent 2241557 commit 1a4e66a
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ init/znapzend.service
init/znapzend.sysv
init/znapzend.upstart
init/znapzend.xml
init/org.znapzend.plist
.DS_Store
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ since the installed perl version is probably very old.

On OmniOS/SmartOS you will need perl and gnu-make.

On macOS, if you have not already installed the Xcode command line tools, you can
get them from the command line (Terminal app) with:

xcode-select --install (or just install the full Xcode app from the Apple app store).

With that in place you can now utter:

```sh
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ AC_CONFIG_FILES([
init/znapzend.sysv
init/znapzend.upstart
init/znapzend.xml
init/org.znapzend.plist
])

AC_SUBST(VERSION)
Expand Down
13 changes: 13 additions & 0 deletions init/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ replacing the tags in the corresponding ```.in``` template file
to match your existing system layout (replace ```@BINDIR@``` usually
with ```/usr/local/bin``` to match other setup documentation).

## macOS/launchd

For macOS launchd, you can copy the generated ```org.znapzend.plist```
file to ```/Library/LaunchDaemons``` and then start the daemon with:

```sh
launchctl load /Library/LaunchDaemons/org.znapzend.plist
```

```Note:``` It is recommended to ```not``` set the ```--daemonize``` flag of ```znapzend```
as launchd will lose control of the process. Check out ```init/org.znapzend.plist.in```
for an example plist.

## Solaris/Illumos

For solaris/illumos OSes you can tell configure to install a znapzend
Expand Down
30 changes: 30 additions & 0 deletions init/org.znapzend.plist.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
<key>KeepAlive</key>
<dict>
<key>Crashed</key>
<false/>
</dict>
<key>Label</key>
<string>org.znapzend</string>
<key>ProgramArguments</key>
<array>
<string>@BINDIR@/org.znapzend</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/var/log/org.znapzend.stderr</string>
<key>StandardOutPath</key>
<string>/var/log/org.znapzend.stdout</string>
<key>ThrottleInterval</key>
<integer>30</integer>
</dict>
</plist>
25 changes: 12 additions & 13 deletions lib/ZnapZend.pm
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ my $refreshBackupPlans = sub {
$self->backupSets($self->zConfig->getBackupSetEnabled($dataSet));

@{$self->backupSets}
or $self->zLog->warn("No backup set defined or enabled, yet. run 'znapzendzetup' to setup znapzend");
or die "No backup set defined or enabled, yet. run 'znapzendzetup' to setup znapzend\n";

for my $backupSet (@{$self->backupSets}){
$backupSet->{srcPlanHash} = $self->zTime->backupPlanToHash($backupSet->{src_plan});
Expand Down Expand Up @@ -157,7 +157,7 @@ my $refreshBackupPlans = sub {
for (keys %$backupSet){
my ($key) = /^dst_([^_]+)_plan$/ or next;

#check if destination exists (i.e. is valid) otherwise recheck as dst might be online, now
#check if destination exists (i.e. is valid) otherwise recheck as dst might be online, now
if (!$backupSet->{"dst_$key" . '_valid'}){

$backupSet->{"dst_$key" . '_valid'} =
Expand All @@ -175,7 +175,7 @@ my $refreshBackupPlans = sub {
};
}
$backupSet->{"dst_$key" . '_valid'} or
$self->zLog->warn("destination '" . $backupSet->{"dst_$key"}
$self->zLog->warn("destination '" . $backupSet->{"dst_$key"}
. "' does not exist or is offline. will be rechecked every run...");
};
}
Expand Down Expand Up @@ -227,7 +227,7 @@ my $sendRecvCleanup = sub {
my $sendFailed = 0;
my $startTime = time;
$self->zLog->info('starting work on backupSet ' . $backupSet->{src});

#get all sub datasets of source filesystem; need to send them all individually if recursive
my $srcSubDataSets = $backupSet->{recursive} eq 'on'
? $self->zZfs->listSubDataSets($backupSet->{src}) : [ $backupSet->{src} ];
Expand All @@ -254,7 +254,7 @@ my $sendRecvCleanup = sub {
}
}

#recheck non valid dst as it might be online, now
#recheck non valid dst as it might be online, now
if (!$backupSet->{"dst_$key" . '_valid'}) {

$backupSet->{"dst_$key" . '_valid'} =
Expand Down Expand Up @@ -397,7 +397,7 @@ my $createSnapshot = sub {
local $ENV{ZNAP_TIME} = $timeStamp;

my $skip = 0;

if ($backupSet->{pre_znap_cmd} && $backupSet->{pre_znap_cmd} ne 'off'){
$self->zLog->info("running pre snapshot command on $backupSet->{src}");

Expand Down Expand Up @@ -468,7 +468,7 @@ my $sendWorker = sub {
$fc->on(
spawn => sub {
my ($fc, $pid) = @_;

$self->zLog->debug('send/receive worker for ' . $backupSet->{src}
. " spawned ($pid)");
$backupSet->{send_pid} = $pid;
Expand Down Expand Up @@ -505,7 +505,7 @@ my $snapWorker = sub {
#snapshot worker callback
sub {
my ($fc, $err) = @_;

$self->zLog->warn('taking snapshot on ' . $backupSet->{src}
. ' failed: ' . $err) if $err;

Expand All @@ -528,7 +528,7 @@ my $snapWorker = sub {
$fc->on(
spawn => sub {
my ($fc, $pid) = @_;

$self->zLog->debug('snapshot worker for ' . $backupSet->{src}
. " spawned ($pid)");
$backupSet->{snap_pid} = $pid;
Expand Down Expand Up @@ -662,20 +662,20 @@ sub start {
$self->$refreshBackupPlans($self->dataset);
$self->$createWorkers;
};

$self->$refreshBackupPlans($self->dataset);

$self->$createWorkers;

$self->zLog->info("znapzend (PID=$$) initialized -- resuming normal operations.");

# if Mojo is running with EV, signals will not be received if the IO loop
# is sleeping so lets activate it periodically
# is sleeping so lets activate it periodically
### RM_COMM_4_TEST ### # remove ### RM_COMM_4_TEST ### comments for testing purpose.
### RM_COMM_4_TEST ### if (0) {
Mojo::IOLoop->recurring(1 => sub { }) if not $self->runonce;
### RM_COMM_4_TEST ### }

#start eventloop
Mojo::IOLoop->start;

Expand Down Expand Up @@ -755,4 +755,3 @@ S<Dominik Hassler E<lt>[email protected]<gt>>
2014-05-30 had Initial Version
=cut
10 changes: 7 additions & 3 deletions t/znapzend.t
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ sub runCommand {
}

use Test::More;
use Test::Exception;

use_ok 'ZnapZend';

Expand All @@ -65,12 +66,15 @@ is (runCommand('--help'), 1, 'znapzend help');

is (runCommand(), 1, 'znapzend');

is (runCommand(qw(--runonce=tank/source)), 1, 'znapzend --runonce');
throws_ok { runCommand(qw(--runonce=nosets) ) } qr/No backup set defined or enabled/,
'znapzend dies with no backup sets defined or enabled at startup';

# seems to allow tests to continue so why not?
is (runCommand('--help'), 1, 'znapzend help');

is (runCommand(qw(--daemonize --debug),'--features=oracleMode,recvu',
qw( --pidfile=znapzend.pid)), 1, 'znapzend --daemonize');

done_testing;

1;

1;

0 comments on commit 1a4e66a

Please sign in to comment.