| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package fsdriver
- import (
- "fmt"
- "math/rand"
- "path"
- "regexp"
- "strings"
- "syscall"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/version"
- "yunion.io/x/pkg/utils"
- "yunion.io/x/onecloud/pkg/apis"
- api "yunion.io/x/onecloud/pkg/apis/compute"
- "yunion.io/x/onecloud/pkg/cloudcommon/types"
- deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
- "yunion.io/x/onecloud/pkg/util/fileutils2"
- "yunion.io/x/onecloud/pkg/util/netutils2"
- "yunion.io/x/onecloud/pkg/util/procutils"
- "yunion.io/x/onecloud/pkg/util/seclib2"
- "yunion.io/x/onecloud/pkg/util/stringutils2"
- "yunion.io/x/onecloud/pkg/util/winutils"
- )
- const (
- ACTIVE_COMPUTER_NAME_KEY = `HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName`
- COMPUTER_NAME_KEY = `HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName`
- TCPIP_PARAM_KEY = `HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters`
- BOOT_SCRIPT_PATH = "/Windows/System32/GroupPolicy/Machine/Scripts/Startup/cloudboot.bat"
- WIN_BOOT_SCRIPT_PATH = "cloudboot"
- WIN_TELEGRAF_BINARY_PATH = "/opt/yunion/bin/telegraf.exe"
- WIN_TELEGRAF_PATH = "/Program Files/Telegraf"
- WIN_QGA_PATH = "/Program Files/Qemu-ga"
- )
- type SWindowsRootFs struct {
- *sGuestRootFsDriver
- guestDebugLogPath string
- bootScript string
- bootScripts map[string]string
- }
- func NewWindowsRootFs(part IDiskPartition) IRootFsDriver {
- seq := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
- suffix := make([]byte, 16)
- lenSeq := len(seq)
- for i := 0; i < 16; i++ {
- suffix[i] = seq[rand.Intn(lenSeq)]
- }
- return &SWindowsRootFs{
- sGuestRootFsDriver: newGuestRootFsDriver(part),
- guestDebugLogPath: `%SystemRoot%\mdbg_` + string(suffix),
- bootScripts: make(map[string]string),
- }
- }
- func (w *SWindowsRootFs) IsFsCaseInsensitive() bool {
- return true
- }
- func (w *SWindowsRootFs) GetName() string {
- return "Windows"
- }
- func (w *SWindowsRootFs) String() string {
- return "WindowsRootFs"
- }
- func (w *SWindowsRootFs) DeployPublicKey(IDiskPartition, string, *deployapi.SSHKeys) error {
- return nil
- }
- func (w *SWindowsRootFs) RootSignatures() []string {
- return []string{
- "/program files", "/windows",
- "/windows/system32/drivers/etc", "/windows/system32/config",
- "/windows/system32/config/sam",
- "/windows/system32/config/software",
- "/windows/system32/config/system",
- }
- }
- func (w *SWindowsRootFs) GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo {
- confPath := w.rootFs.GetLocalPath("/windows/system32/config", true)
- tool := winutils.NewWinRegTool(confPath)
- if tool.CheckPath() {
- distro := w.GetName()
- version := tool.GetProductName()
- curVersion := tool.GetVersion()
- arch := w.GetArch(hostCpuArch)
- lan := tool.GetInstallLanguage()
- return &deployapi.ReleaseInfo{
- Distro: distro,
- Version: version,
- Arch: arch,
- Language: lan,
- CurrentVersion: curVersion,
- }
- } else {
- return nil
- }
- }
- func (w *SWindowsRootFs) GetLoginAccount(rootFs IDiskPartition, sUser string, defaultRootUser bool, windowsDefaultAdminUser bool) (string, error) {
- confPath := w.rootFs.GetLocalPath("/windows/system32/config", true)
- tool := winutils.NewWinRegTool(confPath)
- tool.CheckPath()
- users := tool.GetUsers()
- admin := "Administrator"
- selUsr := ""
- isWin10NonPro := w.IsWindows10NonPro()
- // Win10 try not to use Administrator users // Win 10 professional can use Adminsitrator
- if _, ok := users[admin]; ok && windowsDefaultAdminUser && !isWin10NonPro && w.GetIRootFsDriver().AllowAdminLogin() {
- selUsr = admin
- } else {
- // Looking for an unlocked user who is not an Administrator
- for user, ok := range users {
- if !ok {
- continue
- }
- if user != admin {
- selUsr = user
- }
- }
- if _, ok := users[admin]; ok && len(selUsr) == 0 {
- selUsr = admin
- }
- }
- if selUsr == "" {
- return "", fmt.Errorf("no unlocked user")
- }
- if !users[selUsr] {
- // user is locked
- tool.UnlockUser(selUsr)
- }
- return selUsr, nil
- }
- func (w *SWindowsRootFs) GetArch(hostCpuArch string) string {
- if w.rootFs.Exists("/program files (x86)", true) {
- return apis.OS_ARCH_X86_64
- } else if w.rootFs.Exists("/program files (arm)", true) {
- return apis.OS_ARCH_AARCH64
- }
- if hostCpuArch == apis.OS_ARCH_AARCH32 {
- return apis.OS_ARCH_AARCH32
- } else {
- return apis.OS_ARCH_X86_32
- }
- }
- func (w *SWindowsRootFs) IsWindows10NonPro() bool {
- info := w.GetReleaseInfo(nil)
- if info != nil && strings.HasPrefix(info.Version, "Windows 10 ") && !strings.HasPrefix(info.Version, "Windows 10 Pro") {
- return true
- }
- return false
- }
- func (w *SWindowsRootFs) IsOldWindows() bool {
- info := w.GetReleaseInfo(nil)
- if info != nil && strings.HasPrefix(info.CurrentVersion, "5.") {
- return true
- }
- return false
- }
- func (w *SWindowsRootFs) GetOs() string {
- return "Windows"
- }
- func (w *SWindowsRootFs) appendGuestBootScript(name, content string) {
- w.bootScript += "\r\n" + fmt.Sprintf("start %s", name)
- w.bootScripts[name] = content
- }
- func (w *SWindowsRootFs) regAdd(path, key, val, regType string) string {
- return fmt.Sprintf(`REG ADD %s /V "%s" /D "%s" /T %s /F`, path, key, val, regType)
- }
- func (w *SWindowsRootFs) putGuestScriptContents(spath, content string) error {
- contentArr := []string{}
- contentLen := len(content)
- var j = 0
- if content[0] == '\n' {
- contentArr = append(contentArr, "")
- j += 1
- }
- for i := 1; i < contentLen; i++ {
- if content[i] == '\n' && content[i-1] != '\r' {
- contentArr = append(contentArr, content[j:i])
- j = i + 1
- }
- }
- if j < contentLen {
- contentArr = append(contentArr, content[j:])
- } else {
- contentArr = append(contentArr, "")
- }
- content = strings.Join(contentArr, "\r\n")
- return w.rootFs.FilePutContents(spath, content, false, true)
- }
- func (w *SWindowsRootFs) DeployHostname(part IDiskPartition, hostname, domain string) error {
- bootScript := strings.Join([]string{
- `set HOSTNAME_SCRIPT=%SystemRoot%\hostnamecfg.bat`,
- `if exist %HOSTNAME_SCRIPT% (`,
- ` call %HOSTNAME_SCRIPT%`,
- ` del %HOSTNAME_SCRIPT%`,
- `)`,
- }, "\r\n")
- w.appendGuestBootScript("hostnamecfg", bootScript)
- lines := []string{}
- for k, v := range map[string]string{
- "Hostname": hostname,
- "Domain": domain,
- "NV Hostname": hostname,
- "NV Domain": domain,
- } {
- lines = append(lines, w.regAdd(TCPIP_PARAM_KEY, k, v, "REG_SZ"))
- }
- // windows allow a maximal length of 15
- // http://support.microsoft.com/kb/909264
- if len(hostname) > api.MAX_WINDOWS_COMPUTER_NAME_LENGTH {
- hostname = hostname[:api.MAX_WINDOWS_COMPUTER_NAME_LENGTH]
- }
- lines = append(lines, w.regAdd(ACTIVE_COMPUTER_NAME_KEY, "ComputerName", hostname, "REG_SZ"))
- lines = append(lines, w.regAdd(COMPUTER_NAME_KEY, "ComputerName", hostname, "REG_SZ"))
- hostScripts := strings.Join(lines, "\r\n")
- return w.putGuestScriptContents("/windows/hostnamecfg.bat", hostScripts)
- }
- func (w *SWindowsRootFs) DeployHosts(part IDiskPartition, hn, domain string, ips []string) error {
- var (
- ETC_HOSTS = "/windows/system32/drivers/etc/hosts"
- oldHf = ""
- )
- if w.rootFs.Exists(ETC_HOSTS, true) {
- oldHfBytes, err := w.rootFs.FileGetContents(ETC_HOSTS, true)
- if err != nil {
- log.Errorln(err)
- return err
- }
- oldHf = string(oldHfBytes)
- }
- return w.rootFs.FilePutContents(ETC_HOSTS, fileutils2.FormatHostsFile(oldHf, ips, hn, getHostname(hn, domain)), false, true)
- }
- func (w *SWindowsRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []*types.SServerNic) error {
- mainNic, err := netutils2.GetMainNicFromDeployApi(nics)
- if err != nil {
- return err
- }
- mainIp := ""
- if mainNic != nil {
- mainIp = mainNic.Ip
- }
- mainIp6 := ""
- if mainNic != nil {
- mainIp6 = mainNic.Ip6
- }
- bootScript := strings.Join([]string{
- `set NETCFG_SCRIPT=%SystemRoot%\netcfg.bat`,
- `if exist %NETCFG_SCRIPT% (`,
- ` call %NETCFG_SCRIPT%`,
- ` del %NETCFG_SCRIPT%`,
- `)`,
- }, "\r\n")
- w.appendGuestBootScript("netcfg", bootScript)
- lines := []string{
- "@echo off",
- w.MakeGuestDebugCmd("netcfg step 1"),
- "setlocal enableDelayedExpansion",
- `for /f "delims=" %%a in ('getmac /fo csv /nh /v') do (`,
- ` set line=%%a&set line=!line:"=,!`,
- ` for /f "delims=,,, tokens=1,3" %%b in ("!line!") do (`,
- }
- hasV6 := false
- for _, snic := range nics {
- if len(snic.Ip6) > 0 {
- hasV6 = true
- break
- }
- }
- if hasV6 {
- lines = append(lines, ` netsh interface teredo set state disable`)
- lines = append(lines, ` netsh interface 6to4 set state state=disabled`)
- lines = append(lines, ` netsh interface isatap set state state=disabled`)
- lines = append(lines, ` netsh interface ipv6 set privacy disabled store=persistent`)
- lines = append(lines, ` netsh interface ipv6 set global randomizeidentifiers=disabled store=persistent`)
- }
- for _, snic := range nics {
- mac := snic.Mac
- mac = strings.Replace(strings.ToUpper(mac), ":", "-", -1)
- lines = append(lines, fmt.Sprintf(` if "%%%%c" == "%s" (`, mac))
- if snic.Mtu > 0 {
- lines = append(lines, fmt.Sprintf(` netsh interface ipv4 set subinterface "%%%%b" mtu=%d`, snic.Mtu))
- }
- if snic.Manual {
- if len(snic.Ip) > 0 {
- netmask := netutils2.Netlen2Mask(int(snic.Masklen))
- cfg := fmt.Sprintf(` netsh interface ip set address "%%%%b" static %s %s`, snic.Ip, netmask)
- if len(snic.Gateway) > 0 && snic.Ip == mainIp {
- cfg += fmt.Sprintf(" %s", snic.Gateway)
- }
- lines = append(lines, cfg)
- }
- if len(snic.Ip6) > 0 {
- cfg := fmt.Sprintf(` netsh interface ipv6 add address "%%%%b" %s/%d store=persistent`, snic.Ip6, snic.Masklen6)
- lines = append(lines, cfg)
- if len(snic.Gateway6) > 0 && snic.Ip6 == mainIp6 {
- cfg := fmt.Sprintf(` netsh interface ipv6 add route ::/0 "%%%%b" %s`, snic.Gateway6)
- lines = append(lines, cfg)
- }
- }
- routes4 := []netutils2.SRouteInfo{}
- routes6 := []netutils2.SRouteInfo{}
- routes4, routes6 = netutils2.AddNicRoutes(routes4, routes6, snic, mainIp, mainIp6, len(nics))
- for _, r := range routes4 {
- lines = append(lines, fmt.Sprintf(` netsh interface ip add route %s/%d %s "%%%%b"`, r.Prefix, r.PrefixLen, r.Gateway.String()))
- }
- for _, r := range routes6 {
- lines = append(lines, fmt.Sprintf(` netsh interface ipv6 add route %s/%d %s "%%%%b"`, r.Prefix, r.PrefixLen, r.Gateway.String()))
- }
- dns4list, dns6list := netutils2.GetNicDns(snic)
- if len(dns4list) > 0 {
- lines = append(lines, fmt.Sprintf(
- ` netsh interface ip set dns name="%%%%b" source=static addr=%s`, dns4list[0]))
- if len(dns4list) > 1 {
- for i := 1; i < len(dns4list); i++ {
- lines = append(lines, fmt.Sprintf(` netsh interface ip add dns "%%%%b" %s index=%d`, dns4list[i], i+1))
- }
- }
- }
- if len(dns6list) > 0 {
- lines = append(lines, fmt.Sprintf(
- ` netsh interface ipv6 set dns name="%%%%b" source=static addr=%s`, dns6list[0]))
- if len(dns6list) > 1 {
- for i := 1; i < len(dns6list); i++ {
- lines = append(lines, fmt.Sprintf(` netsh interface ip add dns "%%%%b" %s index=%d`, dns6list[i], i+1))
- }
- }
- }
- if len(snic.Domain) > 0 && snic.Ip == mainIp {
- lines = append(lines, w.regAdd(TCPIP_PARAM_KEY, "SearchList", snic.Domain, "REG_SZ"))
- }
- } else {
- if len(snic.Ip) > 0 {
- lines = append(lines, ` netsh interface ip set address "%%b" dhcp`)
- lines = append(lines, ` netsh interface ip set dns "%%b" dhcp`)
- }
- if len(snic.Ip6) > 0 {
- cfg := ` netsh interface ipv6 set interface "%%b" routerdiscovery=enabled store=persistent`
- lines = append(lines, cfg)
- cfg = ` netsh interface ipv6 set interface "%%b" managedaddress=enabled otherstateful=enabled store=persistent`
- lines = append(lines, cfg)
- }
- }
- lines = append(lines, ` )`)
- }
- lines = append(lines, ` )`)
- lines = append(lines, `)`)
- lines = append(lines, w.MakeGuestDebugCmd("netcfg step 2"))
- // lines = append(lines, `netsh advfirewall firewall set rule group=\"remote desktop\" new enable=yes`)
- netScript := strings.Join(lines, "\r\n")
- return w.putGuestScriptContents("/windows/netcfg.bat", netScript)
- }
- func (w *SWindowsRootFs) MakeGuestDebugCmd(content string) string {
- mark := "============="
- content = regexp.MustCompile(`(["^&<>|])`).ReplaceAllString(content, "^$1")
- return fmt.Sprintf("echo %s %s %s >> %s", mark, content, mark, w.guestDebugLogPath)
- }
- func (w *SWindowsRootFs) prependGuestBootScript(content string) {
- w.bootScript = content + "\r\n" + w.bootScript
- }
- func (w *SWindowsRootFs) PrepareFsForTemplate(IDiskPartition) error {
- for _, f := range []string{"/Pagefile.sys", "/Hiberfil.sys", "/Swapfile.sys"} {
- if w.rootFs.Exists(f, true) {
- w.rootFs.Remove(f, true)
- }
- }
- return nil
- }
- func (w *SWindowsRootFs) CommitChanges(part IDiskPartition) error {
- confPath := part.GetLocalPath("/windows/system32/config", true)
- tool := winutils.NewWinRegTool(confPath)
- tool.CheckPath()
- tool.EnableRdp()
- tool.ResetUSBProfile()
- if w.IsOldWindows() {
- // windows prior to windows 2003 should not try to commit changes
- return nil
- }
- tool.InstallGpeditStartScript(WIN_BOOT_SCRIPT_PATH)
- bootDir := path.Dir(BOOT_SCRIPT_PATH)
- if err := w.rootFs.Mkdir(bootDir, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR, true); err != nil {
- return err
- }
- if err := w.rootFs.FilePutContents(BOOT_SCRIPT_PATH, w.bootScript, false, false); err != nil {
- return errors.Wrap(err, "write boot script")
- }
- for k, v := range w.bootScripts {
- if err := w.rootFs.FilePutContents(path.Join(bootDir, fmt.Sprintf("%s.bat", k)), v, false, false); err != nil {
- return errors.Wrap(err, "write boot scripts")
- }
- }
- return nil
- }
- func (w *SWindowsRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string, isRandomPassword bool) (string, error) {
- rinfo := w.GetReleaseInfo(part)
- confPath := part.GetLocalPath("/windows/system32/config", true)
- tool := winutils.NewWinRegTool(confPath)
- tool.CheckPath()
- success := false
- // symbol ^ is escape character is batch file.
- password = strings.ReplaceAll(password, "^", "")
- if rinfo != nil && version.GE(rinfo.CurrentVersion, "6.1") {
- success = w.deployPublicKeyByGuest(account, password)
- } else {
- success = tool.ChangePassword(account, password) == nil
- }
- var (
- secret string
- err error
- )
- if success {
- if len(publicKey) > 0 {
- secret, err = seclib2.EncryptBase64(publicKey, password)
- if err != nil {
- return "", err
- }
- } else {
- secret, err = utils.EncryptAESBase64(gid, password)
- if err != nil {
- return "", err
- }
- }
- if rinfo != nil && strings.Contains(rinfo.Version, "Windows XP") {
- if len(tool.GetLogontype()) > 0 {
- tool.SetLogontype("0x0")
- }
- }
- } else {
- log.Errorf("Failed Password %s", account)
- }
- defUanme := tool.GetDefaultAccount()
- if len(defUanme) > 0 && defUanme != account {
- tool.SetDefaultAccount(account)
- }
- return secret, nil
- }
- func (w *SWindowsRootFs) deployPublicKeyByGuest(uname, passwd string) bool {
- if !w.deploySetupCompleteScripts(uname, passwd) {
- return false
- }
- bootScript := strings.Join([]string{
- `set CHANGE_PASSWD_SCRIPT=%SystemRoot%\chgpwd.bat`,
- `if exist %CHANGE_PASSWD_SCRIPT% (`,
- ` call %CHANGE_PASSWD_SCRIPT%`,
- ` del %CHANGE_PASSWD_SCRIPT%`,
- `)`,
- }, "\r\n")
- w.appendGuestBootScript("chgpwd", bootScript)
- logPath := w.guestDebugLogPath
- chksum := stringutils2.GetMD5Hash(passwd + logPath[(len(logPath)-10):])
- chgpwdScript := strings.Join([]string{
- w.MakeGuestDebugCmd("change password step 1"),
- strings.Join([]string{
- `%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe`,
- ` -executionpolicy bypass %SystemRoot%\chgpwd.ps1`,
- fmt.Sprintf(" %s %s %s %s", uname, passwd, chksum, logPath),
- }, ""),
- `del %SystemRoot%\chgpwd.ps1`,
- w.MakeGuestDebugCmd("change password step 2"),
- }, "\r\n")
- if w.putGuestScriptContents("/windows/chgpwd.bat", chgpwdScript) != nil {
- return false
- }
- if w.putGuestScriptContents("/windows/chgpwd.ps1", WinScriptChangePassword) != nil {
- return false
- }
- return true
- }
- func (w *SWindowsRootFs) deploySetupCompleteScripts(uname, passwd string) bool {
- SETUP_SCRIPT_PATH := "/Windows/Setup/Scripts/SetupComplete.cmd"
- if !w.rootFs.Exists(path.Dir(SETUP_SCRIPT_PATH), true) {
- w.rootFs.Mkdir(path.Dir(SETUP_SCRIPT_PATH),
- syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR, true)
- }
- if w.putGuestScriptContents("/windows/chgpwd_setup.ps1", WinScriptChangePassword) != nil {
- return false
- }
- cmds := []string{
- `%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass %SystemRoot%\chgpwd_setup.ps1 ` +
- fmt.Sprintf("%s %s", uname, passwd),
- "Net stop wuauserv",
- }
- for _, v := range [][3]string{
- {"AUOptions", "REG_DWORD", "3"},
- {"NoAutoUpdate", "REG_DWORD", "0"},
- {"ScheduledInstallDay", "REG_DWORD", "0"},
- {"ScheduledInstallTime", "REG_DWORD", "4"},
- {"AutoInstallMinorUpdates", "REG_DWORD", "1"},
- {"NoAutoRebootWithLoggedOnUsers", "REG_DWORD", "1"},
- {"IncludeRecommendedUpdates", "REG_DWORD", "0"},
- {"EnableFeaturedSoftware", "REG_DWORD", "1"},
- } {
- cmds = append(cmds, fmt.Sprintf(`REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v %s /t %s /d %s /f`,
- v[0], v[1], v[2]))
- }
- cmds = append(cmds, `REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /t REG_DWORD /d 1 /f`)
- cmds = append(cmds, "Net start wuauserv")
- cmds = append(cmds, "wuauclt /detectnow")
- cmds = append(cmds, `del %SystemRoot%\chgpwd_setup.ps1`)
- cmds = append(cmds, `del %SystemRoot%\Setup\Scripts\SetupComplete.cmd`)
- if w.putGuestScriptContents(SETUP_SCRIPT_PATH, strings.Join(cmds, "\r\n")) != nil {
- return false
- }
- return true
- }
- func (w *SWindowsRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []*deployapi.Disk) error {
- bootScript := strings.Join([]string{
- `set MOUNT_DISK_SCRIPT=%SystemRoot%\mountdisk.bat`,
- `if exist %MOUNT_DISK_SCRIPT% (`,
- ` call %MOUNT_DISK_SCRIPT%`,
- ` del %MOUNT_DISK_SCRIPT%`,
- `)`,
- }, "\r\n")
- w.appendGuestBootScript("mountdisk", bootScript)
- logPath := w.guestDebugLogPath
- mountScript := strings.Join([]string{
- w.MakeGuestDebugCmd("mount disk step 1"),
- `cscript %SystemRoot%\mountdisk.js --debug ` + logPath,
- `del %SystemRoot%\mountdisk.js`,
- w.MakeGuestDebugCmd("mount disk step 2"),
- }, "\r\n")
- if w.putGuestScriptContents("/windows/mountdisk.bat", mountScript) != nil {
- return nil
- }
- w.putGuestScriptContents("/windows/mountdisk.js", WinScriptMountDisk)
- return nil
- }
- func (w *SWindowsRootFs) DetectIsUEFISupport(part IDiskPartition) bool {
- content, err := w.rootFs.FileGetContents("/windows/panther/setupact.log", true)
- if err != nil {
- log.Errorln(err)
- return false
- }
- contentStr := string(content)
- sep := "Detected boot environment: "
- idx := strings.Index(contentStr, sep)
- if idx < 0 {
- return false
- }
- if strings.HasPrefix(contentStr[idx+len(sep):], "EFI") ||
- strings.HasPrefix(contentStr[idx+len(sep):], "UEFI") {
- return true
- }
- return false
- }
- func (l *SWindowsRootFs) IsResizeFsPartitionSupport() bool {
- return true
- }
- func (w *SWindowsRootFs) DeployQgaService(part IDiskPartition) error {
- if err := w.rootFs.Mkdir(WIN_QGA_PATH, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR, true); err != nil {
- return errors.Wrap(err, "mkdir qemu-ga path")
- }
- qgaInstallerPath := path.Join(w.rootFs.GetMountPath(), WIN_QGA_PATH, "qemu-ga-x86_64.msi")
- output, err := procutils.NewCommand("cp", "-f", QGA_WIN_MSI_INSTALLER_PATH, qgaInstallerPath).Output()
- if err != nil {
- return errors.Wrapf(err, "cp qga installer failed %s", output)
- }
- bootScript := strings.Join([]string{
- `start "" "%PROGRAMFILES%\Qemu-ga\qemu-ga-x86_64.msi"`,
- }, "\r\n")
- w.appendGuestBootScript("qemu-ga", bootScript)
- return nil
- }
- func (w *SWindowsRootFs) DeployQgaBlackList(part IDiskPartition) error {
- return nil
- }
- func (w *SWindowsRootFs) DeployTelegraf(config string) (bool, error) {
- if err := w.rootFs.Mkdir(WIN_TELEGRAF_PATH, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR, true); err != nil {
- return false, errors.Wrap(err, "mkdir telegraf path")
- }
- telegrafConfPath := path.Join(w.rootFs.GetMountPath(), WIN_TELEGRAF_PATH, "telegraf.conf")
- if err := w.rootFs.FilePutContents(telegrafConfPath, config, false, true); err != nil {
- return false, errors.Wrap(err, "write boot script")
- }
- telegrafConfPath = strings.ReplaceAll(path.Join("%PROGRAMFILES%", "Telegraf", "telegraf.conf"), "/", "\\")
- telegrafBinaryPath := path.Join(w.rootFs.GetMountPath(), WIN_TELEGRAF_PATH, "telegraf.exe")
- output, err := procutils.NewCommand("cp", "-f", WIN_TELEGRAF_BINARY_PATH, telegrafBinaryPath).Output()
- if err != nil {
- return false, errors.Wrapf(err, "cp telegraf failed %s", output)
- }
- telegrafBinaryPath = strings.ReplaceAll(path.Join("%PROGRAMFILES%", "Telegraf", "telegraf.exe"), "/", "\\")
- bootScript := strings.Join([]string{
- `set SETUP_TELEGRAF_SCRIPT=%SystemRoot%\telegraf.bat`,
- `if exist %SETUP_TELEGRAF_SCRIPT% (`,
- ` call %SETUP_TELEGRAF_SCRIPT%`,
- ` del %SETUP_TELEGRAF_SCRIPT%`,
- `)`,
- }, "\r\n")
- w.appendGuestBootScript("telegraf", bootScript)
- setupTelegrafBatScript := strings.Join([]string{
- w.MakeGuestDebugCmd("setup telegraf step 1"),
- strings.Join([]string{
- `%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe`,
- ` -executionpolicy bypass %SystemRoot%\telegraf.ps1`,
- fmt.Sprintf(" '%s' '%s' >> %s_telegraf", telegrafBinaryPath, telegrafConfPath, w.guestDebugLogPath),
- }, ""),
- `del %SystemRoot%\telegraf.ps1`,
- w.MakeGuestDebugCmd("setup telegraf step 2"),
- }, "\r\n")
- if err := w.putGuestScriptContents("/windows/telegraf.bat", setupTelegrafBatScript); err != nil {
- return false, errors.Wrap(err, "put setup bat scirpt")
- }
- if err := w.putGuestScriptContents("/windows/telegraf.ps1", winTelegrafSetupPowerShellScript); err != nil {
- return false, errors.Wrap(err, "put setup ps1 script")
- }
- return true, nil
- }
- func (w *SWindowsRootFs) ConfigSshd(loginAccount, loginPassword string, sshPort int) error {
- return nil
- }
|