TODO(unfinished) selftest: Samba3: add a clusteredmember environment
authorMichael Adam <obnox@samba.org>
Thu, 20 Oct 2011 10:58:43 +0000 (12:58 +0200)
committerMichael Adam <obnox@samba.org>
Thu, 26 Sep 2013 00:19:24 +0000 (02:19 +0200)
selftest/target/Samba3.pm

index 2f23ae3c1687545b44ffe36ebc7153b70bfbe915..4bcbfb798f3ad9b0a7ae965dbaa9cc7b740fe436 100755 (executable)
@@ -43,6 +43,22 @@ sub teardown_env($$)
        $self->stop_sig_kill($nmbdpid);
        $self->stop_sig_kill($winbinddpid);
 
+       if (defined($envvars->{ctdb_vars})) {
+               $self->teardown_env_ctdb($envvars->{ctdb_vars});
+       }
+
+       return 0;
+}
+
+sub teardown_env_ctdb($$)
+{
+       my ($self, $envvars) = @_;
+
+       my $ctdbdpid = read_pid($envvars, "ctdbd");
+       $self->stop_sig_term($ctdbdpid);
+       sleep(2);
+       $self->stop_sig_kill($ctdbdpid);
+
        return 0;
 }
 
@@ -53,6 +69,10 @@ sub getlog_env_app($$$)
        my $title = "$name LOG of: $envvars->{NETBIOSNAME}\n";
        my $out = $title;
 
+       unless (exists($envvars->{$name."_TEST_LOG"})) {
+               die "getlog_env_app: \$envvars->{".$name."_TEST_LOG} not set\n";
+       }
+
        open(LOG, "<".$envvars->{$name."_TEST_LOG"});
 
        seek(LOG, $envvars->{$name."_TEST_LOG_POS"}, SEEK_SET);
@@ -79,6 +99,14 @@ sub getlog_env($$)
        return $ret;
 }
 
+sub getlog_env_ctdb($$)
+{
+       my ($self, $envvars) = @_;
+       my $ret = "";
+
+       $ret .= $self->getlog_env_app($envvars, "CTDBD");
+}
+
 sub check_env($$)
 {
        my ($self, $envvars) = @_;
@@ -91,6 +119,10 @@ sub setup_env($$$)
 {
        my ($self, $envname, $path) = @_;
        
+       print "\n";
+       print "<<<OBNOX>>> - Samba3::setup_env called for '$envname'\n";
+       print "\n";
+
        if ($envname eq "s3dc") {
                return $self->setup_s3dc("$path/s3dc");
        } elsif ($envname eq "secshare") {
@@ -113,6 +145,14 @@ sub setup_env($$$)
                        }
                }
                return $self->setup_member("$path/member", $self->{vars}->{s3dc});
+       } elsif ($envname eq "clusteredmember") {
+               if (not defined($self->{vars}->{s3dc})) {
+                       if (not defined($self->setup_s3dc("$path/s3dc"))) {
+                               return undef;
+                       }
+               }
+               return $self->setup_clusteredmember("$path/clusteredmember",
+                                                   $self->{vars}->{s3dc});
        } else {
                return undef;
        }
@@ -200,6 +240,69 @@ sub setup_member($$$)
        return $ret;
 }
 
+sub setup_clusteredmember($$$$)
+{
+       my ($self, $prefix, $s3dcvars) = @_;
+       my $swiface = 8;
+
+       print "PROVISIONING CLUSTEREDMEMBER...";
+
+       my $ctdbprefix = "$prefix/ctdb";
+       my $sambaprefix = "$prefix/samba";
+       my $server_name = "CLUSTEREDMEMBER";
+
+       my $ctdb_vars = $self->setup_ctdb($ctdbprefix, $swiface, $server_name);
+
+       $ctdb_vars or return undef;
+
+       my $member_options = "
+       security = domain
+       server signing = on
+       clustering = yes
+       ctdbd socket = $ctdb_vars->{SOCKET_FILE}
+";
+       my $ret = $self->provision($sambaprefix,
+                                  $server_name,
+                                  $swiface,
+                                  "clustermember8pass",
+                                  $member_options);
+
+       $ret or return undef;
+
+       print "<<<OBNOX>>> CLUSTEREDMEMBER: provision done. joining...\n";
+
+       my $net = Samba::bindir_path($self, "net");
+       my $cmd = "";
+       $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
+       $cmd .= "$net join $ret->{CONFIGURATION} $s3dcvars->{DOMAIN} member";
+       $cmd .= " -U$s3dcvars->{USERNAME}\%$s3dcvars->{PASSWORD}";
+
+       if (system($cmd) != 0) {
+           warn("Join failed\n$cmd");
+           return undef;
+       }
+
+       $self->check_or_start($ret, "yes", "yes", "yes");
+
+       if (not $self->wait_for_start($ret)) {
+              return undef;
+       }
+
+       $ret->{DC_SERVER} = $s3dcvars->{SERVER};
+       $ret->{DC_SERVER_IP} = $s3dcvars->{SERVER_IP};
+       $ret->{DC_NETBIOSNAME} = $s3dcvars->{NETBIOSNAME};
+       $ret->{DC_USERNAME} = $s3dcvars->{USERNAME};
+       $ret->{DC_PASSWORD} = $s3dcvars->{PASSWORD};
+
+       $ret->{CTDB_SOCKET_FILE} = $ctdb_vars->{SOCKET_FILE};
+
+       $ret->{ctdb_vars} = $ctdb_vars;
+
+       $self->{vars}->{clusteredmember} = $ret;
+
+       return $ret;
+}
+
 sub setup_admember($$$$)
 {
        my ($self, $prefix, $dcvars, $iface) = @_;
@@ -556,7 +659,7 @@ sub read_pid($$)
        return $pid;
 }
 
-sub check_or_start($$$$$) {
+sub check_or_start($$$$) {
        my ($self, $env_vars, $nmbd, $winbindd, $smbd) = @_;
 
        unlink($env_vars->{NMBD_TEST_LOG});
@@ -1047,7 +1150,10 @@ domusers:X:$gid_domusers:
        $ENV{NSS_WRAPPER_PASSWD} = $nss_wrapper_passwd;
        $ENV{NSS_WRAPPER_GROUP} = $nss_wrapper_group;
 
-        my $cmd = Samba::bindir_path($self, "smbpasswd")." -c $conffile -L -s -a $unix_name > /dev/null";
+        my $cmd = "";
+       $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$swiface\" ";
+       $cmd .= Samba::bindir_path($self, "smbpasswd")." -c $conffile -L -s -a $unix_name > /dev/null";
+       print "<<<OBNOX>>> provision: running smbpasswd ('$cmd')...";
        unless (open(PWD, "|$cmd")) {
              warn("Unable to set password for test account\n$cmd");
              return undef;
@@ -1057,6 +1163,7 @@ domusers:X:$gid_domusers:
              warn("Unable to set password for test account\n$cmd");
              return undef; 
         }
+       print"DONE(smbpasswd)...";
        print "DONE\n";
 
        open(HOSTS, ">>$ENV{SELFTEST_PREFIX}/dns_host_file") or die("Unable to open $ENV{SELFTEST_PREFIX}/dns_host_file");
@@ -1137,4 +1244,250 @@ sub wait_for_start($$)
        return 1;
 }
 
+
+##
+## provision and start of ctdb
+##
+
+sub setup_ctdb($$$$)
+{
+       my ($self, $prefix, $public_if, $server_name) = @_;
+
+       print "PROVISIONING CTDB...";
+
+       my $vars = $self->provision_ctdb($prefix, $public_if, $server_name);
+
+       $vars or return undef;
+
+       $self->check_or_start_ctdb($vars);
+
+       if (not $self->wait_for_start_ctdb($vars)) {
+               return undef;
+       }
+
+       return $vars;
+}
+
+sub check_or_start_ctdb($$) {
+       my ($self, $env_vars) = @_;
+
+       unlink($env_vars->{CTDBD_TEST_LOG});
+       print "STARTING CTDBD...";
+       my $pid = fork();
+       if ($pid == 0) {
+               open STDOUT, ">$env_vars->{CTDBD_TEST_LOG}";
+               open STDERR, '>&STDOUT';
+
+               SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
+
+               my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
+               @preargs = ();
+               if(defined($ENV{CTDBD_VALGRIND})) {
+                       @preargs = split(/ /, $ENV{CTDBD_VALGRIND});
+               }
+
+               exec(@preargs, "$env_vars->{BINDIR}/ctdbd",
+                       "--socket=$env_vars->{SOCKET_FILE}",
+                       "--reclock=$env_vars->{RECLOCK_FILE}",
+                       "--nlist=$env_vars->{NODES_FILE}",
+                       "--nopublicipcheck",
+                       "--event-script-dir=$env_vars->{EVENT_SCRIPT_DIR}",
+                       "--logfile=$env_vars->{LOG_FILE}",
+                       "-d $env_vars->{DEBUG_LEVEL}",
+                       "--dbdir=$env_vars->{DB_DIR}",
+                       "--dbdir-persistent=$env_vars->{DB_DIR_PERSISTENT}",
+                       "--dbdir-state=$env_vars->{DB_DIR_STATE}",
+                       ) or die("Unable to start ctdbd: $!");
+
+#                      "--public-addresses=$env_vars->{PUBLIC_ADDRESSES_FILE}",
+       }
+       write_pid($env_vars, "ctdbd", $pid);
+       print "DONE\n";
+
+       return 0;
+}
+
+sub provision_ctdb($$$$$)
+{
+       my ($self, $prefix, $pub_iface, $server_name, $no_delete_prefix) = @_;
+
+       my %ret = ();
+
+       # use the same address for internal and public:
+       my $internal_ip = "127.0.0.$pub_iface";
+       my $public_ip = "127.0.0.$pub_iface";
+
+       my @dirs = ();
+
+       my $prefix_abs = abs_path($prefix);
+
+       my $var_dir = "$prefix_abs/var";
+       push @dirs, $var_dir;
+
+       my $piddir="$prefix_abs/pid";
+       push @dirs, $piddir;
+
+       my $reclock_file = "$var_dir/rec.lock";
+       my $socket_file = "$var_dir/ctdb.socket";
+       my $log_file = "$var_dir/log.ctdb";
+
+       my $db_dir = "$var_dir/ctdb";
+       push @dirs, $db_dir;
+
+       my $db_dir_persistent = "$db_dir/persistent";
+       push @dirs, $db_dir_persistent;
+
+       my $db_dir_state = "$db_dir/state";
+       push @dirs, $db_dir_state;
+
+       my $etc_dir = "$prefix_abs/etc";
+       push @dirs, $etc_dir;
+
+       my $ctdb_dir = "$etc_dir/ctdb";
+       push @dirs, $ctdb_dir;
+
+       my $nodes_file = "$ctdb_dir/nodes";
+       my $public_addresses_file = "$ctdb_dir/public_addresses";
+
+       my $event_script_dir = "$ctdb_dir/events.d";
+       push @dirs, $event_script_dir;
+
+       #
+       # check / create directories:
+       #
+       die ("prefix_abs = ''") if $prefix_abs eq "";
+       die ("prefix_abs = '/'") if $prefix_abs eq "/";
+
+       mkdir ($prefix_abs, 0777);
+       print "CREATE CTDB TEST ENVIRONMENT in '$prefix_abs'...";
+
+       if (not defined($no_delete_prefix) or not $no_delete_prefix) {
+               system("rm -rf $prefix_abs/*");
+       }
+
+       mkdir($_, 0777) foreach(@dirs);
+
+       # - setup nodes
+       unless (open(NODES, ">$nodes_file")) {
+               warn("Unable to open nodesfile '$nodes_file'");
+               return undef;
+       }
+       print NODES "$internal_ip\n";
+       close(NODES);
+
+       # - setup public-addresses
+       unless(open(PUBLIC_ADDR, ">$public_addresses_file")) {
+               warn("Unable to open public addresses file '$public_addresses_file'");
+               return undef;
+       }
+       print PUBLIC_ADDR "$public_ip/32 swrap$pub_iface\n";
+       close(PUBLIC_ADDR);
+
+       my $event_script = "$event_script_dir/00.test";
+       unless(open(EVENTSCRIPT, ">$event_script")) {
+               warn("Unable to open event script '$event_script'");
+               return undef;
+       }
+       print EVENTSCRIPT "#!/bin/sh
+# event script for clustered samba selftest
+
+echo \"event script called: '\$0 \$\@'\"
+
+exit 0
+";
+
+
+       $ret{CTDBD_TEST_LOG} = "$prefix/ctdbd_test.log";
+       $ret{CTDBD_TEST_LOG_POS} = 0;
+
+       $ret{NODES_FILE} = $nodes_file;
+       $ret{PUBLIC_ADDRESSES_FILE} = $public_addresses_file;
+       $ret{RECLOCK_FILE} = $reclock_file;
+       $ret{SOCKET_FILE} = $socket_file;
+       $ret{DB_DIR} = $db_dir;
+       $ret{DB_DIR_PERSISTENT} = $db_dir_persistent;
+       $ret{DB_DIR_STATE} = $db_dir_state;
+       $ret{LOG_FILE} = $log_file;
+       $ret{EVENT_SCRIPT_DIR} = $event_script_dir;
+       $ret{PUBLIC_INTERFACE} = "swrap$pub_iface";
+       $ret{DEBUG_LEVEL} = 4;
+       $ret{PIDDIR} = $piddir;
+
+       $ret{NETBIOSNAME} = $server_name;
+
+       $ret{SOCKET_WRAPPER_DEFAULT_IFACE} = $pub_iface;
+
+       $ret{BINDIR} = "$self->{srcdir}/ctdb/bin";
+
+       return \%ret;
+}
+
+sub wait_for_start_ctdb($$)
+{
+       my ($self, $envvars) = @_;
+
+       print "wait for ctdbd\n";
+
+       #print `ps axf | grep ctdbd`;
+
+       sleep(3);
+
+       my $cmd = "";
+       $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$envvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
+       $cmd .= "$envvars->{BINDIR}/ctdb --socket=$envvars->{SOCKET_FILE} status";
+
+       print "\n";
+       print "<<<OBNOX>>> wait_for_start_ctdb: running cmd '$cmd'\n";
+       print "\n";
+
+       my $ret = system("$cmd");
+       if ($ret != 0) {
+               print "CTDB failed to start?\n";
+               teardown_env_ctdb($self, $envvars);
+               return 0;
+       }
+
+       sleep(3);
+
+       $ret = system("$cmd");
+       if ($ret != 0) {
+               print "CTDB failed to start?\n";
+               teardown_env_ctdb($self, $envvars);
+               return 0;
+       }
+
+       sleep(3);
+
+       $ret = system("$cmd");
+       if ($ret != 0) {
+               print "CTDB failed to start?\n";
+               teardown_env_ctdb($self, $envvars);
+               return 0;
+       }
+
+       sleep(3);
+
+       $ret = system("$cmd");
+       if ($ret != 0) {
+               print "CTDB failed to start?\n";
+               teardown_env_ctdb($self, $envvars);
+               return 0;
+       }
+
+       sleep(3);
+
+       $ret = system("$cmd");
+       if ($ret != 0) {
+               print "CTDB failed to start?\n";
+               teardown_env_ctdb($self, $envvars);
+               return 0;
+       }
+
+       print "CTDB initialized\n";
+
+       print $self->getlog_env_ctdb($envvars);
+
+       return 1;
+}
+
 1;