From 4408f8a0dec80c34dfe770cc2a81f2d4e074ba8a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 10 Dec 2010 12:13:58 +1100 Subject: [PATCH] wintest Share more of the S4 test code with the s3 test This allows us to run a private BIND in the S3 test, and allows the S3 test to join a freshly provisioned AD instance if the VM isn't already configured. Andrew Bartlett --- wintest/test-s3.py | 58 +++++++-- wintest/test-s4-howto.py | 258 ++------------------------------------- wintest/wintest.py | 239 ++++++++++++++++++++++++++++++++++++ 3 files changed, 298 insertions(+), 257 deletions(-) diff --git a/wintest/test-s3.py b/wintest/test-s3.py index 6bb196b9705f..cdfabaa7692b 100755 --- a/wintest/test-s3.py +++ b/wintest/test-s3.py @@ -6,14 +6,9 @@ import sys, os import optparse import wintest -def check_prerequesites(t): - t.info("Checking prerequesites") - t.setvar('HOSTNAME', t.cmd_output("hostname -s").strip()) - if os.getuid() != 0: - raise Exception("You must run this script as root") +def set_libpath(t): t.putenv("LD_LIBRARY_PATH", "${PREFIX}/lib") - def build_s3(t): '''build samba3''' t.info('Building s3') @@ -98,16 +93,16 @@ def create_shares(t): t.run_cmd("mkdir -p test") -def join_as_member(t, vm): - '''join a windows domain as a member server''' +def prep_join_as_member(t, vm): + '''prepare to join a windows domain as a member server''' t.setwinvars(vm) - t.info("Joining ${WIN_VM} as a member using net ads join") + t.info("Starting VMs for joining ${WIN_VM} as a member using net ads join") t.chdir('${PREFIX}') t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False) t.vm_poweroff("${WIN_VM}", checkfail=False) t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}") - t.ping_wait("${WIN_HOSTNAME}") child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_time=True) + t.get_ipconfig(child) t.del_files(["var", "private"]) t.write_file("lib/smb.conf", ''' [global] @@ -128,6 +123,13 @@ def join_as_member(t, vm): ea support = yes panic action = xterm -e gdb --pid %d ''') + +def join_as_member(t, vm): + '''join a windows domain as a member server''' + t.setwinvars(vm) + t.info("Joining ${WIN_VM} as a member using net ads join") + t.port_wait("${WIN_IP}", 389) + t.retry_cmd("host -t SRV _ldap._tcp.${WIN_REALM} ${WIN_IP}", ['has SRV record'] ) t.cmd_contains("bin/net ads join -Uadministrator%${WIN_PASS}", ["Joined"]) t.cmd_contains("bin/net ads testjoin", ["Join is OK"]) @@ -145,12 +147,27 @@ def test_join_as_member(t, vm): def test_s3(t): '''basic s3 testing''' - check_prerequesites(t) + t.check_prerequesites() + set_libpath(t) + + if not t.skip("configure_bind"): + t.configure_bind() + if not t.skip("stop_bind"): + t.stop_bind() + if not t.skip("stop_vms"): + t.stop_vms() if not t.skip("build"): build_s3(t) + if not t.skip("configure_bind2"): + t.configure_bind() + if not t.skip("start_bind"): + t.start_bind() + if t.have_var('W2K8R2A_VM') and not t.skip("join_w2k8r2"): + prep_join_as_member(t, "W2K8R2A") + t.run_dcpromo_as_first_dc("W2K8R2A", func_level='2008r2') join_as_member(t, "W2K8R2A") create_shares(t) start_s3(t) @@ -159,9 +176,26 @@ def test_s3(t): t.info("S3 test: All OK") +def test_cleanup(t): + '''cleanup after tests''' + t.info("Cleaning up ...") + t.restore_resolv_conf() + if getattr(t, 'bind_child', False): + t.bind_child.kill() + + if __name__ == '__main__': t = wintest.wintest() t.setup("test-s3.py", "source3") - test_s3(t) + try: + test_s3(t) + except: + if not t.opts.nocleanup: + test_cleanup(t) + raise + + if not t.opts.nocleanup: + test_cleanup(t) + t.info("S3 test: All OK") diff --git a/wintest/test-s4-howto.py b/wintest/test-s4-howto.py index e97963f8f34c..f1985945413f 100755 --- a/wintest/test-s4-howto.py +++ b/wintest/test-s4-howto.py @@ -5,16 +5,6 @@ import sys, os import wintest, pexpect, time, subprocess -def check_prerequesites(t): - t.info("Checking prerequesites") - t.setvar('HOSTNAME', t.cmd_output("hostname -s").strip()) - if os.getuid() != 0: - raise Exception("You must run this script as root") - t.run_cmd('ifconfig ${INTERFACE} ${INTERFACE_NET} up') - if t.getvar('INTERFACE_IPV6'): - t.run_cmd('ifconfig ${INTERFACE} inet6 del ${INTERFACE_IPV6}/64', checkfail=False) - t.run_cmd('ifconfig ${INTERFACE} inet6 add ${INTERFACE_IPV6}/64 up') - def build_s4(t): '''build samba4''' t.info('Building s4') @@ -60,13 +50,6 @@ def start_s4(t): '--option', 'panic action=gnome-terminal -e "gdb --pid %PID%"']) t.port_wait("${INTERFACE_IP}", 139) -def stop_vms(t): - '''Shut down any existing alive VMs, so they do not collide with what we are doing''' - t.info('Shutting down any of our VMs already running') - vms = t.get_vms() - for v in vms: - t.vm_poweroff(v, checkfail=False) - def test_smbclient(t): '''test smbclient''' t.info('Testing smbclient') @@ -102,170 +85,6 @@ def create_shares(t): t.run_cmd("mkdir -p var/profiles") -def set_nameserver(t, nameserver): - '''set the nameserver in resolv.conf''' - t.write_file("/etc/resolv.conf.wintest", ''' -# Generated by wintest, the Samba v Windows automated testing system -nameserver %s - -# your original resolv.conf appears below: -''' % t.substitute(nameserver)) - child = t.pexpect_spawn("cat /etc/resolv.conf", crlf=False) - i = child.expect(['your original resolv.conf appears below:', pexpect.EOF]) - if i == 0: - child.expect(pexpect.EOF) - contents = child.before.lstrip().replace('\r', '') - t.write_file('/etc/resolv.conf.wintest', contents, mode='a') - t.write_file('/etc/resolv.conf.wintest-bak', contents) - t.run_cmd("mv -f /etc/resolv.conf.wintest /etc/resolv.conf") - t.resolv_conf_backup = '/etc/resolv.conf.wintest-bak'; - - -def restore_resolv_conf(t): - '''restore the /etc/resolv.conf after testing is complete''' - if getattr(t, 'resolv_conf_backup', False): - t.info("restoring /etc/resolv.conf") - t.run_cmd("mv -f %s /etc/resolv.conf" % t.resolv_conf_backup) - - -def rndc_cmd(t, cmd, checkfail=True): - '''run a rndc command''' - t.run_cmd("${RNDC} -c ${PREFIX}/etc/rndc.conf %s" % cmd, checkfail=checkfail) - -def named_supports_gssapi_keytab(t): - '''see if named supports tkey-gssapi-keytab''' - t.write_file("${PREFIX}/named.conf.test", - 'options { tkey-gssapi-keytab "test"; };') - try: - t.run_cmd("${NAMED_CHECKCONF} ${PREFIX}/named.conf.test") - except subprocess.CalledProcessError: - return False - return True - - -def configure_bind(t): - t.chdir('${PREFIX}') - - nameserver = t.get_nameserver() - if nameserver == t.getvar('INTERFACE_IP'): - raise RuntimeError("old /etc/resolv.conf must not contain %s as a nameserver, this will create loops with the generated dns configuration" % nameserver) - t.setvar('DNSSERVER', nameserver) - - if t.getvar('INTERFACE_IPV6'): - ipv6_listen = 'listen-on-v6 port 53 { ${INTERFACE_IPV6}; };' - else: - ipv6_listen = '' - t.setvar('BIND_LISTEN_IPV6', ipv6_listen) - - if named_supports_gssapi_keytab(t): - t.setvar("NAMED_TKEY_OPTION", - 'tkey-gssapi-keytab "${PREFIX}/private/dns.keytab";') - else: - t.info("LCREALM=${LCREALM}") - t.setvar("NAMED_TKEY_OPTION", - '''tkey-gssapi-credential "DNS/${LCREALM}"; - tkey-domain "${LCREALM}"; - ''') - t.putenv("KRB5_CONFIG", '${PREFIX}/private/krb5.conf') - t.putenv('KEYTAB_FILE', '${PREFIX}/private/dns.keytab') - t.putenv('KRB5_KTNAME', '${PREFIX}/private/dns.keytab') - - t.write_file("etc/named.conf", ''' -options { - listen-on port 53 { ${INTERFACE_IP}; }; - ${BIND_LISTEN_IPV6} - directory "${PREFIX}/var/named"; - dump-file "${PREFIX}/var/named/data/cache_dump.db"; - pid-file "${PREFIX}/var/named/named.pid"; - statistics-file "${PREFIX}/var/named/data/named_stats.txt"; - memstatistics-file "${PREFIX}/var/named/data/named_mem_stats.txt"; - allow-query { any; }; - recursion yes; - ${NAMED_TKEY_OPTION} - max-cache-ttl 10; - max-ncache-ttl 10; - - forward only; - forwarders { - ${DNSSERVER}; - }; - -}; - -key "rndc-key" { - algorithm hmac-md5; - secret "lA/cTrno03mt5Ju17ybEYw=="; -}; - -controls { - inet ${INTERFACE_IP} port 953 - allow { any; } keys { "rndc-key"; }; -}; - -include "${PREFIX}/private/named.conf"; -''') - - # add forwarding for the windows domains - domains = t.get_domains() - for d in domains: - t.write_file('etc/named.conf', - ''' -zone "%s" IN { - type forward; - forward only; - forwarders { - %s; - }; -}; -''' % (d, domains[d]), - mode='a') - - - t.write_file("etc/rndc.conf", ''' -# Start of rndc.conf -key "rndc-key" { - algorithm hmac-md5; - secret "lA/cTrno03mt5Ju17ybEYw=="; -}; - -options { - default-key "rndc-key"; - default-server ${INTERFACE_IP}; - default-port 953; -}; -''') - - set_nameserver(t, t.getvar('INTERFACE_IP')) - - -def stop_bind(t): - '''Stop our private BIND from listening and operating''' - rndc_cmd(t, "stop", checkfail=False) - t.port_wait("${INTERFACE_IP}", 53, wait_for_fail=True) - - t.run_cmd("rm -rf var/named") - - -def start_bind(t): - '''restart the test environment version of bind''' - t.info("Restarting bind9") - t.chdir('${PREFIX}') - - set_nameserver(t, t.getvar('INTERFACE_IP')) - - t.run_cmd("mkdir -p var/named/data") - t.run_cmd("chown -R ${BIND_USER} var/named") - - t.bind_child = t.run_child("${BIND9} -u ${BIND_USER} -n 1 -c ${PREFIX}/etc/named.conf -g") - - t.port_wait("${INTERFACE_IP}", 53) - rndc_cmd(t, "flush") - -def restart_bind(t): - configure_bind(t) - stop_bind(t) - start_bind(t) - def test_dns(t): '''test that DNS is OK''' t.info("Testing DNS") @@ -289,7 +108,7 @@ def test_dyndns(t): '''test that dynamic DNS is working''' t.chdir('${PREFIX}') t.run_cmd("sbin/samba_dnsupdate --fail-immediately") - rndc_cmd(t, "flush") + t.rndc_cmd("flush") def run_winjoin(t, vm): @@ -574,7 +393,7 @@ def prep_join_as_dc(t, vm): t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False) t.vm_poweroff("${WIN_VM}", checkfail=False) t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}") - rndc_cmd(t, 'flush') + t.rndc_cmd('flush') t.run_cmd("rm -rf etc/smb.conf private") child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True) t.get_ipconfig(child) @@ -722,71 +541,20 @@ def test_join_as_rodc(t, vm): t.vm_poweroff("${WIN_VM}") -def run_dcpromo_as_first_dc(t, vm, func_level=None): - t.setwinvars(vm) - t.info("Configuring a windows VM ${WIN_VM} at the first DC in the domain using dcpromo") - child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_time=True) - if t.get_is_dc(child): - return - - if func_level == '2008r2': - t.setvar("FUNCTION_LEVEL_INT", str(4)) - elif func_level == '2003': - t.setvar("FUNCTION_LEVEL_INT", str(1)) - else: - t.setvar("FUNCTION_LEVEL_INT", str(0)) - - child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_ip=True, set_noexpire=True) - - """This server must therefore not yet be a directory server, so we must promote it""" - child.sendline("copy /Y con answers.txt") - child.sendline(''' -[DCInstall] -; New forest promotion -ReplicaOrNewDomain=Domain -NewDomain=Forest -NewDomainDNSName=${WIN_REALM} -ForestLevel=${FUNCTION_LEVEL_INT} -DomainNetbiosName=${WIN_DOMAIN} -DomainLevel=${FUNCTION_LEVEL_INT} -InstallDNS=Yes -ConfirmGc=Yes -CreateDNSDelegation=No -DatabasePath="C:\Windows\NTDS" -LogPath="C:\Windows\NTDS" -SYSVOLPath="C:\Windows\SYSVOL" -; Set SafeModeAdminPassword to the correct value prior to using the unattend file -SafeModeAdminPassword=${WIN_PASS} -; Run-time flags (optional) -RebootOnCompletion=No - -''') - child.expect("copied.") - child.expect("C:") - child.expect("C:") - child.sendline("dcpromo /answer:answers.txt") - i = child.expect(["You must restart this computer", "failed", "Active Directory Domain Services was not installed", "C:"], timeout=120) - if i == 1 or i == 2: - raise Exception("dcpromo failed") - child.sendline("shutdown -r -t 0") - t.port_wait("${WIN_IP}", 139, wait_for_fail=True) - t.port_wait("${WIN_IP}", 139) - - def test_howto(t): '''test the Samba4 howto''' - check_prerequesites(t) + t.check_prerequesites() # we don't need fsync safety in these tests t.putenv('TDB_NO_FSYNC', '1') if not t.skip("configure_bind"): - configure_bind(t) + t.configure_bind(kerberos_support=True, include='${PREFIX}/private/named.conf') if not t.skip("stop_bind"): - stop_bind(t) + t.stop_bind() if not t.skip("stop_vms"): - stop_vms(t) + t.stop_vms() if not t.skip("build"): build_s4(t) @@ -802,9 +570,9 @@ def test_howto(t): if not t.skip("smbclient"): test_smbclient(t) if not t.skip("configure_bind2"): - configure_bind(t) + t.configure_bind(kerberos_support=True, include='${PREFIX}/private/named.conf') if not t.skip("start_bind"): - start_bind(t) + t.start_bind() if not t.skip("dns"): test_dns(t) if not t.skip("kerberos"): @@ -842,7 +610,7 @@ def test_howto(t): create_shares(t) start_s4(t) test_smbclient(t) - restart_bind(t) + t.restart_bind(kerberos_support=True, include='{PREFIX}/private/named.conf') test_dns(t) test_kerberos(t) test_dyndns(t) @@ -851,7 +619,7 @@ def test_howto(t): if t.have_vm('W2K8R2A') and not t.skip("join_w2k8r2"): prep_join_as_dc(t, "W2K8R2A") - run_dcpromo_as_first_dc(t, "W2K8R2A", func_level='2008r2') + t.run_dcpromo_as_first_dc("W2K8R2A", func_level='2008r2') join_as_dc(t, "W2K8R2A") create_shares(t) start_s4(t) @@ -860,7 +628,7 @@ def test_howto(t): if t.have_vm('W2K8R2A') and not t.skip("join_rodc"): prep_join_as_dc(t, "W2K8R2A") - run_dcpromo_as_first_dc(t, "W2K8R2A", func_level='2008r2') + t.run_dcpromo_as_first_dc("W2K8R2A", func_level='2008r2') join_as_rodc(t, "W2K8R2A") create_shares(t) start_s4(t) @@ -869,7 +637,7 @@ def test_howto(t): if t.have_vm('W2K3A') and not t.skip("join_w2k3"): prep_join_as_dc(t, "W2K3A") - run_dcpromo_as_first_dc(t, "W2K3A", func_level='2003') + t.run_dcpromo_as_first_dc("W2K3A", func_level='2003') join_as_dc(t, "W2K3A") create_shares(t) start_s4(t) @@ -882,7 +650,7 @@ def test_howto(t): def test_cleanup(t): '''cleanup after tests''' t.info("Cleaning up ...") - restore_resolv_conf(t) + t.restore_resolv_conf() if getattr(t, 'bind_child', False): t.bind_child.kill() diff --git a/wintest/wintest.py b/wintest/wintest.py index 0d65116562a3..af4588f5c8ee 100644 --- a/wintest/wintest.py +++ b/wintest/wintest.py @@ -16,6 +16,23 @@ class wintest(): os.putenv('PYTHONUNBUFFERED', '1') self.parser = optparse.OptionParser("wintest") + def check_prerequesites(self): + self.info("Checking prerequesites") + self.setvar('HOSTNAME', self.cmd_output("hostname -s").strip()) + if os.getuid() != 0: + raise Exception("You must run this script as root") + self.run_cmd('ifconfig ${INTERFACE} ${INTERFACE_NET} up') + if self.getvar('INTERFACE_IPV6'): + self.run_cmd('ifconfig ${INTERFACE} inet6 del ${INTERFACE_IPV6}/64', checkfail=False) + self.run_cmd('ifconfig ${INTERFACE} inet6 add ${INTERFACE_IPV6}/64 up') + + def stop_vms(self): + '''Shut down any existing alive VMs, so they do not collide with what we are doing''' + self.info('Shutting down any of our VMs already running') + vms = self.get_vms() + for v in vms: + self.vm_poweroff(v, checkfail=False) + def setvar(self, varname, value): '''set a substitution variable''' self.vars[varname] = value @@ -268,6 +285,176 @@ class wintest(): child.expect('\d+.\d+.\d+.\d+') return child.after + def rndc_cmd(self, cmd, checkfail=True): + '''run a rndc command''' + self.run_cmd("${RNDC} -c ${PREFIX}/etc/rndc.conf %s" % cmd, checkfail=checkfail) + + def named_supports_gssapi_keytab(self): + '''see if named supports tkey-gssapi-keytab''' + self.write_file("${PREFIX}/named.conf.test", + 'options { tkey-gssapi-keytab "test"; };') + try: + self.run_cmd("${NAMED_CHECKCONF} ${PREFIX}/named.conf.test") + except subprocess.CalledProcessError: + return False + return True + + def set_nameserver(self, nameserver): + '''set the nameserver in resolv.conf''' + self.write_file("/etc/resolv.conf.wintest", ''' +# Generated by wintest, the Samba v Windows automated testing system +nameserver %s + +# your original resolv.conf appears below: +''' % self.substitute(nameserver)) + child = self.pexpect_spawn("cat /etc/resolv.conf", crlf=False) + i = child.expect(['your original resolv.conf appears below:', pexpect.EOF]) + if i == 0: + child.expect(pexpect.EOF) + contents = child.before.lstrip().replace('\r', '') + self.write_file('/etc/resolv.conf.wintest', contents, mode='a') + self.write_file('/etc/resolv.conf.wintest-bak', contents) + self.run_cmd("mv -f /etc/resolv.conf.wintest /etc/resolv.conf") + self.resolv_conf_backup = '/etc/resolv.conf.wintest-bak'; + + def configure_bind(self, kerberos_support=False, include=None): + self.chdir('${PREFIX}') + + nameserver = self.get_nameserver() + if nameserver == self.getvar('INTERFACE_IP'): + raise RuntimeError("old /etc/resolv.conf must not contain %s as a nameserver, this will create loops with the generated dns configuration" % nameserver) + self.setvar('DNSSERVER', nameserver) + + if self.getvar('INTERFACE_IPV6'): + ipv6_listen = 'listen-on-v6 port 53 { ${INTERFACE_IPV6}; };' + else: + ipv6_listen = '' + self.setvar('BIND_LISTEN_IPV6', ipv6_listen) + + if not kerberos_support: + self.setvar("NAMED_TKEY_OPTION", "") + else: + if self.named_supports_gssapi_keytab(): + self.setvar("NAMED_TKEY_OPTION", + 'tkey-gssapi-keytab "${PREFIX}/private/dns.keytab";') + else: + self.info("LCREALM=${LCREALM}") + self.setvar("NAMED_TKEY_OPTION", + '''tkey-gssapi-credential "DNS/${LCREALM}"; + tkey-domain "${LCREALM}"; + ''') + self.putenv("KRB5_CONFIG", '${PREFIX}/private/krb5.conf') + self.putenv('KEYTAB_FILE', '${PREFIX}/private/dns.keytab') + self.putenv('KRB5_KTNAME', '${PREFIX}/private/dns.keytab') + + if include: + self.setvar("NAMED_INCLUDE", 'include "%s";' % include) + else: + self.setvar("NAMED_INCLUDE", '') + + self.run_cmd("mkdir -p ${PREFIX}/etc") + + self.write_file("etc/named.conf", ''' +options { + listen-on port 53 { ${INTERFACE_IP}; }; + ${BIND_LISTEN_IPV6} + directory "${PREFIX}/var/named"; + dump-file "${PREFIX}/var/named/data/cache_dump.db"; + pid-file "${PREFIX}/var/named/named.pid"; + statistics-file "${PREFIX}/var/named/data/named_stats.txt"; + memstatistics-file "${PREFIX}/var/named/data/named_mem_stats.txt"; + allow-query { any; }; + recursion yes; + ${NAMED_TKEY_OPTION} + max-cache-ttl 10; + max-ncache-ttl 10; + + forward only; + forwarders { + ${DNSSERVER}; + }; + +}; + +key "rndc-key" { + algorithm hmac-md5; + secret "lA/cTrno03mt5Ju17ybEYw=="; +}; + +controls { + inet ${INTERFACE_IP} port 953 + allow { any; } keys { "rndc-key"; }; +}; + +${NAMED_INCLUDE} +''') + + # add forwarding for the windows domains + domains = self.get_domains() + for d in domains: + self.write_file('etc/named.conf', + ''' +zone "%s" IN { + type forward; + forward only; + forwarders { + %s; + }; +}; +''' % (d, domains[d]), + mode='a') + + + self.write_file("etc/rndc.conf", ''' +# Start of rndc.conf +key "rndc-key" { + algorithm hmac-md5; + secret "lA/cTrno03mt5Ju17ybEYw=="; +}; + +options { + default-key "rndc-key"; + default-server ${INTERFACE_IP}; + default-port 953; +}; +''') + + + def stop_bind(self): + '''Stop our private BIND from listening and operating''' + self.rndc_cmd("stop", checkfail=False) + self.port_wait("${INTERFACE_IP}", 53, wait_for_fail=True) + + self.run_cmd("rm -rf var/named") + + + def start_bind(self): + '''restart the test environment version of bind''' + self.info("Restarting bind9") + self.chdir('${PREFIX}') + + self.set_nameserver(self.getvar('INTERFACE_IP')) + + self.run_cmd("mkdir -p var/named/data") + self.run_cmd("chown -R ${BIND_USER} var/named") + + self.bind_child = self.run_child("${BIND9} -u ${BIND_USER} -n 1 -c ${PREFIX}/etc/named.conf -g") + + self.port_wait("${INTERFACE_IP}", 53) + self.rndc_cmd("flush") + + def restart_bind(self, kerberos_support=False, include=None): + self.configure_bind(keberos_support=kerberos_support, include=include) + self.stop_bind() + self.start_bind() + + def restore_resolv_conf(self): + '''restore the /etc/resolv.conf after testing is complete''' + if getattr(self, 'resolv_conf_backup', False): + self.info("restoring /etc/resolv.conf") + self.run_cmd("mv -f %s /etc/resolv.conf" % self.resolv_conf_backup) + + def vm_poweroff(self, vmname, checkfail=True): '''power off a VM''' self.setvar('VMNAME', vmname) @@ -565,6 +752,58 @@ class wintest(): ret.append(self.vars[v]) return ret + + def run_dcpromo_as_first_dc(self, vm, func_level=None): + self.setwinvars(vm) + self.info("Configuring a windows VM ${WIN_VM} at the first DC in the domain using dcpromo") + child = self.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_time=True) + if self.get_is_dc(child): + return + + if func_level == '2008r2': + self.setvar("FUNCTION_LEVEL_INT", str(4)) + elif func_level == '2003': + self.setvar("FUNCTION_LEVEL_INT", str(1)) + else: + self.setvar("FUNCTION_LEVEL_INT", str(0)) + + child = self.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_ip=True, set_noexpire=True) + + """This server must therefore not yet be a directory server, so we must promote it""" + child.sendline("copy /Y con answers.txt") + child.sendline(''' +[DCInstall] +; New forest promotion +ReplicaOrNewDomain=Domain +NewDomain=Forest +NewDomainDNSName=${WIN_REALM} +ForestLevel=${FUNCTION_LEVEL_INT} +DomainNetbiosName=${WIN_DOMAIN} +DomainLevel=${FUNCTION_LEVEL_INT} +InstallDNS=Yes +ConfirmGc=Yes +CreateDNSDelegation=No +DatabasePath="C:\Windows\NTDS" +LogPath="C:\Windows\NTDS" +SYSVOLPath="C:\Windows\SYSVOL" +; Set SafeModeAdminPassword to the correct value prior to using the unattend file +SafeModeAdminPassword=${WIN_PASS} +; Run-time flags (optional) +RebootOnCompletion=No + +''') + child.expect("copied.") + child.expect("C:") + child.expect("C:") + child.sendline("dcpromo /answer:answers.txt") + i = child.expect(["You must restart this computer", "failed", "Active Directory Domain Services was not installed", "C:"], timeout=240) + if i == 1 or i == 2: + raise Exception("dcpromo failed") + child.sendline("shutdown -r -t 0") + self.port_wait("${WIN_IP}", 139, wait_for_fail=True) + self.port_wait("${WIN_IP}", 139) + + def setup(self, testname, subdir): '''setup for main tests, parsing command line''' self.parser.add_option("--conf", type='string', default='', help='config file') -- 2.34.1