diff --git a/pkg/hostman/guestfs/fsdriver/base.go b/pkg/hostman/guestfs/fsdriver/base.go index 51c74f9273..5897a9404b 100644 --- a/pkg/hostman/guestfs/fsdriver/base.go +++ b/pkg/hostman/guestfs/fsdriver/base.go @@ -120,41 +120,51 @@ func (l *sGuestRootFsDriver) IsResizeFsPartitionSupport() bool { return true } +const ( + modeAuthorizedKeysRWX = syscall.S_IRUSR | syscall.S_IWUSR | syscall.S_IXUSR + modeAuthorizedKeysRW = syscall.S_IRUSR | syscall.S_IWUSR +) + +func deployAuthorizedKeys(rootFs IDiskPartition, authFile string, uid, gid int, pubkeys *deployapi.SSHKeys, replace bool) error { + var oldKeys = "" + if !replace { + bOldKeys, _ := rootFs.FileGetContents(authFile, false) + oldKeys = string(bOldKeys) + } + newKeys := MergeAuthorizedKeys(oldKeys, pubkeys) + if err := rootFs.FilePutContents(authFile, newKeys, false, false); err != nil { + return fmt.Errorf("Put keys to %s: %v", authFile, err) + } + if err := rootFs.Chown(authFile, uid, gid, false); err != nil { + return fmt.Errorf("Chown %s to uid: %d, gid: %d: %v", authFile, uid, gid, err) + } + if err := rootFs.Chmod(authFile, uint32(modeAuthorizedKeysRW), false); err != nil { + return fmt.Errorf("Chmod %s to %d error: %v", authFile, uint32(modeAuthorizedKeysRW), err) + } + return nil +} + func DeployAuthorizedKeys(rootFs IDiskPartition, usrDir string, pubkeys *deployapi.SSHKeys, replace bool) error { usrStat := rootFs.Stat(usrDir, false) if usrStat != nil { sshDir := path.Join(usrDir, ".ssh") authFile := path.Join(sshDir, "authorized_keys") - modeRwxOwner := syscall.S_IRUSR | syscall.S_IWUSR | syscall.S_IXUSR - modeRwOwner := syscall.S_IRUSR | syscall.S_IWUSR fStat, _ := usrStat.Sys().(*syscall.Stat_t) + uid := int(fStat.Uid) + gid := int(fStat.Gid) if !rootFs.Exists(sshDir, false) { - err := rootFs.Mkdir(sshDir, modeRwxOwner, false) + err := rootFs.Mkdir(sshDir, modeAuthorizedKeysRWX, false) if err != nil { log.Errorln(err) return err } - err = rootFs.Chown(sshDir, int(fStat.Uid), int(fStat.Gid), false) + err = rootFs.Chown(sshDir, uid, gid, false) if err != nil { log.Errorln(err) return err } } - var oldKeys = "" - if !replace { - bOldKeys, _ := rootFs.FileGetContents(authFile, false) - oldKeys = string(bOldKeys) - } - newKeys := MergeAuthorizedKeys(oldKeys, pubkeys) - if err := rootFs.FilePutContents(authFile, newKeys, false, false); err != nil { - return fmt.Errorf("Put keys to %s: %v", authFile, err) - } - if err := rootFs.Chown(authFile, int(fStat.Uid), int(fStat.Gid), false); err != nil { - return fmt.Errorf("Chown %s to uid: %d, gid: %d: %v", authFile, fStat.Uid, fStat.Gid, err) - } - if err := rootFs.Chmod(authFile, uint32(modeRwOwner), false); err != nil { - return fmt.Errorf("Chmod %s to %d error: %v", authFile, uint32(modeRwOwner), err) - } + return deployAuthorizedKeys(rootFs, authFile, uid, gid, pubkeys, replace) } return nil } diff --git a/pkg/hostman/guestfs/fsdriver/linux.go b/pkg/hostman/guestfs/fsdriver/linux.go index 39799fe968..a417ea903e 100644 --- a/pkg/hostman/guestfs/fsdriver/linux.go +++ b/pkg/hostman/guestfs/fsdriver/linux.go @@ -1362,7 +1362,7 @@ func NewOpenWrtRootFs(part IDiskPartition) IRootFsDriver { } func (d *SOpenWrtRootFs) GetName() string { - return "OpenWRT" + return "OpenWrt" } func (d *SOpenWrtRootFs) String() string { @@ -1372,8 +1372,48 @@ func (d *SOpenWrtRootFs) String() string { func (d *SOpenWrtRootFs) RootSignatures() []string { return []string{"/bin", "/etc/", "/lib", "/sbin", "/overlay", "/etc/openwrt_release", "/etc/openwrt_version"} } +func (d *SOpenWrtRootFs) featureBoardConfig(rootFs IDiskPartition) bool { + if rootFs.Exists("/etc/board.d", false) { + return true + } + return false +} + +func (d *SOpenWrtRootFs) putBoardConfig(rootFs IDiskPartition, f, c string) error { + if err := rootFs.FilePutContents(f, c, false, false); err != nil { + return err + } + if err := rootFs.Chmod(f, 0755, false); err != nil { + return err + } + return nil +} + +func (d *SOpenWrtRootFs) DeployPublicKey(rootFs IDiskPartition, selUsr string, pubkeys *deployapi.SSHKeys) error { + if selUsr == "root" && rootFs.Exists("/etc/dropbear", false) { + var ( + authFile = "/etc/dropbear/authorized_keys" + uid = 0 + gid = 0 + replace = false + ) + return deployAuthorizedKeys(rootFs, authFile, uid, gid, pubkeys, replace) + } + return d.sLinuxRootFs.DeployPublicKey(rootFs, selUsr, pubkeys) +} func (d *SOpenWrtRootFs) DeployHostname(rootFs IDiskPartition, hn, domain string) error { + if d.featureBoardConfig(rootFs) { + f := "/etc/board.d/00-00-onecloud-hostname" + c := fmt.Sprintf(`. /lib/functions/uci-defaults.sh +board_config_update +ucidef_set_hostname '%s' +board_config_flush +exit 0 +`, hn) + return d.putBoardConfig(rootFs, f, c) + } + spath := "/etc/config/system" if !rootFs.Exists(spath, false) { return nil @@ -1388,10 +1428,55 @@ func (d *SOpenWrtRootFs) DeployHostname(rootFs IDiskPartition, hn, domain string return rootFs.FilePutContents(spath, cont, false, false) } +func (d *SOpenWrtRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*types.SServerNic) error { + if d.featureBoardConfig(rootFs) { + macs := "" + for _, nic := range nics { + macs = "," + nic.Mac + } + f := "/etc/board.d/00-01-onecloud-network" + c := fmt.Sprintf(`. /lib/functions/uci-defaults.sh +[ -d /sys/class/net ] || exit 0 + +board_config_update +macs='%s' +i=0 + +oc_set_ifname() { + local net="$1"; shift + local ifname="$1"; shift + + if type ucidef_set_interface &>/dev/null; then + ucidef_set_interface "$net" ifname "$ifname" protocol dhcp + elif type ucidef_set_interface_raw &>/dev/null; then + ucidef_set_interface_raw "$net" "$ifname" "dhcp" + else + echo "no ucidef function to do network ifname config" >&2 + exit 0 + fi +} + +for ifname in $(ls /sys/class/net/); do + p="/sys/class/net/$ifname" + mac="$(cat "$p/address")" + if [ "${macs#*,$mac}" != "$macs" ]; then + oc_set_ifname "lan$i" "$ifname" + i="$(($i + 1))" + fi +done + +board_config_flush +exit 0 +`, macs) + return d.putBoardConfig(rootFs, f, c) + } + return nil +} + func (d *SOpenWrtRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { ver, _ := rootFs.FileGetContents("/etc/openwrt_version", false) return &deployapi.ReleaseInfo{ - Distro: "OpenWRT", + Distro: "OpenWrt", Version: string(ver), Arch: d.GetArch(rootFs), } diff --git a/pkg/hostman/guestman/qemu-kvmhelper.go b/pkg/hostman/guestman/qemu-kvmhelper.go index d39653ac25..7604b5251c 100644 --- a/pkg/hostman/guestman/qemu-kvmhelper.go +++ b/pkg/hostman/guestman/qemu-kvmhelper.go @@ -41,7 +41,7 @@ const ( OS_NAME_ANDROID = "Android" OS_NAME_VMWARE = "VMWare" OS_NAME_CIRROS = "Cirros" - OS_NAME_OPENWRT = "OpenWRT" + OS_NAME_OPENWRT = "OpenWrt" MODE_READLINE = "readline" MODE_CONTROL = "control"