kvm server create

This commit is contained in:
wanyaoqi
2018-08-11 10:21:28 +08:00
parent f04463b526
commit c0a2135567
11 changed files with 169 additions and 25 deletions
+18 -9
View File
@@ -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)
+11 -7
View File
@@ -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")
}
+5 -3
View File
@@ -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
}
+8
View File
@@ -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())
}
+5
View File
@@ -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)
+2
View File
@@ -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
+38 -5
View File
@@ -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
}
+17
View File
@@ -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------------ */
/* --------------------------------------------- */
+57 -1
View File
@@ -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)
}
+4
View File
@@ -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
}