feat(baremetal,region): support disable_image_cache for baremetalagent

This commit is contained in:
Zexi Li
2022-09-19 19:16:15 +08:00
parent fc563cc540
commit ecf61f6ea0
14 changed files with 189 additions and 79 deletions
+82 -61
View File
@@ -17,69 +17,90 @@ package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/cmd/climc/shell"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type BaremetalAgentListOptions struct {
options.BaseListOptions
}
R(&BaremetalAgentListOptions{}, "agent-list", "List all agent", func(s *mcclient.ClientSession, args *BaremetalAgentListOptions) error {
var params *jsonutils.JSONDict
{
var err error
params, err = args.BaseListOptions.Params()
if err != nil {
return err
}
}
result, err := modules.Baremetalagents.List(s, params)
if err != nil {
return err
}
printList(result, modules.Baremetalagents.GetColumns(s))
return nil
})
type BaremetalAgentOpsOperations struct {
ID string `help:"ID or name of agent"`
}
R(&BaremetalAgentOpsOperations{}, "agent-show", "Show details of an agent", func(s *mcclient.ClientSession, args *BaremetalAgentOpsOperations) error {
result, err := modules.Baremetalagents.Get(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&BaremetalAgentOpsOperations{}, "agent-enable", "Enable agent", func(s *mcclient.ClientSession, args *BaremetalAgentOpsOperations) error {
result, err := modules.Baremetalagents.PerformAction(s, args.ID, "enable", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&BaremetalAgentOpsOperations{}, "agent-disable", "Disable agent", func(s *mcclient.ClientSession, args *BaremetalAgentOpsOperations) error {
result, err := modules.Baremetalagents.PerformAction(s, args.ID, "disable", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&BaremetalAgentOpsOperations{}, "agent-delete", "Delete agent", func(s *mcclient.ClientSession, args *BaremetalAgentOpsOperations) error {
result, err := modules.Baremetalagents.Delete(s, args.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type AgentListOptions struct {
options.BaseListOptions
}
func (o AgentListOptions) Params() (jsonutils.JSONObject, error) {
return o.BaseListOptions.Params()
}
func (o AgentListOptions) Description() string {
return "List all agent"
}
type AgentOpsOperations struct {
ID string `help:"ID or name of agent"`
}
func (o AgentOpsOperations) GetId() string {
return o.ID
}
func (o AgentOpsOperations) Params() (jsonutils.JSONObject, error) {
return nil, nil
}
type AgentShowOpt struct {
AgentOpsOperations
}
func (o AgentShowOpt) Description() string {
return "Show details of an agent"
}
type AgentEnableOpt struct {
AgentOpsOperations
}
func (o AgentEnableOpt) Description() string {
return "Enable agent"
}
type AgentDisableOpt struct {
AgentOpsOperations
}
func (o AgentDisableOpt) Description() string {
return "Disable agent"
}
type AgentDeleteOpt struct {
AgentOpsOperations
}
func (o AgentDeleteOpt) Description() string {
return "Delete agent"
}
type AgentEnableImageCacheOpt struct {
AgentOpsOperations
}
func (o AgentEnableImageCacheOpt) Description() string {
return "Enable cache image of a agent"
}
type AgentDisableImageCacheOpt struct {
AgentOpsOperations
}
func (o AgentDisableImageCacheOpt) Description() string {
return "Disable cache image of a agent"
}
func init() {
cmd := shell.NewResourceCmd(&modules.Baremetalagents).WithKeyword("agent")
cmd.List(new(AgentListOptions))
cmd.Show(new(AgentShowOpt))
cmd.Perform("enable", new(AgentEnableOpt))
cmd.Perform("disable", new(AgentDisableOpt))
cmd.Perform("enable-image-cache", new(AgentEnableImageCacheOpt))
cmd.Perform("disable-image-cache", new(AgentDisableImageCacheOpt))
cmd.Delete(new(AgentDeleteOpt))
}
+4 -2
View File
@@ -41,11 +41,9 @@ var (
baremetalAgent *SBaremetalAgent
)
//
// BaremetalAgent has two types of address
// - AccessAddress/Address: this is the address controller to accesss the agent
// - ListenAddress: this is the address baremetal to access the agent
//
type SBaremetalAgent struct {
agent.SBaseAgent
@@ -84,6 +82,10 @@ func (agent *SBaremetalAgent) GetAdminSession() *mcclient.ClientSession {
return auth.GetAdminSession(context.TODO(), o.Options.Region)
}
func (agent *SBaremetalAgent) GetPublicAdminSession() *mcclient.ClientSession {
return auth.GetAdminSessionWithPublic(context.TODO(), o.Options.Region)
}
func (agent *SBaremetalAgent) GetListenIP() (net.IP, error) {
return agent.FindListenIP(o.Options.ListenAddress)
}
+24 -7
View File
@@ -41,6 +41,7 @@ import (
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
apiidenty "yunion.io/x/onecloud/pkg/apis/identity"
o "yunion.io/x/onecloud/pkg/baremetal/options"
"yunion.io/x/onecloud/pkg/baremetal/profiles"
"yunion.io/x/onecloud/pkg/baremetal/pxe"
@@ -101,6 +102,10 @@ func (m *SBaremetalManager) GetClientSession() *mcclient.ClientSession {
return m.Agent.GetAdminSession()
}
func (m *SBaremetalManager) GetPublicClientSession() *mcclient.ClientSession {
return m.Agent.GetPublicAdminSession()
}
func (m *SBaremetalManager) GetZoneId() string {
return m.Agent.Zone.Id
}
@@ -550,6 +555,10 @@ func (b *SBaremetalInstance) GetClientSession() *mcclient.ClientSession {
return b.manager.GetClientSession()
}
func (b *SBaremetalInstance) GetPublicClientSession() *mcclient.ClientSession {
return b.manager.GetPublicClientSession()
}
func (b *SBaremetalInstance) Keyword() string {
return "host"
}
@@ -1062,7 +1071,15 @@ func (b *SBaremetalInstance) getTftpFileUrl(filename string) string {
return fmt.Sprintf("http://%s/tftp/%s", endpoint, filename)
}
func (b *SBaremetalInstance) GetImageCacheUrl() string {
func (b *SBaremetalInstance) GetImageUrl(disableImageCache bool) string {
if disableImageCache {
url, err := b.GetPublicClientSession().GetServiceURL(apis.SERVICE_TYPE_IMAGE, apiidenty.EndpointInterfacePublic, "")
if err != nil {
log.Errorf("Get image public url: %v", err)
return ""
}
return url
}
serverIP, err := b.manager.Agent.GetDHCPServerIP()
if err != nil {
log.Errorf("Get http file server: %v", err)
@@ -2665,10 +2682,10 @@ func replaceHostAddr(urlStr string, addr string) string {
return urlComp.String()
}
func (s *SBaremetalServer) doCreateRoot(term *ssh.Client, devName string) error {
func (s *SBaremetalServer) doCreateRoot(term *ssh.Client, devName string, disableImageCache bool) error {
session := s.baremetal.GetClientSession()
token := session.GetToken().GetTokenString()
urlStr := s.baremetal.GetImageCacheUrl()
urlStr := s.baremetal.GetImageUrl(disableImageCache)
imageId := s.GetRootTemplateId()
cmd := fmt.Sprintf("/lib/mos/rootcreate.sh %s %s %s %s", token, urlStr, imageId, devName)
log.Infof("rootcreate cmd: %q", cmd)
@@ -2678,7 +2695,7 @@ func (s *SBaremetalServer) doCreateRoot(term *ssh.Client, devName string) error
return nil
}
func (s *SBaremetalServer) DoPartitionDisk(tool *disktool.SSHPartitionTool, term *ssh.Client) ([]*disktool.Partition, error) {
func (s *SBaremetalServer) DoPartitionDisk(tool *disktool.SSHPartitionTool, term *ssh.Client, disableImageCache bool) ([]*disktool.Partition, error) {
raid, nonRaid, pcie, err := detect_storages.DetectStorageInfo(term, false)
if err != nil {
return nil, err
@@ -2711,7 +2728,7 @@ func (s *SBaremetalServer) DoPartitionDisk(tool *disktool.SSHPartitionTool, term
if len(rootImageId) > 0 {
rootDisk := disks[0]
rootSize, _ := rootDisk.Int("size")
err = s.doCreateRoot(term, tool.GetRootDisk().GetDevName())
err = s.doCreateRoot(term, tool.GetRootDisk().GetDevName(), disableImageCache)
if err != nil {
return nil, errors.Wrap(err, "Failed to create root")
}
@@ -2753,7 +2770,7 @@ func (s *SBaremetalServer) DoPartitionDisk(tool *disktool.SSHPartitionTool, term
return tool.GetPartitions(), nil
}
func (s *SBaremetalServer) DoRebuildRootDisk(tool *disktool.SSHPartitionTool, term *ssh.Client) ([]*disktool.Partition, error) {
func (s *SBaremetalServer) DoRebuildRootDisk(tool *disktool.SSHPartitionTool, term *ssh.Client, disableImageCache bool) ([]*disktool.Partition, error) {
// raid, nonRaid, pcie, err := detect_storages.DetectStorageInfo(term, false)
// if err != nil {
// return nil, err
@@ -2784,7 +2801,7 @@ func (s *SBaremetalServer) DoRebuildRootDisk(tool *disktool.SSHPartitionTool, te
rootDisk := disks[0]
rootSize, _ := rootDisk.Int("size")
rd := tool.GetRootDisk()
err := s.doCreateRoot(term, rd.GetDevName())
err := s.doCreateRoot(term, rd.GetDevName(), disableImageCache)
if err != nil {
return nil, fmt.Errorf("Failed to create root: %v", err)
}
+4
View File
@@ -69,6 +69,10 @@ 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")
+1 -1
View File
@@ -97,7 +97,7 @@ func (self *SBaremetalCdromTask) DoInsertISO(ctx context.Context, args interface
if !fileutils2.Exists(localImagePath) {
return errors.Error("image not cached")
}
imageBaseUrl := self.Baremetal.GetImageCacheUrl()
imageBaseUrl := self.Baremetal.GetImageUrl(true)
if len(imageBaseUrl) == 0 {
return errors.Error("empty image base url")
}
+1 -1
View File
@@ -61,7 +61,7 @@ func (self *SBaremetalServerCreateTask) DoDeploys(term *ssh.Client) (jsonutils.J
return nil, self.onError(term, err)
}
time.Sleep(2 * time.Second)
parts, err := self.Baremetal.GetServer().DoPartitionDisk(tool, term)
parts, err := self.Baremetal.GetServer().DoPartitionDisk(tool, term, self.IsDisableImageCache())
if err != nil {
return nil, self.onError(term, err)
}
+1 -1
View File
@@ -62,7 +62,7 @@ type IBaremetal interface {
GenerateBootISO() error
SendNicInfo(nic *types.SNicDevInfo, idx int, nicType string, reset bool, ipAddr string, reserve bool) error
DoNTPConfig() error
GetImageCacheUrl() string
GetImageUrl(needImageCache bool) string
RemoveServer()
InitializeServer(session *mcclient.ClientSession, name string) error
+1 -1
View File
@@ -55,7 +55,7 @@ func (self *SBaremetalServerRebuildTask) DoDeploys(term *ssh.Client) (jsonutils.
if err != nil {
return nil, errors.Wrap(err, "NewConfigedSSHPartitionTool")
}
parts, err := self.Baremetal.GetServer().DoRebuildRootDisk(tool, term)
parts, err := self.Baremetal.GetServer().DoRebuildRootDisk(tool, term, self.IsDisableImageCache())
if err != nil {
return nil, fmt.Errorf("Rebuild root disk: %v", err)
}
+2 -2
View File
@@ -31,9 +31,9 @@ type IBaremetalServer interface {
DoDiskUnconfig(term *ssh.Client) error
DoDiskConfig(term *ssh.Client) (*disktool.SSHPartitionTool, error)
DoEraseDisk(term *ssh.Client) error
DoPartitionDisk(tool *disktool.SSHPartitionTool, term *ssh.Client) ([]*disktool.Partition, error)
DoPartitionDisk(tool *disktool.SSHPartitionTool, term *ssh.Client, disableImageCache bool) ([]*disktool.Partition, error)
NewConfigedSSHPartitionTool(term *ssh.Client) (*disktool.SSHPartitionTool, error)
DoRebuildRootDisk(tool *disktool.SSHPartitionTool, term *ssh.Client) ([]*disktool.Partition, error)
DoRebuildRootDisk(tool *disktool.SSHPartitionTool, term *ssh.Client, disableImageCache bool) ([]*disktool.Partition, error)
SyncPartitionSize(term *ssh.Client, parts []*disktool.Partition) ([]jsonutils.JSONObject, error)
DoDeploy(tool *disktool.SSHPartitionTool, term *ssh.Client, data jsonutils.JSONObject, isInit bool) (jsonutils.JSONObject, error)
SaveDesc(desc jsonutils.JSONObject) error
+2
View File
@@ -18,7 +18,9 @@ import "fmt"
func GetYunionOSConfig(sleepTime int, httpSite, kernel string, kernelArgs string, initrd string) string {
kernel = fmt.Sprintf("(http,${http_site})/tftp/%s", kernel)
// kernel = fmt.Sprintf("(tftp,10.127.100.2)/%s", kernel)
initrd = fmt.Sprintf("(http,${http_site})/tftp/%s", initrd)
// initrd = fmt.Sprintf("(tftp,10.127.100.2)/%s", initrd)
return fmt.Sprintf(`
set timeout=%d
set http_site=%s
+19
View File
@@ -500,6 +500,18 @@ func (self *SBaremetalGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Con
return nil
}
func (self *SBaremetalGuestDriver) IsDisableImageCache(gst *models.SGuest) (bool, error) {
host, err := gst.GetHost()
if err != nil {
return false, errors.Wrapf(err, "Get guest %s(%s) host", gst.GetName(), gst.GetId())
}
agent := host.GetAgent(api.AgentTypeBaremetal)
if agent == nil {
return false, errors.Wrapf(errors.ErrNotFound, "get host %s(%s) agent", host.GetName(), host.GetId())
}
return agent.DisableImageCache, nil
}
func (self *SBaremetalGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
if err != nil {
@@ -515,6 +527,13 @@ func (self *SBaremetalGuestDriver) RequestDeployGuestOnHost(ctx context.Context,
} else if val == "deploy" && jsonutils.QueryBoolean(task.GetParams(), "restart", false) {
config.Set("on_finish", jsonutils.NewString("shutdown"))
}
disableCache, err := self.IsDisableImageCache(guest)
if err != nil {
return errors.Wrap(err, "check IsDisableImageCache")
}
config.Set("disable_image_cache", jsonutils.NewBool(disableCache))
url := fmt.Sprintf("/baremetals/%s/servers/%s/%s", host.Id, guest.Id, val)
headers := task.GetTaskRequestHeader()
_, err = host.BaremetalSyncRequest(ctx, "POST", url, headers, config)
+21 -1
View File
@@ -19,6 +19,7 @@ import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
@@ -43,12 +44,31 @@ func (self *SBaremetalHostDriver) GetHypervisor() string {
return api.HYPERVISOR_BAREMETAL
}
func (self *SBaremetalHostDriver) IsDisableImageCache(host *models.SHost) (bool, error) {
agent := host.GetAgent(api.AgentTypeBaremetal)
if agent == nil {
return false, errors.Wrapf(errors.ErrNotFound, "get host %s(%s) agent", host.GetName(), host.GetId())
}
return agent.DisableImageCache, nil
}
func (self *SBaremetalHostDriver) CheckAndSetCacheImage(ctx context.Context, host *models.SHost, storageCache *models.SStoragecache, task taskman.ITask) error {
input := api.CacheImageInput{}
task.GetParams().Unmarshal(&input)
_, err := models.CachedimageManager.FetchById(input.ImageId)
if err != nil {
return err
return errors.Wrapf(err, "fetch cachedimage by image_id %s", input.ImageId)
}
disableCache, err := self.IsDisableImageCache(host)
if err != nil {
return errors.Wrapf(err, "check disable image cache by host %s(%s)", host.GetName(), host.GetId())
}
// iso must be cached to use
if disableCache && input.Format != "iso" {
task.ScheduleRun(nil)
return nil
}
url := "/disks/image_cache"
+22 -1
View File
@@ -50,7 +50,8 @@ type SBaremetalagent struct {
Version string `width:"64" charset:"ascii" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(64, charset='ascii'))
StoragecacheId string `width:"36" charset:"ascii" nullable:"true" list:"admin" get:"admin" update:"admin" create:"admin_optional"`
StoragecacheId string `width:"36" charset:"ascii" nullable:"true" list:"admin" get:"admin" update:"admin" create:"admin_optional"`
DisableImageCache bool `default:"false" list:"admin" create:"admin_optional" update:"admin"`
}
var BaremetalagentManager *SBaremetalagentManager
@@ -154,6 +155,26 @@ func (self *SBaremetalagent) PerformDisable(ctx context.Context, userCred mcclie
return nil, nil
}
func (self *SBaremetalagent) PerformEnableImageCache(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if self.DisableImageCache {
db.Update(self, func() error {
self.DisableImageCache = false
return nil
})
}
return nil, nil
}
func (self *SBaremetalagent) PerformDisableImageCache(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if !self.DisableImageCache {
db.Update(self, func() error {
self.DisableImageCache = true
return nil
})
}
return nil, nil
}
func (self *SBaremetalagent) PerformOnline(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if self.Status == api.BAREMETAL_AGENT_OFFLINE {
db.Update(self, func() error {
+5 -1
View File
@@ -5392,8 +5392,12 @@ func (self *SHost) EsxiRequest(ctx context.Context, method httputils.THttpMethod
return self.doAgentRequest(api.AgentTypeEsxi, ctx, method, url, headers, body)
}
func (self *SHost) GetAgent(at api.TAgentType) *SBaremetalagent {
return BaremetalagentManager.GetAgent(at, self.ZoneId)
}
func (self *SHost) isAgentReady(agentType api.TAgentType) bool {
agent := BaremetalagentManager.GetAgent(agentType, self.ZoneId)
agent := self.GetAgent(agentType)
if agent == nil {
log.Errorf("%s ready: false", agentType)
return false