mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 14:19:49 +08:00
kvm server create
This commit is contained in:
+18
-9
@@ -4,8 +4,9 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/c-bata/go-prompt"
|
||||
prompt "github.com/c-bata/go-prompt"
|
||||
"github.com/yunionio/log"
|
||||
"github.com/yunionio/pkg/util/version"
|
||||
"github.com/yunionio/structarg"
|
||||
@@ -34,6 +35,9 @@ type BaseOptions struct {
|
||||
SUBCOMMAND string `help:"climc subcommand" subcommand:"true"`
|
||||
}
|
||||
|
||||
var CacheToken mcclient.TokenCredential
|
||||
var CacheTime time.Time
|
||||
|
||||
func getSubcommandsParser() (*structarg.ArgumentParser, error) {
|
||||
parse, e := structarg.NewArgumentParser(&BaseOptions{},
|
||||
"climc",
|
||||
@@ -116,18 +120,23 @@ func newClientSession(options *BaseOptions) (*mcclient.ClientSession, error) {
|
||||
options.Timeout,
|
||||
options.Debug,
|
||||
options.Secure)
|
||||
token, err := client.Authenticate(options.OsUsername,
|
||||
options.OsPassword,
|
||||
options.OsDomainName,
|
||||
options.OsProjectName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
if CacheToken == nil || {
|
||||
token, err := client.Authenticate(options.OsUsername,
|
||||
options.OsPassword,
|
||||
options.OsDomainName,
|
||||
options.OsProjectName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
CacheToken = token
|
||||
CacheTime = time.Now()
|
||||
}
|
||||
|
||||
session := client.NewSession(options.OsRegionName,
|
||||
options.OsZoneName,
|
||||
options.OsEndpointType,
|
||||
token,
|
||||
CacheToken,
|
||||
options.ApiVersion)
|
||||
return session, nil
|
||||
}
|
||||
@@ -144,7 +153,7 @@ func main() {
|
||||
fmt.Print(parser.HelpString())
|
||||
} else if options.Version {
|
||||
fmt.Printf("Yunion API client version:\n %s\n", version.GetJsonString())
|
||||
} else if len(os.Args) <= 1 {
|
||||
} else if len(os.Args) <= 1 || (options.ApiVersion == "v2" && len(os.Args) <= 3) {
|
||||
session, e := newClientSession(options)
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
|
||||
@@ -54,13 +54,13 @@ func (self *SBaseGuestDriver) StartGuestCreateTask(guest *models.SGuest, ctx con
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) OnGuestCreateTaskComplete(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
//if jsonutils.QueryBoolean(task.GetParams(), "auto_start", false) {
|
||||
// task.SetStage("on_auto_start_guest", nil)
|
||||
// return guest.StartGueststartTask(ctx, task.GetUserCred(), nil, task.GetTaskId())
|
||||
//} else {
|
||||
task.SetStage("on_sync_status_complete", nil)
|
||||
return guest.StartSyncstatus(ctx, task.GetUserCred(), task.GetTaskId())
|
||||
//}
|
||||
if jsonutils.QueryBoolean(task.GetParams(), "auto_start", false) {
|
||||
task.SetStage("on_auto_start_guest", nil)
|
||||
return guest.StartGueststartTask(ctx, task.GetUserCred(), nil, task.GetTaskId())
|
||||
} else {
|
||||
task.SetStage("on_sync_status_complete", nil)
|
||||
return guest.StartSyncstatus(ctx, task.GetUserCred(), task.GetTaskId())
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) StartDeleteGuestTask(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, params *jsonutils.JSONDict, parentTaskId string) error {
|
||||
@@ -113,3 +113,7 @@ func (self *SBaseGuestDriver) DoGuestCreateDisksTask(ctx context.Context, guest
|
||||
func (self *SBaseGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, vcpuCount, vmemSize int64) error {
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
@@ -3,11 +3,8 @@ package guestdrivers
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
"github.com/yunionio/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type SESXiGuestDriver struct {
|
||||
@@ -44,3 +41,8 @@ func (self *SESXiGuestDriver) RequestDeleteDetachedDisk(ctx context.Context, dis
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SESXiGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -243,3 +243,11 @@ func (self *SKVMGuestDriver) RqeuestSuspendOnHost(ctx context.Context, guest *mo
|
||||
_, _, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, nil, false)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestGuestCreateAllDisks(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
return guest.StartGuestCreateDiskTask(ctx, task.GetUserCred(), task.GetParams(), task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
return guest.StartSyncstatus(ctx, task.GetUserCred(), task.GetTaskId())
|
||||
}
|
||||
|
||||
@@ -607,6 +607,11 @@ func parseDiskInfo(ctx context.Context, userCred mcclient.TokenCredential, info
|
||||
}
|
||||
return &diskConfig, nil
|
||||
}
|
||||
|
||||
// default backend
|
||||
diskConfig.Backend = STORAGE_LOCAL
|
||||
// diskConfig.Medium = DISK_TYPE_HYBRID
|
||||
|
||||
diskStr, err := info.GetString()
|
||||
if err != nil {
|
||||
log.Errorf("invalid diskinfo format %s", err)
|
||||
|
||||
@@ -85,6 +85,8 @@ type IGuestDriver interface {
|
||||
AllowReconfigGuest() bool
|
||||
DoGuestCreateDisksTask(ctx context.Context, guest *SGuest, task taskman.ITask) error
|
||||
RequestChangeVmConfig(ctx context.Context, guest *SGuest, task taskman.ITask, vcpuCount, vmemSize int64) error
|
||||
|
||||
RequestGuestHotAddIso(ctx context.Context, guest *SGuest, path string, task taskman.ITask) error
|
||||
}
|
||||
|
||||
var guestDrivers map[string]IGuestDriver
|
||||
|
||||
@@ -521,6 +521,7 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m
|
||||
hypervisor = HYPERVISOR_BAREMETAL
|
||||
}
|
||||
|
||||
// base validate_create_data
|
||||
if data.Contains("prefer_baremetal") || data.Contains("prefer_host") {
|
||||
if !userCred.IsSystemAdmin() {
|
||||
return nil, httperrors.NewNotSufficientPrivilegeError("Only system admin can specify preferred host")
|
||||
@@ -558,7 +559,6 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
schedtags := make(map[string]string)
|
||||
if data.Contains("aggregate_strategy") {
|
||||
@@ -613,12 +613,16 @@ func (manager *SGuestManager) ValidateCreateData(ctx context.Context, userCred m
|
||||
}
|
||||
}
|
||||
|
||||
// default hypervisor
|
||||
if len(hypervisor) == 0 {
|
||||
hypervisor = HYPERVISOR_KVM
|
||||
}
|
||||
|
||||
if !utils.IsInStringArray(hypervisor, HYPERVISORS) {
|
||||
return nil, httperrors.NewInputParameterError("Hypervisor %s not supported", hypervisor)
|
||||
}
|
||||
|
||||
data.Add(jsonutils.NewString(hypervisor), "hypervisor")
|
||||
|
||||
for idx := 1; data.Contains(fmt.Sprintf("disk.%d", idx)); idx += 1 {
|
||||
diskJson, err := data.Get(fmt.Sprintf("disk.%d", idx))
|
||||
if err != nil {
|
||||
@@ -789,13 +793,27 @@ func getGuestResourceRequirements(ctx context.Context, userCred mcclient.TokenCr
|
||||
|
||||
func (guest *SGuest) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
guest.SVirtualResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data)
|
||||
|
||||
tags := []string{"cpu_bound", "io_bound", "io_hardlimit"}
|
||||
appTags := make([]string, 0)
|
||||
for _, tag := range tags {
|
||||
if data.Contains(tag) {
|
||||
appTags = append(appTags, tag)
|
||||
}
|
||||
}
|
||||
guest.setApptags(ctx, appTags, userCred)
|
||||
osProfileJson, _ := data.Get("__os_profile__")
|
||||
if osProfileJson != nil {
|
||||
guest.setOSProfile(ctx, userCred, osProfileJson)
|
||||
}
|
||||
}
|
||||
|
||||
func (guest *SGuest) setApptags(ctx context.Context, appTags []string, userCred mcclient.TokenCredential) {
|
||||
err := guest.SetMetadata(ctx, "app_tags", strings.Join(appTags, ","), userCred)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SGuestManager) OnCreateComplete(ctx context.Context, items []db.IModel, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
pendingUsage := getGuestResourceRequirements(ctx, userCred, data, len(items))
|
||||
|
||||
@@ -2002,11 +2020,26 @@ func (self *SGuest) insertIso(imageId string) bool {
|
||||
return cdrom.insertIso(imageId)
|
||||
}
|
||||
|
||||
func (self *SGuest) insertIsoSucc(imageId string, path string, size int, name string) bool {
|
||||
func (self *SGuest) InsertIsoSucc(imageId string, path string, size int, name string) bool {
|
||||
cdrom := self.getCdrom()
|
||||
return cdrom.insertIsoSucc(imageId, path, size, name)
|
||||
}
|
||||
|
||||
func (self *SGuest) GetDetailsIso(userCred mcclient.TokenCredential) jsonutils.JSONObject {
|
||||
cdrom := self.getCdrom()
|
||||
desc := jsonutils.NewDict()
|
||||
if len(cdrom.ImageId) > 0 {
|
||||
desc.Set("image_id", jsonutils.NewString(cdrom.ImageId))
|
||||
desc.Set("status", jsonutils.NewString("inserting"))
|
||||
}
|
||||
if len(cdrom.Path) > 0 {
|
||||
desc.Set("name", jsonutils.NewString(cdrom.Name))
|
||||
desc.Set("size", jsonutils.NewInt(int64(cdrom.Size)))
|
||||
desc.Set("status", jsonutils.NewString("ready"))
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, hostId string, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
self.insertIso(imageId)
|
||||
|
||||
@@ -2014,7 +2047,7 @@ func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, host
|
||||
data.Add(jsonutils.NewString(imageId), "image_id")
|
||||
data.Add(jsonutils.NewString(hostId), "host_id")
|
||||
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestInsertISOTask", self, userCred, data, parentTaskId, "", nil)
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestInsertIsoTask", self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/yunionio/sqlchemy"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/cloudprovider"
|
||||
"github.com/yunionio/onecloud/pkg/compute/options"
|
||||
"github.com/yunionio/onecloud/pkg/httperrors"
|
||||
@@ -1517,6 +1518,22 @@ func (manager *SHostManager) GetHostsByManagerAndRegion(managerId string, region
|
||||
return ret
|
||||
}
|
||||
|
||||
func (self *SHost) StartImageCacheTask(ctx context.Context, userCred mcclient.TokenCredential, imageId, parentTaskId string, isForce bool) error {
|
||||
//Todo
|
||||
// HostcachedimagesManager.Register(userCred, self, imageId)
|
||||
data := jsonutils.NewDict()
|
||||
data.Set("image_id", jsonutils.NewString(imageId))
|
||||
if isForce {
|
||||
data.Set("is_force", jsonutils.JSONTrue)
|
||||
}
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "StorageCacheImageTask", self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SHost) Request(userCred mcclient.TokenCredential, method string, url string, headers http.Header, body jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
s := auth.GetSession(userCred, "", "")
|
||||
_, ret, err := s.JSONRequest(self.ManagerUri, "", method, url, headers, body)
|
||||
|
||||
@@ -28,6 +28,10 @@ func (self *GuestCreateDiskTask) OnDiskPrepared(ctx context.Context, obj db.ISta
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *GuestCreateDiskTask) OnDiskPreparedFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageFailed(ctx, data.String())
|
||||
}
|
||||
|
||||
/* --------------------------------------------- */
|
||||
/* -----------KVMGuestCreateDiskTask------------ */
|
||||
/* --------------------------------------------- */
|
||||
|
||||
@@ -4,8 +4,10 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/yunionio/jsonutils"
|
||||
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
|
||||
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"github.com/yunionio/onecloud/pkg/compute/models"
|
||||
)
|
||||
|
||||
type GuestInsertIsoTask struct {
|
||||
@@ -17,5 +19,59 @@ func init() {
|
||||
}
|
||||
|
||||
func (self *GuestInsertIsoTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
// TODO
|
||||
self.prepareIsoImage(ctx, obj)
|
||||
}
|
||||
|
||||
func (self *GuestInsertIsoTask) prepareIsoImage(ctx context.Context, obj db.IStandaloneModel) {
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_ISO_PREPARING, imageId, self.UserCred)
|
||||
var host *models.SHost
|
||||
if self.Params.Contains("host_id") {
|
||||
hostId, _ := self.Params.GetString("host_id")
|
||||
iHost, _ := models.HostManager.FetchById(hostId)
|
||||
host = iHost.(*models.SHost)
|
||||
} else {
|
||||
guest := obj.(*models.SGuest)
|
||||
host = guest.GetHost()
|
||||
}
|
||||
self.SetStage("OnIsoPrepareComplete", nil)
|
||||
host.StartImageCacheTask(ctx, self.UserCred, imageId, self.GetTaskId(), false)
|
||||
}
|
||||
|
||||
func (self *GuestInsertIsoTask) OnIsoPrepareCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
imageId, _ := self.Params.GetString("image_id")
|
||||
db.OpsLog.LogEvent(obj, db.ACT_ISO_PREPARE_FAIL, imageId, self.UserCred)
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.EjectIso(self.UserCred)
|
||||
self.SetStageFailed(ctx, "OnIsoPrepareCompleteFailed")
|
||||
}
|
||||
|
||||
func (self *GuestInsertIsoTask) OnIsoPrepareComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
imageId, _ := data.GetString("image_id")
|
||||
jSize, err := data.Get("size")
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
}
|
||||
size, err := jSize.Int()
|
||||
if err != nil {
|
||||
self.SetStageFailed(ctx, err.Error())
|
||||
}
|
||||
name, _ := data.GetString("name")
|
||||
path, _ := data.GetString("path")
|
||||
guest := obj.(*models.SGuest)
|
||||
if guest.InsertIsoSucc(imageId, path, int(size), name) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_ISO_ATTACH, guest.GetDetailsIso(self.UserCred), self.UserCred)
|
||||
if guest.Status == models.VM_RUNNING {
|
||||
self.SetStage("OnConfigSyncComplete", nil)
|
||||
guest.GetDriver().RequestGuestHotAddIso(ctx, guest, path, self)
|
||||
} else {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
} else {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *GuestInsertIsoTask) OnConfigSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -54,6 +54,10 @@ func (self *SDatastore) GetIZone() cloudprovider.ICloudZone {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetIDisk(idStr string) (cloudprovider.ICloudDisk, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SDatastore) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user