I'm trying to create a simple "Hello World" plugin to test-drive the custom plugin development. The plug-in would execute the command from the parameters (COMMAND), entered in the GUI. For now I have added the command call to the quiesce action.
I have SnapCreator 4.1P1 server installed on Windows server and the client installed on the other Windows server. Both are Windows 2008 R2 x64.
To create the custom plugin, I have done the following:
Server:
Created folder HELLO in C:\Program Files\NetApp\Snap_Creator_Framework\scServer4.1P1\plugins\
Added hello.conf file
#####################################
### SnapCreator Hello World test ###
#####################################
#################################################################################################################
#
#################################################################################################################
APP_NAME=hello
COMMAND=
Created hello.xml in C:\Program Files\NetApp\Snap_Creator_Framework\scServer4.1P1\engine\etc\gui\plugins\simple
It only has one parameter, COMMAND
<?xml version="1.0" encoding="UTF-8"?>
<SimplePlugin xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.netapp.com/snapcreator/ui/client/schema/plugins/simple'
xsi:schemaLocation='http://www.netapp.com/snapcreator/ui/client/schema/plugins/simple com/netapp/snapcreator/ui/xml/simplePlugins.xsd'>
<name>hello</name>
<title>helloTitle</title>
<type>COMMUNITY</type>
<description>helloDescription</description>
<screens>
<screen>
<name>NEW</name>
<params>
<param>COMMAND</param>
</params>
</screen>
<screen>
<name>UPDATE</name>
<params>
<param>COMMAND</param>
</params>
</screen>
</screens>
<params>
<param>
<name>COMMAND</name>
<label>commandLabel</label>
<allowblank>false</allowblank>
<default>echo Hello World!</default>
<description>commandDescription</description>
<type>STRING</type>
</param>
</params>
</SimplePlugin>
Created hello.properties in
C:\Program Files\NetApp\Snap_Creator_Framework\scServer4.1P1\engine\etc\gui\resources
helloTitle=hello
helloDescription=Hello World Script
commandLabel=Command to run
commandDescription=Command to run on the host, such as "echo Hello World!"
The GUI portion works fine, and I can create new profile using the plugin. The application options and plugin parameters get captured in the profile config.
########################################################################################################################
# Application Options #
########################################################################################################################
APP_NAME=hello
########################################################################################################################
# Plug-In Parameter #
########################################################################################################################
COMMAND=echo Hello World!
On the client:
Created hello.pm in C:\Program Files\NetApp\Snap_Creator_Framework\scAgent4.1P1\plugins\perl\hello
It is based on the sample, included with the Snap Creator client
Restarted the Snap Creator client service. Verified the hello plugin is loaded
[2014-04-16T13:37:00,477-0700] INFO [main] com.netapp.snapcreator.agent.nextgen.AgentInitializerImpl - Loaded plugins: [vibe, sybase, domino, mock, arch, oracle, maxdb, hello, xen, smsql, hana, db2, mysql, sme, kvm]
When I try to run the quiesce task, I get the "ERROR: [scf-00070] module [hello] could not be loaded". It is puzzling, because the agent log states the plugin was loaded.
Suspecting there could be something wrong with my code, I have tried to use example scripts, as well as the community scripts in place of my hello.pm.
In this case I get different error:
[2014-04-17 14:11:42,837] ERROR: [vsclc-01:9090(4.1.1.1)] SCF-00037: Application quiesce for plug-in [hello] failed with error [Could not load plugin hello. Reason: Can't locate object method "new" via package "hello" (perhaps you forgot to load "hello"?) at /<C:\Program Files\NetApp\Snap_Creator_Framework\scAgent4.1P1\plugins\wrapper\wrapper.exe>SnapCreator/Mod.pm line 184.
See full debug log below.
[2014-04-17 13:31:32,965] DEBUG: Workflow : quiesce started with workflow id : 67
[2014-04-17 13:31:32,965] DEBUG: Version: Snap Creator Framework 4.1P1
[2014-04-17 13:31:32,965] DEBUG: Profile: hello
[2014-04-17 13:31:32,965] DEBUG: Config: hello
[2014-04-17 13:31:32,965] DEBUG: Action: quiesce
[2014-04-17 13:31:32,965] DEBUG: Plugin: hello
[2014-04-17 13:31:32,965] DEBUG: Policy: null
[2014-04-17 13:31:32,965] DEBUG: Volume Name: cc_backup_test
[2014-04-17 13:31:32,965] DEBUG: Snapshot Name: hello_20140417133132
########## Agent validation ##########
[2014-04-17 13:31:33,652] INFO: Agent validation completed successfully for agent vsclc-01:9090
########## Plugin validation ##########
[2014-04-17 13:31:33,667] INFO: Plugin validation file for plugin hello not found, skipping validation
########## Pre Application Quiesce commands ##########
[2014-04-17 13:31:33,667] INFO: Pre application quiesce commands are not defined
[2014-04-17 13:31:33,667] INFO: Pre Application Quiesce commands finished successfully
[2014-04-17 13:31:33,667] INFO: Application auto discovery is not enabled skipping .
[2014-04-17 13:31:33,667] INFO: Validate volume is not enabled skipping validate volume task.
########## Application Quiesce ##########
[2014-04-17 13:31:33,667] INFO: Application Quiesce for plugin : hello
[2014-04-17 13:31:44,104] ERROR: [vsclc-01:9090(4.1.1.1)] SCF-00037: Application quiesce for plug-in [hello] failed with error [Could not load plugin hello. Reason: ERROR: [scf-00070] module [hello] could not be loaded at /<C:\Program Files\NetApp\Snap_Creator_Framework\scAgent4.1P1\plugins\wrapper\wrapper.exe>SnapCreator/Mod.pm line 182.
] and exit code [99], Exiting!
[2014-04-17 13:31:44,119] DEBUG: Workflow : quiesce_OnFailure started with workflow id : 68
########## Agent Workflow Finalization ##########
[2014-04-17 13:31:44,119] INFO: Agent Workflow Finalization started
[2014-04-17 13:31:49,361] INFO: [vsclc-01:9090 (4.1.1.1)] Finalized workflow with id 67
[2014-04-17 13:31:49,361] INFO: Agent Workflow Finalization finished successfully
########## Snap Creator Framework 4.1P1 failed ##########
[2014-04-17 13:31:49,377] INFO: Pre Exit commands are not defined. Skipping !
The error scf-00037 does make sense. According to the Snap Creator 4.1 Admin Guide:
scf-00037 Application quiesce for plug-in [%s] failed with error [%s] and exit code [%s], Exiting!
Application quiesce failed due to application error. Check logs and application settings. To ignore application errors and proceed with backup, you can set APP_IGNORE_ERROR=Y.
The error scf-00070 in the admin guide is referring to different condition and does not apply here.
scf-00070 File system post_restore for plug-in [%s] failed with exit code [%s], Exiting!
File system post restore failed due to file system error. Check the logs and file system settings.
Am I missing any plugin installation steps? Is 64-bit Java messing with me? Is there something wrong with my code?
I have included hello.pm below for the reference.
Thanks,
Dmitry
hello.pm
#############################################################################
### Copyright NetApp Inc. All rights reserved
### Author: ktenzer
### Date: 08/01/2010
###
### Name: Snap Creator::MOD::Mock
#############################################################################
#############################################################################
# Changes
#############################################################################
### Ver Author Description
### 1.0 ktenzer Initial Version
### 1.1 dmitryse Added running command from config file
#############################################################################
package HELLO;
$| = 1;
our @ISA = qw(Snap Creator::Mod);
use strict;
use warnings;
use diagnostics;
### Load Snap Creator Objects ###
use Snap Creator::Util::Generic qw ( trim isEmpty );
use Snap Creator::Util::OS qw ( isWindows isUnix getUid createTmpFile );
use Snap Creator::Event qw ( INFO ERROR WARN DEBUG COMMENT ASUP CMD DUMP );
my $msgObj = new Snap Creator::Event();
my %config_h = ();
my $result = {
exit_code => 0,
stdout => 'Finished successfully',
stderr => ''
};
sub new {
my $invocant = shift;
my $class = ref($invocant) || $invocant;
my $self = {
@_
};
bless ($self, $class);
return $self;
}
sub setENV {
my ($self, $obj) = @_;
%config_h = %{$obj};
my @message_a = ();
$msgObj->collect(\@message_a, INFO, "$config_h{'APP_NAME'}::setENV");
$result->{message} = \@message_a;
return $result;
}
sub quiesce {
my $self = shift;
my $result = {
exit_code => 0,
stdout => "",
stderr => "",
};
my $cmd = ();
my @message_a = ();
my $error_code="0";
$msgObj->collect(\@message_a, INFO, "Running quiesce");
#Send command
if (defined $config_h{'COMMAND'}) {
$cmd="$config_h{'COMMAND'}";
} else {
$cmd="echo Hello World!";
}
}
$result = $RUN_CMD->($cmd);
push (@message_a, @{$result->{message}}) if exists ($result->{message});
if ($result->{exit_code} != 0) {
$msgObj->collect(\@message_a, ERROR, "Executing command finished with errors");
} else {
$msgObj->collect(\@message_a, INFO, "Command executed successfully");
}
END:
$result->{message} = \@message_a;
return $result;
}
sub unquiesce {
my $result = {
exit_code => 0,
stdout => "",
stderr => "",
};
my @message_a = ();
$msgObj->collect(\@message_a, INFO, "$config_h{'APP_NAME'}::unquiesce");
$result->{message} = \@message_a;
return $result;
}
sub discover {
my $result = {
exit_code => 0,
stdout => "",
stderr => "",
};
my @message_a = ();
$msgObj->collect(\@message_a, INFO, "$config_h{'APP_NAME'}::discovery");
$result->{message} = \@message_a;
return $result;
}
########################################
### Private Methods (local use only) ###
########################################
### Run Commands ###
$RUN_CMD=sub {
my ($cmd) = @_;
my $result = {
exit_code => 0,
stdout => "",
stderr => ""
};
my @message_a = ();
$msgObj->collect(\@message_a, DEBUG, "Executing command [$cmd]");
$result = SnapCreator::Util::OS->execute($cmd);
$msgObj->collect(\@message_a, DEBUG, "Command [$cmd] finished with\nexit code: [$result->{exit_code}]\nstdout: [$result->{stdout}]\nstderr: [$result->{stderr}]");
# Error logging
if (! defined ($result) || $result->{exit_code} != 0) {
$msgObj->collect(\@message_a, ERROR, "[hello-00001] Command [$cmd] failed with return code $result->{exit_code} and message $result->{stderr}");
} else {
$msgObj->collect(\@message_a, DEBUG, "Executing of external command finished successfully");
}
$result->{message} = \@message_a;
return $result;
};
1;