mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
feat(region,host): qga deploy network config on attach nics (#22547)
This commit is contained in:
@@ -155,8 +155,9 @@ func init() {
|
||||
})
|
||||
|
||||
type ServerAttachNetworkOptions struct {
|
||||
SERVER string `help:"ID or Name of server"`
|
||||
NETDESC []string `help:"Network description"`
|
||||
SERVER string `help:"ID or Name of server"`
|
||||
DisableSyncConfig bool `help:"Disable sync config"`
|
||||
NETDESC []string `help:"Network description"`
|
||||
}
|
||||
R(&ServerAttachNetworkOptions{}, "server-attach-network", "Attach a server to a virtual network", func(s *mcclient.ClientSession, args *ServerAttachNetworkOptions) error {
|
||||
input := compute.AttachNetworkInput{}
|
||||
@@ -167,6 +168,7 @@ func init() {
|
||||
}
|
||||
input.Nets = append(input.Nets, conf)
|
||||
}
|
||||
input.DisableSyncConfig = &args.DisableSyncConfig
|
||||
params := jsonutils.Marshal(input)
|
||||
srv, err := modules.Servers.PerformAction(s, args.SERVER, "attachnetwork", params)
|
||||
if err != nil {
|
||||
|
||||
@@ -1175,7 +1175,7 @@ type ServerQgaGetNetworkInput struct {
|
||||
}
|
||||
|
||||
type ServerQgaTimeoutInput struct {
|
||||
// qga execute timeout millisecond
|
||||
// qga execute timeout second
|
||||
Timeout int
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ func (self *GuestSyncConfTask) StartRestartNetworkTask(ctx context.Context, gues
|
||||
// try use qga restart network
|
||||
err = func() error {
|
||||
host, _ := guest.GetHost()
|
||||
err = guest.GetDriver().QgaRequestGuestPing(ctx, self.GetTaskRequestHeader(), host, guest, false, &api.ServerQgaTimeoutInput{1000})
|
||||
err = guest.GetDriver().QgaRequestGuestPing(ctx, self.GetTaskRequestHeader(), host, guest, false, &api.ServerQgaTimeoutInput{1})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "qga guest-ping")
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestman/desc"
|
||||
deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
|
||||
"yunion.io/x/onecloud/pkg/hostman/monitor"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
@@ -107,7 +108,6 @@ func (m *SGuestManager) QgaSetNetwork(ctx context.Context, params interface{}) (
|
||||
Gateway: input.Gateway,
|
||||
}
|
||||
|
||||
//func (m *SGuestManager) QgaSetNetwork(netmod *monitor.NetworkModify, sid string, execTimeout int) (string, error) {
|
||||
guest, err := m.checkAndInitGuestQga(input.Sid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -144,3 +144,15 @@ func (m *SGuestManager) QgaGetOsInfo(sid string) (jsonutils.JSONObject, error) {
|
||||
}
|
||||
return jsonutils.Marshal(res), nil
|
||||
}
|
||||
|
||||
func (guest *SKVMGuestInstance) QgaAddNicsConfigure(addNics []*desc.SGuestNetwork) error {
|
||||
if guest.guestAgent == nil {
|
||||
if err := guest.InitQga(); err != nil {
|
||||
return errors.Wrap(err, "init qga")
|
||||
}
|
||||
}
|
||||
if err := guest.guestAgent.GuestPing(1); err != nil {
|
||||
return errors.Wrap(err, "Qga ping")
|
||||
}
|
||||
return guest.guestAgent.QgaDeployNics(deployapi.GuestNicsToServerNics(addNics))
|
||||
}
|
||||
|
||||
@@ -615,11 +615,34 @@ type SGuestNetworkSyncTask struct {
|
||||
addNics []*desc.SGuestNetwork
|
||||
errors []error
|
||||
|
||||
addNicMacs []string
|
||||
addNicConfs []*monitor.NetworkModify
|
||||
|
||||
callback func(...error)
|
||||
}
|
||||
|
||||
func (n *SGuestNetworkSyncTask) Start(callback func(...error)) {
|
||||
n.callback = callback
|
||||
if len(n.addNics) > 0 {
|
||||
nics := make([]*desc.SGuestNetwork, 0)
|
||||
nics = append(nics, n.guest.Desc.Nics...)
|
||||
nics = append(nics, n.addNics...)
|
||||
if err := n.guest.QgaAddNicsConfigure(nics); err != nil {
|
||||
log.Errorf("QgaAddNicsConfigure failed %s", err)
|
||||
} else {
|
||||
addNicMacs := make([]string, 0)
|
||||
addNicConfs := make([]*monitor.NetworkModify, 0)
|
||||
for i := range n.addNics {
|
||||
addNicMacs = append(addNicMacs, n.addNics[i].Mac)
|
||||
addNicConfs = append(addNicConfs, &monitor.NetworkModify{
|
||||
Ipmask: fmt.Sprintf("%s/%d", n.addNics[i].Ip, n.addNics[i].Masklen),
|
||||
Gateway: n.addNics[i].Gateway,
|
||||
})
|
||||
}
|
||||
n.addNicMacs = addNicMacs
|
||||
n.addNicConfs = addNicConfs
|
||||
}
|
||||
}
|
||||
n.syncNetworkConf()
|
||||
}
|
||||
|
||||
@@ -633,10 +656,59 @@ func (n *SGuestNetworkSyncTask) syncNetworkConf() {
|
||||
n.addNics = n.addNics[:len(n.addNics)-1]
|
||||
n.addNic(nic)
|
||||
} else {
|
||||
if len(n.addNicMacs) > 0 {
|
||||
// try restart added nics, wait for added nic ready
|
||||
time.Sleep(3 * time.Second)
|
||||
if err := n.qgaRestartAddedNics(); err != nil {
|
||||
log.Errorf("failed qgaRestartAddedNics")
|
||||
}
|
||||
}
|
||||
|
||||
n.callback(n.errors...)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *SGuestNetworkSyncTask) qgaRestartAddedNics() error {
|
||||
err := n.qgaGetAddedNicDevs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range n.addNicConfs {
|
||||
if n.addNicConfs[i].Device != "" {
|
||||
err = n.guest.guestAgent.QgaRestartNetwork(n.addNicConfs[i])
|
||||
if err != nil {
|
||||
log.Errorf("Failed QgaRestartNetwork %s %s", n.addNicConfs[i].Device, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *SGuestNetworkSyncTask) qgaGetAddedNicDevs() error {
|
||||
data, err := n.guest.guestAgent.QgaGetNetwork()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "QgaGetNetwork")
|
||||
}
|
||||
var parsedData []api.IfnameDetail
|
||||
ifnames, err := jsonutils.Parse(data)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "parse qga network output %s", data)
|
||||
}
|
||||
err = ifnames.Unmarshal(&parsedData)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unmarshal ifnames")
|
||||
}
|
||||
for i := range n.addNicMacs {
|
||||
for j := range parsedData {
|
||||
if n.addNicMacs[i] == parsedData[j].HardwareAddress {
|
||||
n.addNicConfs[i].Device = parsedData[j].Name
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *SGuestNetworkSyncTask) removeNic(nic *desc.SGuestNetwork) {
|
||||
callback := func(res string) {
|
||||
if len(res) > 0 && !strings.Contains(res, "not found") {
|
||||
@@ -794,7 +866,7 @@ func (n *SGuestNetworkSyncTask) onDeviceAdd(nic *desc.SGuestNetwork) {
|
||||
func NewGuestNetworkSyncTask(
|
||||
guest *SKVMGuestInstance, delNics, addNics []*desc.SGuestNetwork,
|
||||
) *SGuestNetworkSyncTask {
|
||||
return &SGuestNetworkSyncTask{guest, delNics, addNics, make([]error, 0), nil}
|
||||
return &SGuestNetworkSyncTask{guest, delNics, addNics, make([]error, 0), nil, nil, nil}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -598,6 +598,11 @@ if systemctl is-active --quiet network.service; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if command -v netplan &>/dev/null; then
|
||||
netplan try --timeout 0
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if command -v ip &> /dev/null; then
|
||||
ip link set $DEV down && ip link set $DEV up
|
||||
exit 0
|
||||
@@ -653,6 +658,38 @@ func (qga *QemuGuestAgent) QgaSetNetwork(qgaNetMod *monitor.NetworkModify, guest
|
||||
}
|
||||
}
|
||||
|
||||
func (qga *QemuGuestAgent) QgaRestartNetwork(qgaNetMod *monitor.NetworkModify) error {
|
||||
//Getting information about the operating system
|
||||
resOsInfo, err := qga.QgaGuestGetOsInfo()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get os info")
|
||||
}
|
||||
|
||||
//Judgement based on id, currently only windows and other systems are judged
|
||||
switch resOsInfo.Id {
|
||||
case "mswindows":
|
||||
return qga.QgaSetWindowsNetwork(qgaNetMod)
|
||||
default:
|
||||
return qga.QgaRestartLinuxNetwork(qgaNetMod)
|
||||
}
|
||||
}
|
||||
|
||||
func (qga *QemuGuestAgent) QgaDeployNics(guestNics []*types.SServerNic) error {
|
||||
//Getting information about the operating system
|
||||
resOsInfo, err := qga.QgaGuestGetOsInfo()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get os info")
|
||||
}
|
||||
|
||||
if resOsInfo.Id == "mswindows" {
|
||||
return nil
|
||||
}
|
||||
if err := qga.qgaDeployNetworkConfigure(guestNics); err != nil {
|
||||
return errors.Wrap(err, "qgaDeployNetworkConfigure")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
# @username: the user account whose password to change
|
||||
# @password: the new password entry string, base64 encoded
|
||||
|
||||
@@ -866,7 +866,7 @@ type ServerQgaCommand struct {
|
||||
ServerIdOptions
|
||||
|
||||
COMMAND string `help:"qga command"`
|
||||
Timeout int `help:"qga command execute timeout (ms)"`
|
||||
Timeout int `help:"qga command execute timeout (s)"`
|
||||
}
|
||||
|
||||
func (o *ServerQgaCommand) Params() (jsonutils.JSONObject, error) {
|
||||
@@ -876,7 +876,7 @@ func (o *ServerQgaCommand) Params() (jsonutils.JSONObject, error) {
|
||||
type ServerQgaPing struct {
|
||||
ServerIdOptions
|
||||
|
||||
Timeout int `help:"qga command execute timeout (ms)"`
|
||||
Timeout int `help:"qga command execute timeout (s)"`
|
||||
}
|
||||
|
||||
func (o *ServerQgaPing) Params() (jsonutils.JSONObject, error) {
|
||||
|
||||
Reference in New Issue
Block a user