Files
cloudpods/pkg/baremetal/tasks/basedeploy.go

160 lines
4.3 KiB
Go

// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/baremetal/utils/uefi"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/ssh"
)
type IServerBaseDeployTask interface {
IPXEBootTask
RemoveEFIOSEntry() bool
DoDeploys(term *ssh.Client) (jsonutils.JSONObject, error)
PostDeploys(term *ssh.Client) error
}
type SBaremetalServerBaseDeployTask struct {
SBaremetalPXEBootTaskBase
needPXEBoot bool
}
func newBaremetalServerBaseDeployTask(
userCred mcclient.TokenCredential,
baremetal IBaremetal,
taskId string,
data jsonutils.JSONObject,
) SBaremetalServerBaseDeployTask {
task := SBaremetalServerBaseDeployTask{
SBaremetalPXEBootTaskBase: newBaremetalPXEBootTaskBase(userCred, baremetal, taskId, data),
needPXEBoot: true,
}
// any inheritance must call:
// task.SetStage(task.InitPXEBootTask)
return task
}
func (self *SBaremetalServerBaseDeployTask) IServerBaseDeployTask() IServerBaseDeployTask {
return self.GetVirtualObject().(IServerBaseDeployTask)
}
func (self *SBaremetalServerBaseDeployTask) GetName() string {
return "BaremetalServerBaseDeployTask"
}
func (self *SBaremetalServerBaseDeployTask) NeedPXEBoot() bool {
return self.needPXEBoot
}
func (self *SBaremetalServerBaseDeployTask) IsDisableImageCache() bool {
return jsonutils.QueryBoolean(self.data, "disable_image_cache", false)
}
func (self *SBaremetalServerBaseDeployTask) GetFinishAction() string {
if self.data != nil {
action, _ := self.data.GetString("on_finish")
return action
}
return ""
}
func (self *SBaremetalServerBaseDeployTask) RemoveEFIOSEntry() bool {
return false
}
func (self *SBaremetalServerBaseDeployTask) DoDeploys(_ *ssh.Client) (jsonutils.JSONObject, error) {
return nil, nil
}
func (self *SBaremetalServerBaseDeployTask) PostDeploys(_ *ssh.Client) error {
return nil
}
func (self *SBaremetalServerBaseDeployTask) OnPXEBoot(ctx context.Context, term *ssh.Client, args interface{}) error {
log.Infof("%s called on stage pxeboot, args: %v", self.GetName(), args)
if self.IServerBaseDeployTask().RemoveEFIOSEntry() {
if err := uefi.RemoteTryRemoveOSBootEntry(term); err != nil {
return errors.Wrap(err, "Remote uefi boot entry")
}
}
result, err := self.IServerBaseDeployTask().DoDeploys(term)
if err != nil {
return errors.Wrap(err, "Do deploy")
}
if err := AdjustUEFIBootOrder(term, self.Baremetal); err != nil {
return errors.Wrap(err, "Adjust UEFI boot order")
}
_, err = term.Run(
"/bin/sync",
"/sbin/sysctl -w vm.drop_caches=3",
)
if err != nil {
return errors.Wrap(err, "Sync disk")
}
if err := self.IServerBaseDeployTask().PostDeploys(term); err != nil {
return errors.Wrap(err, "post deploy")
}
onFinishAction := self.GetFinishAction()
if utils.IsInStringArray(onFinishAction, []string{"restart", "shutdown"}) {
if self.Baremetal.HasBMC() {
if err := self.EnsurePowerShutdown(false); err != nil {
return errors.Wrap(err, "Ensure power off")
}
if onFinishAction == "restart" {
if err := self.EnsurePowerUp(); err != nil {
return errors.Wrap(err, "Ensure power up")
}
}
self.Baremetal.AutoSyncAllStatus()
} else {
if onFinishAction == "shutdown" {
log.Infof("None BMC baremetal can't shutdown when deploying")
/*
* if err := self.Baremetal.SSHShutdown(); err != nil {
* return errors.Wrap(err, "Try ssh shutdown")
* }
*/
} else {
// do restart
// hack: ssh reboot to disk
self.needPXEBoot = false
if err := self.EnsureSSHReboot(); err != nil {
return errors.Wrap(err, "Try ssh reboot")
}
}
}
self.Baremetal.SyncAllStatus(types.POWER_STATUS_ON)
}
SetTaskComplete(self, result)
return nil
}