From 5bc7502d61ae1d77ca97cd3a8483f85af3b4ab5c Mon Sep 17 00:00:00 2001 From: daniceexi <wxp@cn.ibm.com> Date: Tue, 3 Dec 2013 02:26:31 -0500 Subject: [PATCH] code drop for feature to support multiple disks/paritions and multiple nics configuration for Windows deployment. --- perl-xCAT/xCAT/Schema.pm | 32 ++ xCAT-server/lib/perl/xCAT/SvrUtils.pm | 12 +- xCAT-server/lib/perl/xCAT/Template.pm | 107 +++++- xCAT-server/lib/xcat/plugins/windows.pm | 347 +++++++++++------- .../windows/enterprise.win2k8.x86_64.tmpl | 9 +- .../xcat/netboot/windows/fixupunattend.vbs | 64 +++- .../share/xcat/netboot/windows/startnet.cmd | 2 +- 7 files changed, 407 insertions(+), 166 deletions(-) diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 3e24192fd..2368060bd 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -731,6 +731,20 @@ linuximage => { disable => "Set to 'yes' or '1' to comment out this row.", }, }, +winimage => { + cols => [qw(imagename template installto partitionfile comments disable)], + keys => [qw(imagename)], + tablespace =>'XCATTBS32K', + table_desc => 'Information about a Windows operating system image that can be used to deploy cluster nodes.', + descriptions => { + imagename => 'The name of this xCAT OS image definition.', + template => 'The fully qualified name of the template file that is used to create the windows unattend.xml file for diskful installation.', + installto => 'The disk and partition that the Windows will be deployed to. The valid format is <disk>:<partition>. If it is not set, default value is 0:1 for bios boot mode(legacy) and 0:3 for uefi boot mode; If it is set to 1, it means 1:1 for bios boot and 1:3 for uefi boot', + partitionfile => 'The path of partition configuration file. Since the partition configuration for bios boot mode and uefi boot mode are different, this configuration file should include two parts if customer wants to support both bios and uefi mode. If customer just wants to support one of the modes, specify one of them anyway. Example of partition configuration file: [BIOS]xxxxxxx[UEFI]yyyyyyy.', + comments => 'Any user-written notes.', + disable => "Set to 'yes' or '1' to comment out this row.", + } +}, passwd => { cols => [qw(key username password cryptmethod authdomain comments disable)], keys => [qw(key username)], @@ -2707,6 +2721,24 @@ push(@{$defspec{node}->{'attrs'}}, @nodeattrs); access_tabentry => 'linuximage.imagename=attr:imagename', }, #################### +# winimage table# +#################### + {attr_name => 'template', + only_if => 'imagetype=windows', + tabentry => 'winimage.template', + access_tabentry => 'winimage.imagename=attr:imagename', + }, + {attr_name => 'installto', + only_if => 'imagetype=windows', + tabentry => 'winimage.installto', + access_tabentry => 'winimage.imagename=attr:imagename', + }, +{attr_name => 'partitionfile', + only_if => 'imagetype=windows', + tabentry => 'winimage.partitionfile', + access_tabentry => 'winimage.imagename=attr:imagename', + }, +#################### # nimimage table# #################### {attr_name => 'nimtype', diff --git a/xCAT-server/lib/perl/xCAT/SvrUtils.pm b/xCAT-server/lib/perl/xCAT/SvrUtils.pm index 648d765a0..7193ac58f 100644 --- a/xCAT-server/lib/perl/xCAT/SvrUtils.pm +++ b/xCAT-server/lib/perl/xCAT/SvrUtils.pm @@ -638,6 +638,7 @@ sub update_tables_with_templates #update the osimage and linuximage table my $osimagetab; my $linuximagetab; + my $winimagetab; if ($args{checkonly}) { if (keys %profiles) { return (0,""); @@ -697,7 +698,16 @@ sub update_tables_with_templates osdistroname=>$osdistroname); $osimagetab->setAttribs(\%key_col, \%tb_cols); - if ($osname !~ /^win/) { + if ($osname =~ /^win/) { + if (!$winimagetab) { $winimagetab=xCAT::Table->new('winimage',-create=>1); } + if ($winimagetab) { + my %key_col = (imagename=>$imagename); + my %tb_cols=(template=>$tmplfile); + $winimagetab->setAttribs(\%key_col, \%tb_cols); + } else { + return (1, "Cannot open the winimage table."); + } + } else { if (!$linuximagetab) { $linuximagetab=xCAT::Table->new('linuximage',-create=>1); } if ($linuximagetab) { my %key_col = (imagename=>$imagename); diff --git a/xCAT-server/lib/perl/xCAT/Template.pm b/xCAT-server/lib/perl/xCAT/Template.pm index b7c2e82bb..1ec743c90 100644 --- a/xCAT-server/lib/perl/xCAT/Template.pm +++ b/xCAT-server/lib/perl/xCAT/Template.pm @@ -350,24 +350,78 @@ sub windows_account_data { return $useraccountxml; } sub windows_net_cfg { - if ($::XCATSITEVALS{managedaddressmode} =~ /static/) { return "<!-- WINCFG Static not supported -->"; } - unless ($::XCATSITEVALS{managedaddressmode} =~ /autoula/) { - return ""; #windows default behavior - } - #autoula, - my $hoststab; - my $mactab = xCAT::Table->new('mac',-create=>0); - unless ($mactab) { die "mac table should always exist prior to template processing when doing autoula"; } - my $ent = $mactab->getNodeAttribs($node,['mac'],prefetchcache=>1); - unless ($ent and $ent->{mac}) { die "missing mac data for $node"; } - my $suffix = $ent->{mac}; - my $mac = $suffix; - $suffix = lc($suffix); + if ($::XCATSITEVALS{managedaddressmode} =~ /static/) { return "<!-- WINCFG Static not supported -->"; } + unless ($::XCATSITEVALS{managedaddressmode} =~ /autoula/) { + # handle the general windows deployment that create interfaces sections from nic table + my $component_head = '<component name="Microsoft-Windows-TCPIP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'; + my $component_end = '</component>'; + + my $interfaces_cfg = '<Interfaces>'; + my $nicstab = xCAT::Table->new('nics',-create=>0); + my $hasif; + if ($nicstab) { + my $nicsent = $nicstab->getNodeAttribs($node,['nicips']); + if ($nicsent->{nicips}) { + my @nics = split (/,/, $nicsent->{nicips}); + foreach (@nics) { + my $gateway; + my $interface_cfg = '<Interface wcm:action="add">'; + my ($nicname, $ips) = split(/!/, $_); + unless ($nicname) {next;} + if ($ips) { + $interface_cfg .= '<Ipv4Settings><DhcpEnabled>false</DhcpEnabled></Ipv4Settings><Ipv6Settings><DhcpEnabled>false</DhcpEnabled></Ipv6Settings>'; + $interface_cfg .= "<Identifier>$nicname</Identifier>"; + $interface_cfg .= '<UnicastIpAddresses>'; + + my @setip = split (/\|/, $ips); + my $num = 1; + foreach my $ip (@setip) { + my ($netmask, $gw) = getNM_GW($ip); + unless ($netmask) { + next; + } + if ($gw) { $gateway = $gw; } + $interface_cfg .= '<IpAddress wcm:action="add" wcm:keyValue="'.$num++.'">'.$ip."/$netmask".'</IpAddress>'; + } + + $interface_cfg .= "</UnicastIpAddresses>" + } else { + # set with dhcp + $interface_cfg .= '<Ipv4Settings><DhcpEnabled>true</DhcpEnabled></Ipv4Settings><Ipv6Settings><DhcpEnabled>true</DhcpEnabled></Ipv6Settings>'; + $interface_cfg .= "<Identifier>$nicname</Identifier>"; + } + + # add the default gateway + $interface_cfg .= '<Routes><Route wcm:action="add"><Identifier>1</Identifier><NextHopAddress>'.$gateway.'</NextHopAddress><Prefix>0/0</Prefix></Route></Routes>'; + $interface_cfg .= '</Interface>'; + + $interfaces_cfg .= $interface_cfg; + $hasif = 1; + } + } + } + $interfaces_cfg .= "</Interfaces>"; + if ($hasif) { + return "$component_head$interfaces_cfg$component_end"; #windows default behavior + } else { + return ""; + } + } + + #autoula, + my $hoststab; + my $mactab = xCAT::Table->new('mac',-create=>0); + unless ($mactab) { die "mac table should always exist prior to template processing when doing autoula"; } + my $ent = $mactab->getNodeAttribs($node,['mac'],prefetchcache=>1); + unless ($ent and $ent->{mac}) { die "missing mac data for $node"; } + my $suffix = $ent->{mac}; + my $mac = $suffix; + $suffix = lc($suffix); $mac =~ s/:/-/g; - unless ($hoststab) { $hoststab = xCAT::Table->new('hosts',-create=>1); } - my $ulaaddr = autoulaaddress($suffix); - $hoststab->setNodeAttribs($node,{ip=>$ulaaddr}); - return '<component name="Microsoft-Windows-TCPIP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'."\r\n<Interfaces><Interface wcm:action=\"add\">\r\n<Ipv4Settings><DhcpEnabled>false</DhcpEnabled></Ipv4Settings><Ipv6Settings><DhcpEnabled>false</DhcpEnabled></Ipv6Settings>\r\n<Identifier>$mac</Identifier>\r\n<UnicastIpAddresses>\r\n<IpAddress wcm:action=\"add\" wcm:keyValue=\"1\">$ulaaddr/64</IpAddress>\r\n</UnicastIpAddresses>\r\n</Interface>\r\n</Interfaces>\r\n</component>\r\n"; + unless ($hoststab) { $hoststab = xCAT::Table->new('hosts',-create=>1); } + my $ulaaddr = autoulaaddress($suffix); + $hoststab->setNodeAttribs($node,{ip=>$ulaaddr}); + return '<component name="Microsoft-Windows-TCPIP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'."\r\n<Interfaces><Interface wcm:action=\"add\">\r\n<Ipv4Settings><DhcpEnabled>false</DhcpEnabled></Ipv4Settings><Ipv6Settings><DhcpEnabled>false</DhcpEnabled></Ipv6Settings>\r\n<Identifier>$mac</Identifier>\r\n<UnicastIpAddresses>\r\n<IpAddress wcm:action=\"add\" wcm:keyValue=\"1\">$ulaaddr/64</IpAddress>\r\n</UnicastIpAddresses>\r\n</Interface>\r\n</Interfaces>\r\n</component>\r\n"; } sub windows_dns_cfg { my $domain; @@ -974,5 +1028,24 @@ sub enablesshbetweennodes return $result; } +# Get the netmask and gateway for a specific ip +# netmask is the number of bits +sub getNM_GW() +{ + my $ip = shift; + + my $nettab = xCAT::Table->new("networks"); + if ($nettab) { + my @nets = $nettab->getAllAttribs('net','mask','gateway'); + foreach my $net (@nets) { + if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $ip, $net->{'mask'}, 0)) { + return (xCAT::NetworkUtils::formatNetmask($net->{'mask'},0,1), $net->{'gateway'}); + } + } + } + + return (undef, undef); +} + 1; diff --git a/xCAT-server/lib/xcat/plugins/windows.pm b/xCAT-server/lib/xcat/plugins/windows.pm index 5e4c6bf7b..820d86b28 100644 --- a/xCAT-server/lib/xcat/plugins/windows.pm +++ b/xCAT-server/lib/xcat/plugins/windows.pm @@ -241,6 +241,10 @@ sub mkinstall my $hmtab = xCAT::Table->new('nodehm'); my $vpdtab = xCAT::Table->new('vpd'); my $vpdhash = $vpdtab->getNodesAttribs(\@nodes,['uuid']); + my %img_hash=(); + my $winimagetab; + my $osimagetab; + unless (-r "$tftpdir/Boot/pxeboot.0" ) { $callback->( {error => [ "The Windows netboot image is not created, consult documentation on how to add Windows deployment support to xCAT"],errorcode=>[1] @@ -253,148 +257,184 @@ sub mkinstall copy("/etc/xcat/cert/ca.pem","$installroot/xcat/ca.pem"); } require xCAT::Template; + + # get image attributes + my $osents = $ostab->getNodesAttribs(\@nodes, ['profile', 'os', 'arch', 'provmethod']); + foreach $node (@nodes) { - my $osinst; - my $ent = $ostab->getNodeAttribs($node, ['profile', 'os', 'arch']); - unless ($ent->{os} and $ent->{arch} and $ent->{profile}) - { - $callback->( - { - error => ["No profile defined in nodetype for $node"], - errorcode => [1] + my $os; + my $arch; + my $profile; + my $tmplfile; + my $imagename; # set it if running of 'nodeset osimage=xxx' + my $partfile; + my $installto; + + my $ent = $osents->{$node}->[0]; + if ($ent and $ent->{provmethod} and ($ent->{provmethod} ne 'install') and ($ent->{provmethod} ne 'netboot') and ($ent->{provmethod} ne 'statelite')) { + $imagename=$ent->{provmethod}; + if (!exists($img_hash{$imagename})) { + if (!$osimagetab) { + $osimagetab=xCAT::Table->new('osimage', -create=>1); + } + + my $ref = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod'); + if ($ref) { + $img_hash{$imagename}->{osver}=$ref->{'osvers'}; + $img_hash{$imagename}->{osarch}=$ref->{'osarch'}; + $img_hash{$imagename}->{profile}=$ref->{'profile'}; + $img_hash{$imagename}->{provmethod}=$ref->{'provmethod'}; + if (!$winimagetab) { + $winimagetab=xCAT::Table->new('winimage', -create=>1); + } + my $ref1 = $winimagetab->getAttribs({imagename => $imagename}, 'template', 'installto', 'partitionfile'); + if ($ref1) { + if ($ref1->{'template'}) { + $img_hash{$imagename}->{template}=$ref1->{'template'}; } - ); - next; #No profile - } - my $os = $ent->{os}; - my $arch = $ent->{arch}; - my $profile = $ent->{profile}; - if ($os eq "imagex") { - my $wimfile="$installroot/images/$arch/$profile.wim"; - unless ( -r $wimfile ) { - $callback->({error=>["$wimfile not found, run rimage on a node to capture first"],errorcode=>[1]}); - next; - } - my $script=applyimagescript($arch,$profile); - my $shandle; - open($shandle,">","$installroot/autoinst/$node.cmd"); - print $shandle $script; - close($shandle); - if ($vpdhash->{$node}) { - mkwinlinks($node,$ent,$vpdhash->{$node}->[0]->{uuid}); - } else { - mkwinlinks($node,$ent); - } - if ($arch =~ /x86_64/) - { - $bptab->setNodeAttribs( - $node, - { - kernel => "Boot/pxeboot.0", - initrd => "", - kcmdline => "" - } - ); - } elsif ($arch =~ /x86/) { - unless (-r "$tftpdir/Boot/pxeboot32.0") { - my $origpxe; - my $pxeboot; - open($origpxe,"<$tftpdir/Boot/pxeboot.0"); - open($pxeboot,">$tftpdir/Boot/pxeboot32.0"); - binmode($origpxe); - binmode($pxeboot); - my @origpxecontent = <$origpxe>; - foreach (@origpxecontent) { - s/bootmgr.exe/bootm32.exe/; - print $pxeboot $_; - } - } - unless (-r "$tftpdir/bootm32.exe") { - my $origmgr; - my $bootmgr; - open($origmgr,"<$tftpdir/bootmgr.exe"); - open($bootmgr,">$tftpdir/bootm32.exe"); - binmode($origmgr); - binmode($bootmgr); - my @data = <$origmgr>; - foreach (@data) { - s/(\\.B.o.o.t.\\.B.)C(.)D/${1}3${2}2/; # 16 bit encoding... cheat - print $bootmgr $_; - } - } - $bptab->setNodeAttribs( - $node, - { - kernel => "Boot/pxeboot32.0", - initrd => "", - kcmdline => "" - } - ); - } - next; - } + if ($ref1->{'installto'}) { + $img_hash{$imagename}->{installto}=$ref1->{'installto'}; + } + if ($ref1->{'partitionfile'}) { + $img_hash{$imagename}->{partitionfile}=$ref1->{'partitionfile'}; + } + } + } else { + $callback->({error => ["The os image $imagename does not exists on the osimage table for $node"], errorcode => [1]}); + next; + } + } - my $custmplpath = "$installroot/custom/install/windows"; - my $tmplpath = "$::XCATROOT/share/xcat/install/windows"; - if ($os =~ /^hyperv/) { - $custmplpath = "$installroot/custom/install/hyperv"; - $tmplpath = "$::XCATROOT/share/xcat/install/hyperv"; - } - my $tmplfile=xCAT::SvrUtils::get_tmpl_file_name($custmplpath, $profile, $os, $arch); - if (! $tmplfile) { $tmplfile=xCAT::SvrUtils::get_tmpl_file_name($tmplpath, $profile, $os, $arch); } + my $ph=$img_hash{$imagename}; + $os = $ph->{osver}; + $arch = $ph->{osarch}; + $profile = $ph->{profile}; + $partfile = $ph->{partitionfile}; + $tmplfile = $ph->{template}; + $installto = $ph->{installto}; + } else { + unless ($ent->{os} and $ent->{arch} and $ent->{profile}) + { + $callback->( + { + error => ["No profile defined in nodetype for $node"], + errorcode => [1] + } + ); + next; #No profile + } + + $os = $ent->{os}; + $arch = $ent->{arch}; + $profile = $ent->{profile}; + if ($os eq "imagex") { + my $wimfile="$installroot/images/$arch/$profile.wim"; + unless ( -r $wimfile ) { + $callback->({error=>["$wimfile not found, run rimage on a node to capture first"],errorcode=>[1]}); + next; + } + my $script=applyimagescript($arch,$profile); + my $shandle; + open($shandle,">","$installroot/autoinst/$node.cmd"); + print $shandle $script; + close($shandle); + if ($vpdhash->{$node}) { + mkwinlinks($node,$ent,$vpdhash->{$node}->[0]->{uuid}); + } else { + mkwinlinks($node,$ent); + } + if ($arch =~ /x86_64/) + { + $bptab->setNodeAttribs( + $node, + { + kernel => "Boot/pxeboot.0", + initrd => "", + kcmdline => "" + } + ); + } elsif ($arch =~ /x86/) { + unless (-r "$tftpdir/Boot/pxeboot32.0") { + my $origpxe; + my $pxeboot; + open($origpxe,"<$tftpdir/Boot/pxeboot.0"); + open($pxeboot,">$tftpdir/Boot/pxeboot32.0"); + binmode($origpxe); + binmode($pxeboot); + my @origpxecontent = <$origpxe>; + foreach (@origpxecontent) { + s/bootmgr.exe/bootm32.exe/; + print $pxeboot $_; + } + } + unless (-r "$tftpdir/bootm32.exe") { + my $origmgr; + my $bootmgr; + open($origmgr,"<$tftpdir/bootmgr.exe"); + open($bootmgr,">$tftpdir/bootm32.exe"); + binmode($origmgr); + binmode($bootmgr); + my @data = <$origmgr>; + foreach (@data) { + s/(\\.B.o.o.t.\\.B.)C(.)D/${1}3${2}2/; # 16 bit encoding... cheat + print $bootmgr $_; + } + } + $bptab->setNodeAttribs( + $node, + { + kernel => "Boot/pxeboot32.0", + initrd => "", + kcmdline => "" + } + ); + } + next; + } + + my $custmplpath = "$installroot/custom/install/windows"; + my $tmplpath = "$::XCATROOT/share/xcat/install/windows"; + if ($os =~ /^hyperv/) { + $custmplpath = "$installroot/custom/install/hyperv"; + $tmplpath = "$::XCATROOT/share/xcat/install/hyperv"; + } + my $tmplfile=xCAT::SvrUtils::get_tmpl_file_name($custmplpath, $profile, $os, $arch); + if (! $tmplfile) { $tmplfile=xCAT::SvrUtils::get_tmpl_file_name($tmplpath, $profile, $os, $arch); } + } + unless ( -r "$tmplfile") { - $callback->( - { - error => - ["No unattended template exists for " . $ent->{profile}], - errorcode => [1] - } - ); + $callback->({error =>["No unattended template exists for " . $ent->{profile}],errorcode => [1]}); next; } #Call the Template class to do substitution to produce an unattend.xml file in the autoinst dir my $tmperr; - my @utilfiles = ( - "fixupunattend.vbs", - "detectefi.exe", - "xCAT.psd1", - "xCAT.psm1", - "xCAT.format.ps1xml", - "nextdestiny.ps1", - ); - foreach my $utilfile (@utilfiles) { - unless (-r "$installroot/utils/windows/$utilfile" and stat("$::XCATROOT/share/xcat/netboot/windows/$utilfile")->mtime <= stat("$installroot/utils/windows/$utilfile")->mtime) { - mkpath("$installroot/utils/windows/"); - copy("$::XCATROOT/share/xcat/netboot/windows/$utilfile","$installroot/utils/windows/$utilfile"); - } - } - if (-r "$tmplfile") - { - $tmperr = - xCAT::Template->subvars( + my @utilfiles = ( + "fixupunattend.vbs", + "detectefi.exe", + "xCAT.psd1", + "xCAT.psm1", + "xCAT.format.ps1xml", + "nextdestiny.ps1", + ); + foreach my $utilfile (@utilfiles) { + unless (-r "$installroot/utils/windows/$utilfile" and stat("$::XCATROOT/share/xcat/netboot/windows/$utilfile")->mtime <= stat("$installroot/utils/windows/$utilfile")->mtime) { + mkpath("$installroot/utils/windows/"); + copy("$::XCATROOT/share/xcat/netboot/windows/$utilfile","$installroot/utils/windows/$utilfile"); + } + } + if (-r "$tmplfile") { + $tmperr = xCAT::Template->subvars( $tmplfile, "$installroot/autoinst/$node.xml", $node, - 0 - ); + 0); } - if ($tmperr) - { - $callback->( - { - node => [ - { - name => [$node], - error => [$tmperr], - errorcode => [1] - } - ] - } - ); + if ($tmperr) { + $callback->({node => [{name => [$node], error => [$tmperr], errorcode => [1]}]}); next; } @@ -405,7 +445,6 @@ sub mkinstall {error => [ "The Windows netboot image is not created, consult documentation on how to add Windows deployment support to xCAT"],errorcode=>[1] }); } elsif (-r $installroot."/$os/$arch/sources/install.wim") { - if ($arch =~ /x86/) { $bptab->setNodeAttribs( @@ -440,15 +479,53 @@ sub mkinstall } } + if (-f "$::XCATROOT/share/xcat/netboot/detectefi.exe" and not -f "$installroot/utils/detectefi.exe") { + mkpath("$installroot/utils/"); + copy("$::XCATROOT/share/xcat/netboot/detectefi.exe","$installroot/utils/detectefi.exe"); + } - if (-f "$::XCATROOT/share/xcat/netboot/detectefi.exe" and not -f "$installroot/utils/detectefi.exe") { - mkpath("$installroot/utils/"); - copy("$::XCATROOT/share/xcat/netboot/detectefi.exe","$installroot/utils/detectefi.exe"); - } + my $partcfg; + if ($partfile) { + if (-r $partfile) { + $partcfg = "[BIOS]"; + if (open (PFILE, "<$partfile")) { + while (<PFILE>) { + s/\s*$//g; + s/^\s*//g; + if (/^\[bios\](.*)/i) { + $partcfg .= $1; + } elsif (/^\[uefi\](.*)/i) { + $partcfg .= "[UEFI]$1"; + } else { + $partcfg .= $_; + } + } + } + } else { + $callback->({data =>["Cannot open partition configuration file: $partfile."]}); + } + } + + if ($installto && ($installto !~ /^[\d:]+$/)) { + $callback->({error =>["The format of installto is not correct: installto."]}); + $installto = ""; + } + + # generate the auto running command file for windows deployment open($shandle,">","$installroot/autoinst/$node.cmd"); - print $shandle 'for /f "tokens=2 delims= " %%i in ('."'net use ^| find ".'"install"'."') do set instdrv=%%i\r\n"; - print $shandle "%instdrv%\\utils\\windows\\fixupunattend.vbs %instdrv%\\autoinst\\$node.xml x:\\unattend.xml\r\n"; - + if ($partcfg) { + print $shandle "set PARTCFG=\"$partcfg\n"; + } + if ($installto) { + print $shandle "set INSTALLTO=$installto\n"; + } + print $shandle 'for /f "tokens=2 delims= " %%i in ('."'net use ^| find ".'"install"'."') do set instdrv=%%i\r\n"; + print $shandle "%instdrv%\\utils\\windows\\fixupunattend.vbs %instdrv%\\autoinst\\$node.xml x:\\unattend.xml\r\n"; + + #### test part + #print $shandle "start /max cmd\r\n"; + #print $shandle "pause\r\n"; + if ($sspeed) { $sport++; print $shandle "%instdrv%\\$os\\$arch\\setup /unattend:x:\\unattend.xml /emsport:COM$sport /emsbaudrate:$sspeed /noreboot\r\n"; @@ -460,7 +537,7 @@ sub mkinstall print $shandle 'reg copy HKLM\system\CurrentControlSet\services\TCPIP6\parameters HKLM\csystem\ControlSet001\services\TCPIP6\parameters /f'."\r\n"; print $shandle 'reg copy HKLM\system\CurrentControlSet\services\TCPIP6\parameters HKLM\csystem\ControlSet002\services\TCPIP6\parameters /f'."\r\n"; print $shandle 'reg unload HKLM\csystem'."\r\n"; - print $shandle "If EXIST X:\\Windows\\system32\\WindowsPowerShell GOTO PSH\r\n"; + print $shandle "If EXIST X:\\Windows\\system32\\WindowsPowerShell GOTO PSH\r\n"; print $shandle "IF %PROCESSOR_ARCHITECTURE%==AMD64 GOTO x64\r\n"; print $shandle "IF %PROCESSOR_ARCHITECTURE%==x64 GOTO x64\r\n"; print $shandle "IF %PROCESSOR_ARCHITECTURE%==x86 GOTO x86\r\n"; diff --git a/xCAT-server/share/xcat/install/windows/enterprise.win2k8.x86_64.tmpl b/xCAT-server/share/xcat/install/windows/enterprise.win2k8.x86_64.tmpl index 7a90b4e27..b019c369c 100644 --- a/xCAT-server/share/xcat/install/windows/enterprise.win2k8.x86_64.tmpl +++ b/xCAT-server/share/xcat/install/windows/enterprise.win2k8.x86_64.tmpl @@ -14,11 +14,7 @@ <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <DiskConfiguration> <WillShowUI>OnError</WillShowUI> - <Disk> - <DiskID>==INSTALLTODISK==</DiskID> - <WillWipeDisk>true</WillWipeDisk> - ==BOOTPARTITIONS== - </Disk> + ==DISKCONFIG== </DiskConfiguration> <DynamicUpdate> <Enable>false</Enable> @@ -27,7 +23,7 @@ <OSImage> <InstallTo> <DiskID>==INSTALLTODISK==</DiskID> - <PartitionID>1</PartitionID> + <PartitionID>==INSTALLTOPART==</PartitionID> </InstallTo> <InstallFrom> <MetaData wcm:action="add"> @@ -90,6 +86,7 @@ </component> </settings> <settings pass="specialize"> + #WINNETCFG# <component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <fDenyTSConnections>false</fDenyTSConnections> </component> diff --git a/xCAT-server/share/xcat/netboot/windows/fixupunattend.vbs b/xCAT-server/share/xcat/netboot/windows/fixupunattend.vbs index e3fdf572d..b23a9ad92 100644 --- a/xCAT-server/share/xcat/netboot/windows/fixupunattend.vbs +++ b/xCAT-server/share/xcat/netboot/windows/fixupunattend.vbs @@ -1,5 +1,5 @@ Dim filesys, srcfile, srcfilename, fline, dstfilename, dstfile, myshell, netuse -Dim tmpstr, elems, instdrv +Dim tmpstr, elems, instdrv, instpart, partcfg, partbios, partuefi Set myshell = WScript.createObject("WScript.Shell") Set netuse = myshell.Exec("net use") Dim drvletter @@ -23,9 +23,37 @@ if instdrv = "" Then instdrv = myenv("INSTALLTO") End If if instdrv = "" Then - instdrv = "0" + instdrv = "0:0" End If - + +Dim strpoint +strpoint = InStr(instdrv, ":") +if strpoint Then + tmpstr = instdrv + instdrv = left(tmpstr,strpoint-1) + instpart = mid(tmpstr,strpoint+1) +End If + +partcfg = myshell.ExpandEnvironmentStrings ( "%PARTCFG%" ) +if InStr(partcfg,"%PARTCFG%") Then + Set myenv=myshell.Environment("User") + partcfg = myenv("%PARTCFG%") +End If +if instdrv = "" Then + Set myenv=myshell.Environment("System") + partcfg = myenv("%PARTCFG%") +End If + +strpoint = InStr(partcfg, "[BIOS]") +If strpoint Then + partbios = Mid(partcfg, strpoint+6) + strpoint = InStr(partbios, "[UEFI]") + If strpoint Then + partuefi = Mid(partbios, strpoint+6) + partbios = Left(partbios, strpoint-1) + End If +End If + Set filesys = CreateObject("Scripting.FileSystemObject") dim notefi notefi=1 @@ -41,11 +69,35 @@ Do Until srcfile.AtEndOfStream fline = srcfile.ReadLine if notefi=0 then fline = Replace(fline,"==BOOTPARTITIONS==","<CreatePartitions><CreatePartition><Order>1</Order><Type>EFI</Type><Size>260</Size></CreatePartition><CreatePartition><Order>2</Order><Type>MSR</Type><Size>128</Size></CreatePartition><CreatePartition><Order>3</Order><Type>Primary</Type><Extend>true</Extend></CreatePartition></CreatePartitions>") - fline = Replace(fline,"==INSTALLTOPART==","3") + + if partuefi<>"" Then + fline = Replace(fline,"==DISKCONFIG==", partuefi) + else + fline = Replace(fline,"==DISKCONFIG==","<DiskID>" & instdrv & "<Disk></DiskID><WillWipeDisk>true</WillWipeDisk><CreatePartitions><CreatePartition><Order>1</Order><Type>EFI</Type><Size>260</Size></CreatePartition><CreatePartition><Order>2</Order><Type>MSR</Type><Size>128</Size></CreatePartition><CreatePartition><Order>3</Order><Type>Primary</Type><Extend>true</Extend></CreatePartition></CreatePartitions></Disk>") + end if + + if instpart<>"0" Then + fline = Replace(fline,"==INSTALLTOPART==", instpart) + else + fline = Replace(fline,"==INSTALLTOPART==","3") + end if else fline = Replace(fline,"==BOOTPARTITIONS==","<CreatePartitions><CreatePartition><Order>1</Order><Type>Primary</Type><Extend>true</Extend></CreatePartition></CreatePartitions>") - fline = Replace(fline,"==INSTALLTOPART==","1") + + if partbios<>"" Then + fline = Replace(fline,"==DISKCONFIG==", partbios) + else + fline = Replace(fline,"==DISKCONFIG==", "<DiskID>" & instdrv & "<Disk></DiskID><WillWipeDisk>true</WillWipeDisk><CreatePartitions><CreatePartition><Order>1</Order><Type>Primary</Type><Extend>true</Extend></CreatePartition></CreatePartitions></Disk>") + end if + + if instpart<>"0" Then + fline = Replace(fline,"==INSTALLTOPART==",instpart) + else + fline = Replace(fline,"==INSTALLTOPART==","1") + end if end if + fline = Replace(fline,"==INSTALLTODISK==",instdrv) - dstfile.WriteLine(Replace(fline,"==INSTALLSHARE==",drvletter)) + + dstfile.WriteLine(Replace(fline,"==INSTALLSHARE==",drvletter)) Loop diff --git a/xCAT-server/share/xcat/netboot/windows/startnet.cmd b/xCAT-server/share/xcat/netboot/windows/startnet.cmd index 91bd12a8f..0b87df390 100644 --- a/xCAT-server/share/xcat/netboot/windows/startnet.cmd +++ b/xCAT-server/share/xcat/netboot/windows/startnet.cmd @@ -25,7 +25,7 @@ echo Waiting for successful mount of \\%XCATD%\install (if this hangs, check tha :nomount net use i: \\%XCATD%\install || goto :nomount echo Successfully mounted \\%XCATD%\install, moving on to execute remote script -for /f "delims=: tokens=2" %%c in ('ipconfig ^|find "IPv4 Address. . ."') do set NODEIP=%%c +for /f "delims=: tokens=2" %%c in ('ipconfig ^|find "IPv4 Address. . ."') do for /f "tokens=1" %%d in ('echo %%c') do for /f "delims=. tokens=1,2,3,4" %%m in ('echo %%d') do if "%%m.%%n" NEQ "169.254" set NODEIP=%%m.%%n.%%o.%%p for /f %%c in ('echo %NODEIP%') do set NODEIP=%%c if exist i:\autoinst\%NODEIP%.cmd copy i:\autoinst\%NODEIP%.cmd x:\xcat\autoscript.cmd if exist i:\autoinst\%uuid%.cmd copy i:\autoinst\%uuid%.cmd x:\xcat\autoscript.cmd