Skip to content

Commit

Permalink
fix windows install regedit record
Browse files Browse the repository at this point in the history
  • Loading branch information
wanyaoqi committed Jun 15, 2020
1 parent f441306 commit 9372a7b
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 34 deletions.
4 changes: 2 additions & 2 deletions pkg/hostman/diskutils/fsutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func ResizeDiskFs(diskPath string, sizeMb int) error {
}
log.Infof("gdisk: %s %s", stdoutPut, stderrOutPut)
if err = proc.Wait(); err != nil {
if status, succ := procutils.GetExitStatus(err); succ {
if status, succ := proc.GetExitStatus(err); succ {
if status != 1 {
return err
}
Expand Down Expand Up @@ -279,7 +279,7 @@ func FsckExtFs(fpath string) bool {
} else {
err = cmd.Wait()
if err != nil {
if status, ok := procutils.GetExitStatus(err); ok {
if status, ok := cmd.GetExitStatus(err); ok {
if status < 4 {
return true
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/hostman/guestfs/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,13 @@ func DeployGuestFs(
}

func IsPartitionReadonly(rootfs fsdriver.IDiskPartition) bool {
log.Infof("Test if read-only fs ...")
var filename = fmt.Sprintf("/.%f", rand.Float32())
if err := rootfs.FilePutContents(filename, fmt.Sprintf("%f", rand.Float32()), false, false); err == nil {
rootfs.Remove(filename, false)
log.Infof("File system %s is not readonly", rootfs.GetMountPath())
return false
} else {
log.Errorf("File system is readonly: %s", err)
log.Errorf("File system %s is readonly: %s", rootfs.GetMountPath(), err)
return true
}
}
39 changes: 27 additions & 12 deletions pkg/hostman/guestfs/fsdriver/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"syscall"

"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"

"yunion.io/x/onecloud/pkg/cloudcommon/types"
Expand All @@ -38,14 +39,16 @@ import (
const (
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.bat"
WIN_BOOT_SCRIPT_PATH = "cloudboot"
)

type SWindowsRootFs struct {
*sGuestRootFsDriver

guestDebugLogPath string
bootScripts string

bootScript string
bootScripts map[string]string
}

func NewWindowsRootFs(part IDiskPartition) IRootFsDriver {
Expand All @@ -59,6 +62,7 @@ func NewWindowsRootFs(part IDiskPartition) IRootFsDriver {
return &SWindowsRootFs{
sGuestRootFsDriver: newGuestRootFsDriver(part),
guestDebugLogPath: `%SystemRoot%\mdbg_` + string(suffix),
bootScripts: make(map[string]string),
}
}

Expand Down Expand Up @@ -149,9 +153,9 @@ func (w *SWindowsRootFs) GetOs() string {
return "Windows"
}

func (w *SWindowsRootFs) appendGuestBootScript(content string) string {
w.bootScripts += "\r\n" + content
return w.bootScripts
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 {
Expand Down Expand Up @@ -192,7 +196,7 @@ func (w *SWindowsRootFs) DeployHostname(part IDiskPartition, hostname, domain st
` del %HOSTNAME_SCRIPT%`,
`)`,
}, "\r\n")
w.appendGuestBootScript(bootScript)
w.appendGuestBootScript("hostnamecfg", bootScript)

lines := []string{}
for k, v := range map[string]string{
Expand Down Expand Up @@ -247,7 +251,7 @@ func (w *SWindowsRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []*
` del %NETCFG_SCRIPT%`,
`)`,
}, "\r\n")
w.appendGuestBootScript(bootScript)
w.appendGuestBootScript("netcfg", bootScript)
lines := []string{
"@echo off",
w.MakeGuestDebugCmd("netcfg step 1"),
Expand Down Expand Up @@ -311,7 +315,7 @@ func (w *SWindowsRootFs) MakeGuestDebugCmd(content string) string {
}

func (w *SWindowsRootFs) prependGuestBootScript(content string) {
w.bootScripts = content + "\r\n" + w.bootScripts
w.bootScript = content + "\r\n" + w.bootScript
}

func (w *SWindowsRootFs) PrepareFsForTemplate(IDiskPartition) error {
Expand All @@ -329,10 +333,20 @@ func (w *SWindowsRootFs) CommitChanges(part IDiskPartition) error {
tool.CheckPath()
tool.EnableRdp()
tool.InstallGpeditStartScript(WIN_BOOT_SCRIPT_PATH)
if err := w.rootFs.Mkdir(path.Dir(BOOT_SCRIPT_PATH), syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR, true); err != nil {

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
}
return w.rootFs.FilePutContents(BOOT_SCRIPT_PATH, w.bootScripts, false, false)
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) (string, error) {
Expand All @@ -341,6 +355,7 @@ func (w *SWindowsRootFs) ChangeUserPasswd(part IDiskPartition, account, gid, pub
tool := winutils.NewWinRegTool(confPath)
tool.CheckPath()
success := false

if rinfo != nil && version.GE(rinfo.Version, "6.1") {
success = w.deployPublicKeyByGuest(account, password)
} else {
Expand Down Expand Up @@ -389,7 +404,7 @@ func (w *SWindowsRootFs) deployPublicKeyByGuest(uname, passwd string) bool {
` del %CHANGE_PASSWD_SCRIPT%`,
`)`,
}, "\r\n")
w.prependGuestBootScript(bootScript)
w.appendGuestBootScript("chgpwd", bootScript)
logPath := w.guestDebugLogPath
chksum := stringutils2.GetMD5Hash(passwd + logPath[(len(logPath)-10):])

Expand Down Expand Up @@ -458,7 +473,7 @@ func (w *SWindowsRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []*depl
` del %MOUNT_DISK_SCRIPT%`,
`)`,
}, "\r\n")
w.appendGuestBootScript(bootScript)
w.appendGuestBootScript("mountdisk", bootScript)
logPath := w.guestDebugLogPath
mountScript := strings.Join([]string{
w.MakeGuestDebugCmd("mount disk step 1"),
Expand Down
19 changes: 13 additions & 6 deletions pkg/util/procutils/procutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ type Command struct {
path string
args []string

cmd Cmd
cmd Cmd
remoteCmd bool
}

func NewCommand(name string, args ...string) *Command {
Expand All @@ -53,9 +54,10 @@ func NewCommandContext(ctx context.Context, name string, args ...string) *Comman
// exec remote command as far as possible
func NewRemoteCommandAsFarAsPossible(name string, args ...string) *Command {
return &Command{
path: name,
args: args,
cmd: execInstance.Command(name, args...),
path: name,
args: args,
cmd: execInstance.Command(name, args...),
remoteCmd: true,
}
}

Expand Down Expand Up @@ -90,6 +92,7 @@ func (c *Command) Output() ([]byte, error) {
}

func (c *Command) Start() error {
log.Debugf("Exec command: %s %v", c.path, c.args)
return c.cmd.Start()
}

Expand All @@ -107,6 +110,10 @@ func (c *Command) Kill() error {
return c.cmd.Kill()
}

func GetExitStatus(err error) (int, bool) {
return execInstance.GetExitStatus(err)
func (c *Command) GetExitStatus(err error) (int, bool) {
if c.remoteCmd {
return _remoteExecutor.GetExitStatus(err)
} else {
return localExecutor.GetExitStatus(err)
}
}
31 changes: 19 additions & 12 deletions pkg/util/winutils/winutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (w *SWinRegTool) samChange(user string, seq ...string) error {
return fmt.Errorf("Failed to change SAM password, not exit cleanly")
case err := <-done:
if err != nil {
if exitStatus, ok := procutils.GetExitStatus(err); ok {
if exitStatus, ok := proc.GetExitStatus(err); ok {
if exitStatus == 2 {
return nil
}
Expand Down Expand Up @@ -297,6 +297,7 @@ func (w *SWinRegTool) listRegistry(spath string, keySeg []string) ([]string, []s
keyPattern := regexp.MustCompile("^<(?P<key>[^>]+)>$")
valPattern := regexp.MustCompile(`^(?P<size>\d+)\s+(?P<type>REG\_\w+)\s+<(?P<key>[^>]+)>\s*`)
for _, line := range lines {
line = strings.TrimSpace(line)
m := regutils2.GetParams(keyPattern, line)
if len(m) > 0 {
keys = append(keys, m["key"])
Expand All @@ -310,7 +311,7 @@ func (w *SWinRegTool) listRegistry(spath string, keySeg []string) ([]string, []s
return keys, values, nil
}

func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode int) bool {
func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode []int) bool {
proc := procutils.NewCommand(GetChntpwPath(), "-e", spath)
stdin, err := proc.StdinPipe()
if err != nil {
Expand Down Expand Up @@ -339,6 +340,7 @@ func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode int) bool
}

for _, op := range ops {
log.Debugf("Input: %s", op)
io.WriteString(stdin, op+"\n")
}
io.WriteString(stdin, "q\n")
Expand All @@ -360,33 +362,38 @@ func (w *SWinRegTool) cmdRegistry(spath string, ops []string, retcode int) bool
done <- proc.Wait()
}()
select {
case <-time.After(time.Millisecond * 100):
proc.Kill()
case <-time.After(time.Millisecond * 1000):
log.Errorf("Cmd registry timeout")
if err := proc.Kill(); err != nil {
log.Errorf("kill cmd registry process failed %s", err)
}
case err := <-done:
if err != nil {
if exitStatus, ok := procutils.GetExitStatus(err); ok {
if exitStatus == retcode {
if exitStatus, ok := proc.GetExitStatus(err); ok {
if in, _ := utils.InArray(exitStatus, retcode); in {
return true
}
}
} else {
return retcode == 0
if in, _ := utils.InArray(0, retcode); in {
return true
}
}
}
return false
}

func (w *SWinRegTool) setRegistry(spath string, keySeg []string, value string) bool {
keyPath := strings.Join(keySeg, "\\")
return w.cmdRegistry(spath, []string{fmt.Sprintf("ed %s", keyPath), value}, 0)
return w.cmdRegistry(spath, []string{fmt.Sprintf("ed %s", keyPath), value}, []int{0})
}

func (w *SWinRegTool) mkdir(spath string, keySeg []string) bool {
return w.cmdRegistry(spath,
[]string{
fmt.Sprintf("cd %s", strings.Join(keySeg[:len(keySeg)-1], "\\")),
fmt.Sprintf("nk %s", keySeg[len(keySeg)-1]),
}, 2)
}, []int{0, 2})
}

func (w *SWinRegTool) keyExists(spath string, keySeg []string) bool {
Expand Down Expand Up @@ -460,7 +467,7 @@ func (w *SWinRegTool) newValue(spath string, keySeg []string, regtype, val strin
} else {
cmds = append(cmds, val)
}
return w.cmdRegistry(spath, cmds, 0)
return w.cmdRegistry(spath, cmds, []int{0})
}

func (w *SWinRegTool) GetRegistry(keyPath string) string {
Expand Down Expand Up @@ -687,16 +694,16 @@ func (w *SWinRegTool) installGpeditStartScript(script, scriptPath string) {
for _, kvt := range kvts {
w.SetRegistry(fmt.Sprintf(`%s\Startup\0\%s`, scriptPath, kvt[0]), kvt[1], kvt[2])
}

} else {
for w.KeyExists(scriptPath + (fmt.Sprintf(`\Startup\0\%d`, idx))) {
idx += 1
}
}

// `%WINDIR%\cloudboot.bat`
kvts := [][3]string{
{"Script", script, "REG_SZ"},
{"Parameters", "", "REG_SZ"},
{"Parameters", `%WINDIR%\cloudboot.bat`, "REG_SZ"},
{"ExecTime", "", "REG_QWORD"},
{"IsPowershell", "0", "REG_DWORD"},
}
Expand Down

0 comments on commit 9372a7b

Please sign in to comment.