From 3acf030fefa0487684bec4039147fd83ae2370fb Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Tue, 2 Jul 2019 15:11:11 +0800 Subject: [PATCH 1/2] - set mirror status on switch - deploy agent - gpfs snapshot - code fixs --- .../doc.go => cmd/host-deployer/main.go | 9 +- go.mod | 2 + go.sum | 2 + pkg/baremetal/manager.go | 9 +- pkg/baremetal/nic.go | 2 +- pkg/cloudcommon/service/services.go | 22 +- pkg/cloudcommon/sshkeys/sshkeys.go | 33 - pkg/cloudcommon/types/nic.go | 59 +- pkg/cloudprovider/serversku.go | 14 + pkg/compute/hostdrivers/kvm.go | 25 +- pkg/compute/models/disks.go | 11 +- pkg/compute/models/snapshots.go | 18 +- pkg/compute/tasks/disk_create_task.go | 4 +- pkg/compute/tasks/guest_backup_tasks.go | 9 +- pkg/compute/tasks/guest_disk_snapshot_task.go | 43 +- .../{storageman => diskutils}/diskutils.go | 4 +- pkg/hostman/diskutils/doc.go | 1 + .../{storageman => diskutils}/lvmutils.go | 2 +- .../{storageman => diskutils}/nbd/doc.go | 2 +- .../{storageman => diskutils}/nbd/nbdman.go | 0 .../nbd/nbdman_test.go | 0 pkg/hostman/guestfs/core.go | 136 +- pkg/hostman/guestfs/fsdriver/android.go | 12 +- pkg/hostman/guestfs/fsdriver/base.go | 43 +- pkg/hostman/guestfs/fsdriver/base_test.go | 6 +- pkg/hostman/guestfs/fsdriver/drivers.go | 9 +- pkg/hostman/guestfs/fsdriver/esxi.go | 11 +- pkg/hostman/guestfs/fsdriver/interface.go | 16 +- pkg/hostman/guestfs/fsdriver/linux.go | 151 +- pkg/hostman/guestfs/fsdriver/macos.go | 11 +- pkg/hostman/guestfs/fsdriver/nicteaming.go | 27 +- pkg/hostman/guestfs/fsdriver/windows.go | 36 +- pkg/hostman/guestfs/kvmpart.go | 12 +- pkg/hostman/guestfs/localfs.go | 12 +- .../{ => guestman}/guesthandlers/doc.go | 2 +- .../guesthandlers/guesthandler.go | 4 +- pkg/hostman/guestman/guestman.go | 37 +- pkg/hostman/guestman/guesttasks.go | 14 +- pkg/hostman/guestman/qemu-kvm.go | 4 +- pkg/hostman/host_services.go | 14 +- pkg/hostman/hostdeployer/apis/deploy.pb.go | 1673 +++++++++++++++++ pkg/hostman/hostdeployer/apis/deploy.proto | 159 ++ pkg/hostman/hostdeployer/apis/doc.go | 1 + pkg/hostman/hostdeployer/apis/utils.go | 114 ++ .../hostdeployer/deployclient/deployclient.go | 105 ++ pkg/hostman/hostdeployer/deployclient/doc.go | 1 + .../hostdeployer/deployserver/deployserver.go | 254 +++ pkg/hostman/hostdeployer/deployserver/doc.go | 1 + .../hostdeployer/deployserver/options.go | 27 + pkg/hostman/hostinfo/hostdhcp/dhcpserver.go | 2 +- pkg/hostman/hostinfo/hostinfo.go | 67 +- pkg/hostman/options/options.go | 4 +- pkg/hostman/storageman/core.go | 2 +- pkg/hostman/storageman/disk_base.go | 77 +- pkg/hostman/storageman/disk_local.go | 26 +- pkg/hostman/storageman/disk_nas.go | 40 + pkg/hostman/storageman/disk_rbd.go | 24 +- .../diskhandlers/diskhandler.go | 0 .../{ => storageman}/diskhandlers/doc.go | 2 +- pkg/hostman/storageman/storage_base.go | 181 +- pkg/hostman/storageman/storage_gpfs.go | 1 + pkg/hostman/storageman/storage_local.go | 183 +- pkg/hostman/storageman/storage_nas.go | 12 +- pkg/hostman/storageman/storage_nfs.go | 5 +- pkg/hostman/storageman/storage_rbd.go | 46 +- pkg/hostman/storageman/storagehandler/doc.go | 1 + .../{ => storagehandler}/storagehandler.go | 19 +- pkg/hostman/system_service/host_deployer.go | 17 + pkg/hostman/system_service/system_service.go | 1 + pkg/image/options/options.go | 3 +- pkg/image/service/service.go | 6 +- pkg/image/tasks/image_probe_task.go | 45 +- pkg/util/netutils2/netutils.go | 27 +- pkg/util/sysutils/kvm.go | 19 + .../golang/protobuf/proto/decode.go | 1 - .../golang/protobuf/proto/deprecated.go | 63 + .../github.com/golang/protobuf/proto/equal.go | 3 +- .../golang/protobuf/proto/extensions.go | 78 +- .../github.com/golang/protobuf/proto/lib.go | 38 +- .../golang/protobuf/proto/message_set.go | 137 +- .../golang/protobuf/proto/pointer_reflect.go | 5 +- .../golang/protobuf/proto/pointer_unsafe.go | 15 +- .../golang/protobuf/proto/properties.go | 31 +- .../golang/protobuf/proto/table_marshal.go | 45 +- .../golang/protobuf/proto/table_unmarshal.go | 74 +- .../golang/protobuf/ptypes/any/any.pb.go | 45 +- .../golang/protobuf/ptypes/any/any.proto | 21 +- .../golang/protobuf/ptypes/duration.go | 2 +- .../protobuf/ptypes/duration/duration.pb.go | 26 +- .../golang/protobuf/ptypes/timestamp.go | 6 +- .../protobuf/ptypes/timestamp/timestamp.pb.go | 34 +- .../protobuf/ptypes/timestamp/timestamp.proto | 8 +- vendor/modules.txt | 14 +- 93 files changed, 3485 insertions(+), 1134 deletions(-) rename pkg/cloudcommon/sshkeys/doc.go => cmd/host-deployer/main.go (77%) delete mode 100644 pkg/cloudcommon/sshkeys/sshkeys.go rename pkg/hostman/{storageman => diskutils}/diskutils.go (99%) create mode 100644 pkg/hostman/diskutils/doc.go rename pkg/hostman/{storageman => diskutils}/lvmutils.go (99%) rename pkg/hostman/{storageman => diskutils}/nbd/doc.go (89%) rename pkg/hostman/{storageman => diskutils}/nbd/nbdman.go (100%) rename pkg/hostman/{storageman => diskutils}/nbd/nbdman_test.go (100%) rename pkg/hostman/{ => guestman}/guesthandlers/doc.go (96%) rename pkg/hostman/{ => guestman}/guesthandlers/guesthandler.go (98%) create mode 100644 pkg/hostman/hostdeployer/apis/deploy.pb.go create mode 100644 pkg/hostman/hostdeployer/apis/deploy.proto create mode 100644 pkg/hostman/hostdeployer/apis/doc.go create mode 100644 pkg/hostman/hostdeployer/apis/utils.go create mode 100644 pkg/hostman/hostdeployer/deployclient/deployclient.go create mode 100644 pkg/hostman/hostdeployer/deployclient/doc.go create mode 100644 pkg/hostman/hostdeployer/deployserver/deployserver.go create mode 100644 pkg/hostman/hostdeployer/deployserver/doc.go create mode 100644 pkg/hostman/hostdeployer/deployserver/options.go rename pkg/hostman/{ => storageman}/diskhandlers/diskhandler.go (100%) rename pkg/hostman/{ => storageman}/diskhandlers/doc.go (96%) create mode 100644 pkg/hostman/storageman/storagehandler/doc.go rename pkg/hostman/storageman/{ => storagehandler}/storagehandler.go (88%) create mode 100644 pkg/hostman/system_service/host_deployer.go create mode 100644 vendor/github.com/golang/protobuf/proto/deprecated.go diff --git a/pkg/cloudcommon/sshkeys/doc.go b/cmd/host-deployer/main.go similarity index 77% rename from pkg/cloudcommon/sshkeys/doc.go rename to cmd/host-deployer/main.go index 108e1b758b..33b79a61fc 100644 --- a/pkg/cloudcommon/sshkeys/doc.go +++ b/cmd/host-deployer/main.go @@ -12,4 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -package sshkeys // import "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" +package main + +import "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployserver" + +func main() { + deployer := deployserver.NewDeployService() + deployer.StartService() +} diff --git a/go.mod b/go.mod index 532fb5f39d..10c3124a37 100644 --- a/go.mod +++ b/go.mod @@ -61,6 +61,7 @@ require ( github.com/golang-plus/testing v1.0.0 // indirect github.com/golang-plus/uuid v1.0.0 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect + github.com/golang/protobuf v1.3.1 github.com/google/btree v1.0.0 // indirect github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect github.com/google/gopacket v1.1.17 @@ -138,6 +139,7 @@ require ( golang.org/x/time v0.0.0-20181108054448-85acf8d2951c // indirect google.golang.org/appengine v1.3.0 // indirect google.golang.org/genproto v0.0.0-20181218023534-67d6565462c5 // indirect + google.golang.org/grpc v1.19.0 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/go-playground/validator.v8 v8.18.2 // indirect diff --git a/go.sum b/go.sum index 9be78048b0..1aabbb011c 100644 --- a/go.sum +++ b/go.sum @@ -167,6 +167,8 @@ github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200j github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= diff --git a/pkg/baremetal/manager.go b/pkg/baremetal/manager.go index 9cf7e0b1f8..22a0ebe07b 100644 --- a/pkg/baremetal/manager.go +++ b/pkg/baremetal/manager.go @@ -50,11 +50,11 @@ import ( "yunion.io/x/onecloud/pkg/baremetal/utils/disktool" "yunion.io/x/onecloud/pkg/baremetal/utils/ipmitool" raiddrivers "yunion.io/x/onecloud/pkg/baremetal/utils/raid/drivers" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" "yunion.io/x/onecloud/pkg/cloudcommon/types" "yunion.io/x/onecloud/pkg/compute/baremetal" "yunion.io/x/onecloud/pkg/hostman/guestfs" "yunion.io/x/onecloud/pkg/hostman/guestfs/sshpart" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/auth" @@ -1704,18 +1704,19 @@ func (s *SBaremetalServer) SyncPartitionSize(term *ssh.Client, parts []*disktool } func (s *SBaremetalServer) DoDeploy(term *ssh.Client, data jsonutils.JSONObject, isInit bool) (jsonutils.JSONObject, error) { - publicKey := sshkeys.GetKeys(data) + publicKey := deployapi.GetKeys(data) deploys, _ := data.GetArray("deploys") password, _ := data.GetString("password") resetPassword := jsonutils.QueryBoolean(data, "reset_password", false) if resetPassword && len(password) == 0 { password = seclib.RandomPassword(12) } - deployInfo := guestfs.NewDeployInfo(publicKey, deploys, password, isInit, true, o.Options.LinuxDefaultRootUser, o.Options.WindowsDefaultAdminUser, false) + deployInfo := deployapi.NewDeployInfo(publicKey, deployapi.JsonDeploysToStructs(deploys), + password, isInit, true, o.Options.LinuxDefaultRootUser, o.Options.WindowsDefaultAdminUser, false) return s.deployFs(term, deployInfo) } -func (s *SBaremetalServer) deployFs(term *ssh.Client, deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error) { +func (s *SBaremetalServer) deployFs(term *ssh.Client, deployInfo *deployapi.DeployInfo) (jsonutils.JSONObject, error) { raid, nonRaid, pcie, err := detect_storages.DetectStorageInfo(term, false) if err != nil { return nil, err diff --git a/pkg/baremetal/nic.go b/pkg/baremetal/nic.go index 22be7861aa..50c7ca6523 100644 --- a/pkg/baremetal/nic.go +++ b/pkg/baremetal/nic.go @@ -50,7 +50,7 @@ func GetNicDHCPConfig( routes := make([][]string, 0) for _, route := range n.Routes { - routes = append(routes, []string{route[0], route[1]}) + routes = append(routes, []string{route.Route[0], route.Route[1]}) } conf := &dhcp.ResponseConfig{ diff --git a/pkg/cloudcommon/service/services.go b/pkg/cloudcommon/service/services.go index cf6e3ae99a..caab07f7e5 100644 --- a/pkg/cloudcommon/service/services.go +++ b/pkg/cloudcommon/service/services.go @@ -16,14 +16,18 @@ package service import ( "fmt" - "log" "os" "path/filepath" "strconv" + "syscall" + + "yunion.io/x/log" "yunion.io/x/onecloud/pkg/cloudcommon/options" "yunion.io/x/onecloud/pkg/util/fileutils2" "yunion.io/x/onecloud/pkg/util/procutils" + "yunion.io/x/pkg/util/signalutils" + "yunion.io/x/pkg/utils" ) type IService interface { @@ -38,6 +42,10 @@ type SServiceBase struct { O *options.BaseOptions } +func NewBaseService(service IService) *SServiceBase { + return &SServiceBase{Service: service} +} + func (s *SServiceBase) StartService() { defer s.Service.OnExitService() defer s.RemovePid() @@ -78,3 +86,15 @@ func (s *SServiceBase) RemovePid() { os.Remove(s.O.PidFile) } } + +func (s *SServiceBase) SignalTrap(onExit func()) { + // dump goroutine stack + signalutils.RegisterSignal(func() { + utils.DumpAllGoroutineStack(log.Logger().Out) + }, syscall.SIGUSR1) + if onExit != nil { + quitSignals := []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM} + signalutils.RegisterSignal(onExit, quitSignals...) + } + signalutils.StartTrap() +} diff --git a/pkg/cloudcommon/sshkeys/sshkeys.go b/pkg/cloudcommon/sshkeys/sshkeys.go deleted file mode 100644 index 595125f371..0000000000 --- a/pkg/cloudcommon/sshkeys/sshkeys.go +++ /dev/null @@ -1,33 +0,0 @@ -// 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 sshkeys - -import "yunion.io/x/jsonutils" - -type SSHKeys struct { - PublicKey string - DeletePublicKey string - AdminPublicKey string - ProjectPublicKey string -} - -func GetKeys(data jsonutils.JSONObject) *SSHKeys { - var ret = new(SSHKeys) - ret.PublicKey, _ = data.GetString("public_key") - ret.DeletePublicKey, _ = data.GetString("delete_public_key") - ret.AdminPublicKey, _ = data.GetString("admin_public_key") - ret.ProjectPublicKey, _ = data.GetString("project_public_key") - return ret -} diff --git a/pkg/cloudcommon/types/nic.go b/pkg/cloudcommon/types/nic.go index 0627bb52c8..bf467e7cd3 100644 --- a/pkg/cloudcommon/types/nic.go +++ b/pkg/cloudcommon/types/nic.go @@ -18,6 +18,8 @@ import ( "net" "yunion.io/x/pkg/util/netutils" + + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) const ( @@ -30,21 +32,21 @@ var ( ) type SNic struct { - Type string `json:"nic_type"` - Domain string `json:"domain"` - Wire string `json:"wire"` - IpAddr string `json:"ip_addr"` - WireId string `json:"wire_id"` - NetId string `json:"net_id"` - Rate int64 `json:"rate"` - Mtu int64 `json:"mtu"` - Mac string `json:"mac"` - Dns string `json:"dns"` - MaskLen int8 `json:"masklen"` - Net string `json:"net"` - Gateway string `json:"gateway"` - LinkUp bool `json:"link_up"` - Routes []SRoute `json:"routes,omitempty"` + Type string `json:"nic_type"` + Domain string `json:"domain"` + Wire string `json:"wire"` + IpAddr string `json:"ip_addr"` + WireId string `json:"wire_id"` + NetId string `json:"net_id"` + Rate int64 `json:"rate"` + Mtu int64 `json:"mtu"` + Mac string `json:"mac"` + Dns string `json:"dns"` + MaskLen int8 `json:"masklen"` + Net string `json:"net"` + Gateway string `json:"gateway"` + LinkUp bool `json:"link_up"` + Routes []*deployapi.Routes `json:"routes,omitempty"` } func (n SNic) GetNetMask() string { @@ -55,33 +57,8 @@ func (n SNic) GetMac() net.HardwareAddr { return getMac(n.Mac) } -type SRoute []string - type SServerNic struct { - Name string `json:"name"` - Index int `json:"index"` - Bridge string `json:"bridge"` - Domain string `json:"domain"` - Ip string `json:"ip"` - Vlan int `json:"vlan"` - Driver string `json:"driver"` - Masklen int `json:"masklen"` - Virtual bool `json:"virtual"` - Manual bool `json:"manual"` - WireId string `json:"wire_id"` - NetId string `json:"net_id"` - Mac string `json:"mac"` - BandWidth int `json:"bw"` - Dns string `json:"dns"` - Net string `json:"net"` - Interface string `json:"interface"` - Gateway string `json:"gateway"` - Ifname string `json:"ifname"` - Routes []SRoute `json:"routes,omitempty"` - NicType string `json:"nic_type,omitempty"` - LinkUp bool `json:"link_up,omitempty"` - Mtu int64 `json:"mtu,omitempty"` - TeamWith string `json:"team_with,omitempty"` + *deployapi.Nic TeamingMaster *SServerNic `json:"-"` TeamingSlaves []*SServerNic `json:"-"` diff --git a/pkg/cloudprovider/serversku.go b/pkg/cloudprovider/serversku.go index 148392fa4d..ffb1161a5e 100644 --- a/pkg/cloudprovider/serversku.go +++ b/pkg/cloudprovider/serversku.go @@ -1,3 +1,17 @@ +// 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 cloudprovider type SServerSku struct { diff --git a/pkg/compute/hostdrivers/kvm.go b/pkg/compute/hostdrivers/kvm.go index 8e57424800..955661a332 100644 --- a/pkg/compute/hostdrivers/kvm.go +++ b/pkg/compute/hostdrivers/kvm.go @@ -225,17 +225,22 @@ func (self *SKVMHostDriver) RequestAllocateDiskOnStorage(ctx context.Context, ho iSnapshot, _ := models.SnapshotManager.FetchById(snapshotId) snapshot := iSnapshot.(*models.SSnapshot) snapshotStorage := models.StorageManager.FetchStorageById(snapshot.StorageId) - snapshotHost := snapshotStorage.GetMasterHost() - if options.Options.SnapshotCreateDiskProtocol == "url" { - content.Set("snapshot_url", - jsonutils.NewString(fmt.Sprintf("%s/download/snapshots/%s/%s/%s", - snapshotHost.ManagerUri, snapshotStorage.Id, snapshot.DiskId, snapshot.Id))) - content.Set("snapshot_out_of_chain", jsonutils.NewBool(snapshot.OutOfChain)) - } else if options.Options.SnapshotCreateDiskProtocol == "fuse" { - content.Set("snapshot_url", jsonutils.NewString(fmt.Sprintf("%s/snapshots/%s/%s", - snapshotHost.GetFetchUrl(true), snapshot.DiskId, snapshot.Id))) + if snapshotStorage.StorageType == api.STORAGE_LOCAL { + snapshotHost := snapshotStorage.GetMasterHost() + if options.Options.SnapshotCreateDiskProtocol == "url" { + content.Set("snapshot_url", + jsonutils.NewString(fmt.Sprintf("%s/download/snapshots/%s/%s/%s", + snapshotHost.ManagerUri, snapshotStorage.Id, snapshot.DiskId, snapshot.Id))) + content.Set("snapshot_out_of_chain", jsonutils.NewBool(snapshot.OutOfChain)) + } else if options.Options.SnapshotCreateDiskProtocol == "fuse" { + content.Set("snapshot_url", jsonutils.NewString(fmt.Sprintf("%s/snapshots/%s/%s", + snapshotHost.GetFetchUrl(true), snapshot.DiskId, snapshot.Id))) + } + content.Set("protocol", jsonutils.NewString(options.Options.SnapshotCreateDiskProtocol)) + } else { + content.Set("snapshot_url", jsonutils.NewString(snapshot.Location)) + content.Set("protocol", jsonutils.NewString("location")) } - content.Set("protocol", jsonutils.NewString(options.Options.SnapshotCreateDiskProtocol)) } url := fmt.Sprintf("/disks/%s/create/%s", storage.Id, disk.Id) diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index 4bef4c4d5c..ce47438405 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -589,6 +589,14 @@ func (self *SDisk) AllowGetDetailsConvertSnapshot(ctx context.Context, userCred } func (self *SDisk) GetDetailsConvertSnapshot(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) { + needs, err := SnapshotManager.IsDiskSnapshotsNeedConvert(self.Id) + if err != nil { + return nil, httperrors.NewInternalServerError("Fetch snapshot count failed %s", err) + } + if !needs { + return nil, httperrors.NewBadRequestError("Disk %s don't need convert snapshots", self.Id) + } + deleteSnapshot := SnapshotManager.GetDiskFirstSnapshot(self.Id) if deleteSnapshot == nil { return nil, httperrors.NewNotFoundError("Can not get disk snapshot") @@ -651,7 +659,8 @@ func (self *SDisk) PerformCreateSnapshot(ctx context.Context, userCred mcclient. return nil, httperrors.NewBadRequestError("Disk dosen't attach guest??") } storage := self.GetStorage() - if guests[0].Hypervisor == api.HYPERVISOR_KVM && storage.StorageType != api.STORAGE_LOCAL { + if guests[0].Hypervisor == api.HYPERVISOR_KVM && + !utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_LOCAL, api.STORAGE_NFS, api.STORAGE_GPFS}) { return nil, httperrors.NewBadRequestError("storage %s not support snapshot", storage.StorageType) } diff --git a/pkg/compute/models/snapshots.go b/pkg/compute/models/snapshots.go index 61197d890e..ebf54fe15b 100644 --- a/pkg/compute/models/snapshots.go +++ b/pkg/compute/models/snapshots.go @@ -406,6 +406,16 @@ func (self *SSnapshotManager) GetDiskSnapshots(diskId string) []SSnapshot { return dest } +func (self *SSnapshotManager) IsDiskSnapshotsNeedConvert(diskId string) (bool, error) { + count, err := self.Query().Equals("disk_id", diskId). + In("status", []string{api.SNAPSHOT_READY, api.SNAPSHOT_DELETING}). + Equals("out_of_chain", false).CountWithError() + if err != nil { + return false, err + } + return count >= options.Options.DefaultMaxSnapshotCount, nil +} + func (self *SSnapshotManager) GetDiskFirstSnapshot(diskId string) *SSnapshot { dest := &SSnapshot{} q := self.Query().SubQuery() @@ -476,8 +486,8 @@ func (self *SSnapshot) StartSnapshotDeleteTask(ctx context.Context, userCred mcc } func (self *SSnapshot) ValidateDeleteCondition(ctx context.Context) error { - if self.RefCount > 0 { - return fmt.Errorf("Snapshot reference(by disk) count > 0, can not delete") + if len(self.ExternalId) == 0 && self.RefCount > 0 { + return httperrors.NewBadRequestError("Snapshot reference(by disk) count > 0, can not delete") } return nil } @@ -488,8 +498,10 @@ func (self *SSnapshot) CustomizeDelete(ctx context.Context, userCred mcclient.To } if len(self.ExternalId) == 0 { if self.CreatedBy == api.SNAPSHOT_MANUAL { - if !self.FakeDeleted { + if !self.OutOfChain && !self.FakeDeleted { return self.FakeDelete() + } else if self.OutOfChain { + return self.StartSnapshotDeleteTask(ctx, userCred, false, "") } _, err := SnapshotManager.GetConvertSnapshot(self) if err != nil { diff --git a/pkg/compute/tasks/disk_create_task.go b/pkg/compute/tasks/disk_create_task.go index acbb477609..fd7cdf4a5b 100644 --- a/pkg/compute/tasks/disk_create_task.go +++ b/pkg/compute/tasks/disk_create_task.go @@ -65,7 +65,7 @@ func (self *DiskCreateTask) OnStorageCacheImageComplete(ctx context.Context, dis storage := disk.GetStorage() host := storage.GetMasterHost() db.OpsLog.LogEvent(disk, db.ACT_ALLOCATING, disk.GetShortDesc(ctx), self.GetUserCred()) - disk.SetStatus(self.GetUserCred(), api.DISK_STARTALLOC, "") + disk.SetStatus(self.GetUserCred(), api.DISK_STARTALLOC, fmt.Sprintf("Disk start alloc use host %s(%s)", host.Name, host.Id)) if len(disk.BackupStorageId) > 0 { self.SetStage("OnMasterStorageCreateDiskComplete", nil) } else { @@ -82,7 +82,7 @@ func (self *DiskCreateTask) OnMasterStorageCreateDiskComplete(ctx context.Contex storage := models.StorageManager.FetchStorageById(disk.BackupStorageId) host := storage.GetMasterHost() db.OpsLog.LogEvent(disk, db.ACT_BACKUP_ALLOCATING, disk.GetShortDesc(ctx), self.GetUserCred()) - disk.SetStatus(self.UserCred, api.DISK_BACKUP_STARTALLOC, "") + disk.SetStatus(self.UserCred, api.DISK_BACKUP_STARTALLOC, fmt.Sprintf("Backup disk start alloc use host %s(%s)", host.Name, host.Id)) self.SetStage("OnDiskReady", nil) if err := disk.StartAllocate(ctx, host, storage, self.GetTaskId(), self.GetUserCred(), rebuild, snapshot, self); err != nil { self.OnBackupAllocateFailed(ctx, disk, jsonutils.NewString(fmt.Sprintf("Backup disk alloctate failed: %s", err.Error()))) diff --git a/pkg/compute/tasks/guest_backup_tasks.go b/pkg/compute/tasks/guest_backup_tasks.go index 8ab398a11c..2f51ab9c7d 100644 --- a/pkg/compute/tasks/guest_backup_tasks.go +++ b/pkg/compute/tasks/guest_backup_tasks.go @@ -96,7 +96,7 @@ func (self *GuestSwitchToBackupTask) OnBackupGuestStoped(ctx context.Context, gu } func (self *GuestSwitchToBackupTask) OnNewMasterStarted(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { - self.SetStageComplete(ctx, nil) + self.OnComplete(ctx, guest, nil) } func (self *GuestSwitchToBackupTask) OnFail(ctx context.Context, guest *models.SGuest, reason string) { @@ -106,13 +106,18 @@ func (self *GuestSwitchToBackupTask) OnFail(ctx context.Context, guest *models.S self.SetStageFailed(ctx, reason) } +func (self *GuestSwitchToBackupTask) OnComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { + guest.SetMetadata(ctx, "__mirror_job_status", "", self.UserCred) + self.SetStageComplete(ctx, nil) +} + func (self *GuestSwitchToBackupTask) OnSwitched(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { oldStatus, _ := self.Params.GetString("old_status") if utils.IsInStringArray(oldStatus, api.VM_RUNNING_STATUS) { self.SetStage("OnNewMasterStarted", nil) guest.StartGueststartTask(ctx, self.UserCred, nil, self.GetTaskId()) } else { - self.SetStageComplete(ctx, nil) + self.OnComplete(ctx, guest, nil) } } diff --git a/pkg/compute/tasks/guest_disk_snapshot_task.go b/pkg/compute/tasks/guest_disk_snapshot_task.go index a70b4e3741..3a3fecd287 100644 --- a/pkg/compute/tasks/guest_disk_snapshot_task.go +++ b/pkg/compute/tasks/guest_disk_snapshot_task.go @@ -253,7 +253,6 @@ func (self *SnapshotDeleteTask) OnDeleteSnapshot(ctx context.Context, snapshot * snapshot.RealDelete(ctx, self.UserCred) self.TaskComplete(ctx, snapshot, nil) } else { - guest, _ := snapshot.GetGuest() var FakeDelete = false if snapshot.CreatedBy == api.SNAPSHOT_MANUAL && snapshot.FakeDeleted == false { FakeDelete = true @@ -266,8 +265,7 @@ func (self *SnapshotDeleteTask) OnDeleteSnapshot(ctx context.Context, snapshot * } else { snapshot.RealDelete(ctx, self.UserCred) } - self.SetStage("TaskComplete", nil) - guest.StartSyncstatus(ctx, self.UserCred, "") + self.TaskComplete(ctx, snapshot, nil) } } else { snapshot.SetStatus(self.UserCred, api.SNAPSHOT_READY, "OnDeleteSnapshot") @@ -282,35 +280,40 @@ func (self *SnapshotDeleteTask) OnDeleteSnapshotFailed(ctx context.Context, snap func (self *SnapshotDeleteTask) OnReloadDiskSnapshot(ctx context.Context, snapshot *models.SSnapshot, data jsonutils.JSONObject) { if !jsonutils.QueryBoolean(data, "reopen", false) { - log.Infof("OnDeleteSnapshot with no reopen") + log.Infof("OnReloadDiskSnapshot with no reopen") return } - if snapshot.CreatedBy == api.SNAPSHOT_AUTO { - err := snapshot.RealDelete(ctx, self.UserCred) - if err != nil { - self.TaskFailed(ctx, snapshot, err.Error()) - return - } - } else { - err := snapshot.FakeDelete() - if err != nil { - self.TaskFailed(ctx, snapshot, err.Error()) - return - } - } - self.SetStage("TaskComplete", nil) + guest, err := snapshot.GetGuest() if err != nil { - self.SetStageFailed(ctx, err.Error()) + self.TaskFailed(ctx, snapshot, err.Error()) return } - guest.StartSyncstatus(ctx, self.UserCred, self.GetTaskId()) + if snapshot.FakeDeleted { + params := jsonutils.NewDict() + params.Set("delete_snapshot", jsonutils.NewString(snapshot.Id)) + params.Set("disk_id", jsonutils.NewString(snapshot.DiskId)) + params.Set("auto_deleted", jsonutils.JSONTrue) + self.SetStage("OnDeleteSnapshot", nil) + err = guest.GetDriver().RequestDeleteSnapshot(ctx, guest, self, params) + if err != nil { + self.TaskFailed(ctx, snapshot, err.Error()) + } + } else { + self.TaskComplete(ctx, snapshot, nil) + } } func (self *SnapshotDeleteTask) TaskComplete(ctx context.Context, snapshot *models.SSnapshot, data jsonutils.JSONObject) { db.OpsLog.LogEvent(snapshot, db.ACT_SNAPSHOT_DELETE, snapshot.GetShortDesc(ctx), self.UserCred) logclient.AddActionLogWithStartable(self, snapshot, logclient.ACT_DELOCATE, nil, self.UserCred, true) self.SetStageComplete(ctx, nil) + guest, err := snapshot.GetGuest() + if err != nil { + log.Errorln(err.Error()) + return + } + guest.StartSyncstatus(ctx, self.UserCred, "") } func (self *SnapshotDeleteTask) TaskFailed(ctx context.Context, snapshot *models.SSnapshot, reason string) { diff --git a/pkg/hostman/storageman/diskutils.go b/pkg/hostman/diskutils/diskutils.go similarity index 99% rename from pkg/hostman/storageman/diskutils.go rename to pkg/hostman/diskutils/diskutils.go index 808785ec5f..457aba0ace 100644 --- a/pkg/hostman/storageman/diskutils.go +++ b/pkg/hostman/diskutils/diskutils.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storageman +package diskutils import ( "fmt" @@ -26,9 +26,9 @@ import ( "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/hostman/diskutils/nbd" "yunion.io/x/onecloud/pkg/hostman/guestfs" "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" - "yunion.io/x/onecloud/pkg/hostman/storageman/nbd" "yunion.io/x/onecloud/pkg/util/fileutils2" "yunion.io/x/onecloud/pkg/util/procutils" "yunion.io/x/onecloud/pkg/util/qemuimg" diff --git a/pkg/hostman/diskutils/doc.go b/pkg/hostman/diskutils/doc.go new file mode 100644 index 0000000000..a23c20344e --- /dev/null +++ b/pkg/hostman/diskutils/doc.go @@ -0,0 +1 @@ +package diskutils // import "yunion.io/x/onecloud/pkg/hostman/diskutils" diff --git a/pkg/hostman/storageman/lvmutils.go b/pkg/hostman/diskutils/lvmutils.go similarity index 99% rename from pkg/hostman/storageman/lvmutils.go rename to pkg/hostman/diskutils/lvmutils.go index bec80653c2..f7e50b3af4 100644 --- a/pkg/hostman/storageman/lvmutils.go +++ b/pkg/hostman/diskutils/lvmutils.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storageman +package diskutils import ( "fmt" diff --git a/pkg/hostman/storageman/nbd/doc.go b/pkg/hostman/diskutils/nbd/doc.go similarity index 89% rename from pkg/hostman/storageman/nbd/doc.go rename to pkg/hostman/diskutils/nbd/doc.go index 10c133eeda..e5c309db66 100644 --- a/pkg/hostman/storageman/nbd/doc.go +++ b/pkg/hostman/diskutils/nbd/doc.go @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -package nbd // import "yunion.io/x/onecloud/pkg/hostman/storageman/nbd" +package nbd // import "yunion.io/x/onecloud/pkg/hostman/diskutils/nbd" diff --git a/pkg/hostman/storageman/nbd/nbdman.go b/pkg/hostman/diskutils/nbd/nbdman.go similarity index 100% rename from pkg/hostman/storageman/nbd/nbdman.go rename to pkg/hostman/diskutils/nbd/nbdman.go diff --git a/pkg/hostman/storageman/nbd/nbdman_test.go b/pkg/hostman/diskutils/nbd/nbdman_test.go similarity index 100% rename from pkg/hostman/storageman/nbd/nbdman_test.go rename to pkg/hostman/diskutils/nbd/nbdman_test.go diff --git a/pkg/hostman/guestfs/core.go b/pkg/hostman/guestfs/core.go index 08a1aed9f4..7ecfbabe60 100644 --- a/pkg/hostman/guestfs/core.go +++ b/pkg/hostman/guestfs/core.go @@ -18,52 +18,15 @@ import ( "fmt" "math/rand" + "github.com/pkg/errors" "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/util/netutils" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" - "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" + fsdriver "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) -type SDeployInfo struct { - publicKey *sshkeys.SSHKeys - deploys []jsonutils.JSONObject - password string - isInit bool - enableTty bool - defaultRootUser bool - windowsDefaultAdminUser bool - enableCloudInit bool -} - -func NewDeployInfo( - publicKey *sshkeys.SSHKeys, - deploys []jsonutils.JSONObject, - password string, - isInit bool, - enableTty bool, - defaultRootUser bool, - windowsDefaultAdminUser bool, - enableCloudInit bool, -) *SDeployInfo { - return &SDeployInfo{ - publicKey: publicKey, - deploys: deploys, - password: password, - isInit: isInit, - enableTty: enableTty, - defaultRootUser: defaultRootUser, - windowsDefaultAdminUser: windowsDefaultAdminUser, - enableCloudInit: enableCloudInit, - } -} - -func (d *SDeployInfo) String() string { - return fmt.Sprintf("deplys: %s, password %s, isInit: %v, enableTty: %v, defaultRootUser: %v, enableCloudInit: %v", - d.deploys, d.password, d.isInit, d.enableTty, d.defaultRootUser, d.enableCloudInit) -} - func DetectRootFs(part fsdriver.IDiskPartition) fsdriver.IRootFsDriver { for _, newDriverFunc := range fsdriver.GetRootfsDrivers() { d := newDriverFunc(part) @@ -91,53 +54,49 @@ func testRootfs(d fsdriver.IRootFsDriver) bool { return true } -func DeployGuestFs( - rootfs fsdriver.IRootFsDriver, - guestDesc *jsonutils.JSONDict, - deployInfo *SDeployInfo, -) (jsonutils.JSONObject, error) { - var ret = jsonutils.NewDict() - var ips = make([]string, 0) - var err error - - hn, _ := guestDesc.GetString("name") - domain, _ := guestDesc.GetString("domain") - gid, _ := guestDesc.GetString("uuid") - nics, _ := guestDesc.GetArray("nics") - - partition := rootfs.GetPartition() - releaseInfo := rootfs.GetReleaseInfo(partition) - +func DoDeployGuestFs(rootfs fsdriver.IRootFsDriver, guestDesc *deployapi.GuestDesc, deployInfo *deployapi.DeployInfo, +) (*deployapi.DeployGuestFsResponse, error) { + var ( + err error + ret = new(deployapi.DeployGuestFsResponse) + ips = make([]string, 0) + hn = guestDesc.Name + domain = guestDesc.Domain + gid = guestDesc.Uuid + nics = guestDesc.Nics + nicsStandby = guestDesc.NicsStandby + partition = rootfs.GetPartition() + releaseInfo = rootfs.GetReleaseInfo(partition) + ) for _, n := range nics { - ip, _ := n.GetString("ip") var addr netutils.IPV4Addr - if addr, err = netutils.NewIPV4Addr(ip); err != nil { + if addr, err = netutils.NewIPV4Addr(n.Ip); err != nil { return nil, fmt.Errorf("Fail to get ip addr from %s: %v", n.String(), err) } if netutils.IsPrivate(addr) { - ips = append(ips, ip) + ips = append(ips, n.Ip) } } if releaseInfo != nil { - ret.Set("distro", jsonutils.NewString(releaseInfo.Distro)) + ret.Distro = releaseInfo.Distro if len(releaseInfo.Version) > 0 { - ret.Set("version", jsonutils.NewString(releaseInfo.Version)) + ret.Version = releaseInfo.Version } if len(releaseInfo.Arch) > 0 { - ret.Set("arch", jsonutils.NewString(releaseInfo.Arch)) + ret.Arch = releaseInfo.Arch } if len(releaseInfo.Language) > 0 { - ret.Set("language", jsonutils.NewString(releaseInfo.Language)) + ret.Language = releaseInfo.Language } } - ret.Set("os", jsonutils.NewString(rootfs.GetOs())) + ret.Os = rootfs.GetOs() if IsPartitionReadonly(partition) { return ret, nil } - if len(deployInfo.deploys) > 0 { - if err = rootfs.DeployFiles(deployInfo.deploys); err != nil { + if len(deployInfo.Deploys) > 0 { + if err = rootfs.DeployFiles(deployInfo.Deploys); err != nil { return nil, fmt.Errorf("DeployFiles: %v", err) } } @@ -150,7 +109,7 @@ func DeployGuestFs( if err = rootfs.DeployNetworkingScripts(partition, nics); err != nil { return nil, fmt.Errorf("DeployNetworkingScripts: %v", err) } - if nicsStandby, e := guestDesc.GetArray("nics_standby"); e == nil { + if len(nicsStandby) > 0 { if err = rootfs.DeployStandbyNetworkingScripts(partition, nics, nicsStandby); err != nil { return nil, fmt.Errorf("DeployStandbyNetworkingScripts: %v", err) } @@ -158,36 +117,35 @@ func DeployGuestFs( if err = rootfs.DeployUdevSubsystemScripts(partition); err != nil { return nil, fmt.Errorf("DeployUdevSubsystemScripts: %v", err) } - if deployInfo.isInit { - disks, _ := guestDesc.GetArray("disks") - if err = rootfs.DeployFstabScripts(partition, disks); err != nil { + if deployInfo.IsInit { + if err = rootfs.DeployFstabScripts(partition, guestDesc.Disks); err != nil { return nil, fmt.Errorf("DeployFstabScripts: %v", err) } } - if len(deployInfo.password) > 0 { + if len(deployInfo.Password) > 0 { if account := rootfs.GetLoginAccount(partition, - deployInfo.defaultRootUser, deployInfo.windowsDefaultAdminUser); len(account) > 0 { - ret.Set("account", jsonutils.NewString(account)) - if err = rootfs.DeployPublicKey(partition, account, deployInfo.publicKey); err != nil { + deployInfo.DefaultRootUser, deployInfo.WindowsDefaultAdminUser); len(account) > 0 { + if err = rootfs.DeployPublicKey(partition, account, deployInfo.PublicKey); err != nil { return nil, fmt.Errorf("DeployPublicKey: %v", err) } var secret string if secret, err = rootfs.ChangeUserPasswd(partition, account, gid, - deployInfo.publicKey.PublicKey, deployInfo.password); err != nil { + deployInfo.PublicKey.PublicKey, deployInfo.Password); err != nil { return nil, fmt.Errorf("ChangeUserPasswd: %v", err) } + ret.Account = account if len(secret) > 0 { - ret.Set("key", jsonutils.NewString(secret)) + ret.Key = secret } } } - if err = rootfs.DeployYunionroot(partition, deployInfo.publicKey, deployInfo.isInit, deployInfo.enableCloudInit); err != nil { + if err = rootfs.DeployYunionroot(partition, deployInfo.PublicKey, deployInfo.IsInit, deployInfo.EnableCloudInit); err != nil { return nil, fmt.Errorf("DeployYunionroot: %v", err) } if partition.SupportSerialPorts() { - if deployInfo.enableTty { - if err = rootfs.EnableSerialConsole(partition, ret); err != nil { + if deployInfo.EnableTty { + if err = rootfs.EnableSerialConsole(partition, nil); err != nil { return nil, fmt.Errorf("EnableSerialConsole: %v", err) } } else { @@ -200,10 +158,26 @@ func DeployGuestFs( return nil, fmt.Errorf("CommitChanges: %v", err) } - log.Debugf("Deploy finished, return: %s", ret.String()) + log.Infof("Deploy finished, return: %s", ret.String()) return ret, nil } +func DeployGuestFs( + rootfs fsdriver.IRootFsDriver, + guestDesc *jsonutils.JSONDict, + deployInfo *deployapi.DeployInfo, +) (jsonutils.JSONObject, error) { + desc, err := deployapi.GuestDescToDeployDesc(guestDesc) + if err != nil { + return nil, errors.Wrap(err, "To deploy desc fail") + } + ret, err := DoDeployGuestFs(rootfs, desc, deployInfo) + if err != nil { + return nil, err + } + return jsonutils.Marshal(ret), nil +} + func IsPartitionReadonly(rootfs fsdriver.IDiskPartition) bool { log.Infof("Test if read-only fs ...") var filename = fmt.Sprintf("/.%f", rand.Float32()) diff --git a/pkg/hostman/guestfs/fsdriver/android.go b/pkg/hostman/guestfs/fsdriver/android.go index 4893c80488..7e89a0c80a 100644 --- a/pkg/hostman/guestfs/fsdriver/android.go +++ b/pkg/hostman/guestfs/fsdriver/android.go @@ -19,9 +19,7 @@ import ( "sort" "strings" - "yunion.io/x/jsonutils" - - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) func ParsePropStr(lines string) map[string]string { @@ -83,7 +81,7 @@ func (m *SAndroidRootFs) GetLoginAccount(rootFs IDiskPartition, defaultRootUser return "" } -func (m *SAndroidRootFs) DeployPublicKey(rootfs IDiskPartition, uname string, pubkeys *sshkeys.SSHKeys) error { +func (m *SAndroidRootFs) DeployPublicKey(rootfs IDiskPartition, uname string, pubkeys *deployapi.SSHKeys) error { return nil } @@ -103,14 +101,14 @@ func (m *SAndroidRootFs) GetOs() string { return "Android" } -func (m *SAndroidRootFs) GetReleaseInfo(IDiskPartition) *SReleaseInfo { +func (m *SAndroidRootFs) GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo { spath := "/android-*/system/build.prop" lines, _ := m.rootFs.FileGetContents(spath, false) prop := ParsePropStr(string(lines)) distro, _ := prop["ro.product.model"] version, _ := prop["ro.build.version.release"] arch, _ := prop["ro.product.cpu.abi"] - return &SReleaseInfo{ + return &deployapi.ReleaseInfo{ Distro: distro, Version: version, Arch: arch, @@ -121,7 +119,7 @@ func (m *SAndroidRootFs) PrepareFsForTemplate(IDiskPartition) error { return nil } -func (m *SAndroidRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []jsonutils.JSONObject) error { +func (m *SAndroidRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []*deployapi.Nic) error { return nil } diff --git a/pkg/hostman/guestfs/fsdriver/base.go b/pkg/hostman/guestfs/fsdriver/base.go index 8b536c96f6..f5ab5e59c4 100644 --- a/pkg/hostman/guestfs/fsdriver/base.go +++ b/pkg/hostman/guestfs/fsdriver/base.go @@ -24,7 +24,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) type sGuestRootFsDriver struct { @@ -37,19 +37,17 @@ func newGuestRootFsDriver(rootFs IDiskPartition) *sGuestRootFsDriver { } } -func (d *sGuestRootFsDriver) DeployFiles(deploys []jsonutils.JSONObject) error { +func (d *sGuestRootFsDriver) DeployFiles(deploys []*deployapi.DeployContent) error { caseInsensitive := d.IsFsCaseInsensitive() for _, deploy := range deploys { var modAppend = false - if action, _ := deploy.GetString("action"); action == "append" { + if deploy.Action == "append" { modAppend = true } - sPath, err := deploy.GetString("path") - if err != nil { - log.Errorln(err) - return err + if len(deploy.Path) == 0 { + return fmt.Errorf("Deploy file missing param path") } - dirname := filepath.Dir(sPath) + dirname := filepath.Dir(deploy.Path) if !d.GetPartition().Exists(dirname, caseInsensitive) { modeRWXOwner := syscall.S_IRUSR | syscall.S_IWUSR | syscall.S_IXUSR err := d.GetPartition().Mkdir(dirname, modeRWXOwner, caseInsensitive) @@ -58,8 +56,8 @@ func (d *sGuestRootFsDriver) DeployFiles(deploys []jsonutils.JSONObject) error { return err } } - if content, err := deploy.GetString("content"); err == nil { - err := d.GetPartition().FilePutContents(sPath, content, modAppend, caseInsensitive) + if len(deploy.Content) > 0 { + err := d.GetPartition().FilePutContents(deploy.Path, deploy.Content, modAppend, caseInsensitive) if err != nil { log.Errorln(err) return err @@ -81,7 +79,7 @@ func (d *sGuestRootFsDriver) IsFsCaseInsensitive() bool { return false } -func (d *sGuestRootFsDriver) DeployYunionroot(rootfs IDiskPartition, pubkeys *sshkeys.SSHKeys, isInit, enableCloudInit bool) error { +func (d *sGuestRootFsDriver) DeployYunionroot(rootfs IDiskPartition, pubkeys *deployapi.SSHKeys, isInit, enableCloudInit bool) error { return nil } @@ -89,11 +87,11 @@ func (d *sGuestRootFsDriver) DeployUdevSubsystemScripts(rootfs IDiskPartition) e return nil } -func (d *sGuestRootFsDriver) DeployStandbyNetworkingScripts(part IDiskPartition, nics, nicsStandby []jsonutils.JSONObject) error { +func (d *sGuestRootFsDriver) DeployStandbyNetworkingScripts(part IDiskPartition, nics, nicsStandby []*deployapi.Nic) error { return nil } -func (d *sGuestRootFsDriver) DeployFstabScripts(_ IDiskPartition, _ []jsonutils.JSONObject) error { +func (d *sGuestRootFsDriver) DeployFstabScripts(_ IDiskPartition, _ []*deployapi.Disk) error { return nil } @@ -117,22 +115,7 @@ func (l *sGuestRootFsDriver) IsCloudinitInstall() bool { return false } -type SReleaseInfo struct { - Distro string `json:"os_distribution,omitempty"` - Version string `json:"os_version,omitempty"` - Arch string `json:"os_arch,omitempty"` - Language string `json:"os_language,omitempty"` -} - -func newReleaseInfo(distro, version, arch string) *SReleaseInfo { - return &SReleaseInfo{ - Distro: distro, - Version: version, - Arch: arch, - } -} - -func DeployAuthorizedKeys(rootFs IDiskPartition, usrDir string, pubkeys *sshkeys.SSHKeys, replace bool) error { +func DeployAuthorizedKeys(rootFs IDiskPartition, usrDir string, pubkeys *deployapi.SSHKeys, replace bool) error { usrStat := rootFs.Stat(usrDir, false) if usrStat != nil { sshDir := path.Join(usrDir, ".ssh") @@ -171,7 +154,7 @@ func DeployAuthorizedKeys(rootFs IDiskPartition, usrDir string, pubkeys *sshkeys return nil } -func MergeAuthorizedKeys(oldKeys string, pubkeys *sshkeys.SSHKeys) string { +func MergeAuthorizedKeys(oldKeys string, pubkeys *deployapi.SSHKeys) string { var allkeys = make(map[string]string) if len(oldKeys) > 0 { for _, line := range strings.Split(oldKeys, "\n") { diff --git a/pkg/hostman/guestfs/fsdriver/base_test.go b/pkg/hostman/guestfs/fsdriver/base_test.go index 19ebe9ee6d..52c717739e 100644 --- a/pkg/hostman/guestfs/fsdriver/base_test.go +++ b/pkg/hostman/guestfs/fsdriver/base_test.go @@ -17,13 +17,13 @@ package fsdriver import ( "testing" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) func TestMergeAuthorizedKeys(t *testing.T) { type args struct { oldKeys string - pubkeys *sshkeys.SSHKeys + pubkeys *deployapi.SSHKeys } tests := []struct { name string @@ -34,7 +34,7 @@ func TestMergeAuthorizedKeys(t *testing.T) { name: "MergeAuthorizedKeys", args: args{ oldKeys: "Test KEY", - pubkeys: &sshkeys.SSHKeys{}, + pubkeys: &deployapi.SSHKeys{}, }, want: "Test KEY\n", }, diff --git a/pkg/hostman/guestfs/fsdriver/drivers.go b/pkg/hostman/guestfs/fsdriver/drivers.go index 0d7612125f..ad83b808ff 100644 --- a/pkg/hostman/guestfs/fsdriver/drivers.go +++ b/pkg/hostman/guestfs/fsdriver/drivers.go @@ -16,13 +16,18 @@ package fsdriver type newRootFsDriverFunc func(part IDiskPartition) IRootFsDriver -var rootfsDrivers = make([]newRootFsDriverFunc, 0) +var ( + privatePrefixes []string + rootfsDrivers = make([]newRootFsDriverFunc, 0) +) func GetRootfsDrivers() []newRootFsDriverFunc { return rootfsDrivers } -func init() { +func Init(initPrivatePrefixes []string) { + privatePrefixes = make([]string, len(initPrivatePrefixes)) + copy(privatePrefixes, initPrivatePrefixes) linuxFsDrivers := []newRootFsDriverFunc{ NewCentosRootFs, NewFedoraRootFs, NewRhelRootFs, NewDebianRootFs, NewCirrosRootFs, NewCirrosNewRootFs, NewUbuntuRootFs, diff --git a/pkg/hostman/guestfs/fsdriver/esxi.go b/pkg/hostman/guestfs/fsdriver/esxi.go index 0921dfb3cc..f7f023637a 100644 --- a/pkg/hostman/guestfs/fsdriver/esxi.go +++ b/pkg/hostman/guestfs/fsdriver/esxi.go @@ -15,10 +15,9 @@ package fsdriver import ( - "yunion.io/x/jsonutils" "yunion.io/x/pkg/utils" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) type SEsxiRootFs struct { @@ -67,19 +66,19 @@ func (m *SEsxiRootFs) DeployHosts(part IDiskPartition, hn, domain string, ips [] return nil } -func (m *SEsxiRootFs) GetReleaseInfo(IDiskPartition) *SReleaseInfo { +func (m *SEsxiRootFs) GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo { spath := "/boot.cfg" lines, _ := m.rootFs.FileGetContents(spath, false) prop := ParsePropStr(string(lines)) version, _ := prop["build"] - return &SReleaseInfo{ + return &deployapi.ReleaseInfo{ Distro: "ESXi", Version: version, Arch: "x86_64", } } -func (m *SEsxiRootFs) DeployPublicKey(rootfs IDiskPartition, uname string, pubkeys *sshkeys.SSHKeys) error { +func (m *SEsxiRootFs) DeployPublicKey(rootfs IDiskPartition, uname string, pubkeys *deployapi.SSHKeys) error { return nil } @@ -87,6 +86,6 @@ func (m *SEsxiRootFs) PrepareFsForTemplate(IDiskPartition) error { return nil } -func (m *SEsxiRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []jsonutils.JSONObject) error { +func (m *SEsxiRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []*deployapi.Nic) error { return nil } diff --git a/pkg/hostman/guestfs/fsdriver/interface.go b/pkg/hostman/guestfs/fsdriver/interface.go index 4c606ad51f..d97d7f1ef8 100644 --- a/pkg/hostman/guestfs/fsdriver/interface.go +++ b/pkg/hostman/guestfs/fsdriver/interface.go @@ -19,7 +19,7 @@ import ( "yunion.io/x/jsonutils" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) type IDiskPartition interface { @@ -61,22 +61,22 @@ type IRootFsDriver interface { IsFsCaseInsensitive() bool RootSignatures() []string RootExcludeSignatures() []string - GetReleaseInfo(IDiskPartition) *SReleaseInfo + GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo GetOs() string DeployHostname(part IDiskPartition, hn, domain string) error DeployHosts(part IDiskPartition, hn, domain string, ips []string) error - DeployNetworkingScripts(IDiskPartition, []jsonutils.JSONObject) error - DeployStandbyNetworkingScripts(part IDiskPartition, nics, nicsStandby []jsonutils.JSONObject) error + DeployNetworkingScripts(IDiskPartition, []*deployapi.Nic) error + DeployStandbyNetworkingScripts(part IDiskPartition, nics, nicsStandby []*deployapi.Nic) error DeployUdevSubsystemScripts(IDiskPartition) error - DeployFstabScripts(IDiskPartition, []jsonutils.JSONObject) error + DeployFstabScripts(IDiskPartition, []*deployapi.Disk) error GetLoginAccount(IDiskPartition, bool, bool) string - DeployPublicKey(IDiskPartition, string, *sshkeys.SSHKeys) error + DeployPublicKey(IDiskPartition, string, *deployapi.SSHKeys) error ChangeUserPasswd(part IDiskPartition, account, gid, publicKey, password string) (string, error) - DeployYunionroot(rootFs IDiskPartition, pubkeys *sshkeys.SSHKeys, isInit bool, enableCloudInit bool) error + DeployYunionroot(rootFs IDiskPartition, pubkeys *deployapi.SSHKeys, isInit bool, enableCloudInit bool) error EnableSerialConsole(IDiskPartition, *jsonutils.JSONDict) error DisableSerialConsole(IDiskPartition) error CommitChanges(IDiskPartition) error - DeployFiles(deploys []jsonutils.JSONObject) error + DeployFiles(deploys []*deployapi.DeployContent) error DetectIsUEFISupport(IDiskPartition) bool IsCloudinitInstall() bool diff --git a/pkg/hostman/guestfs/fsdriver/linux.go b/pkg/hostman/guestfs/fsdriver/linux.go index 0e9f3dc603..7bbb87213d 100644 --- a/pkg/hostman/guestfs/fsdriver/linux.go +++ b/pkg/hostman/guestfs/fsdriver/linux.go @@ -30,9 +30,8 @@ import ( "yunion.io/x/pkg/util/netutils" "yunion.io/x/pkg/utils" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" "yunion.io/x/onecloud/pkg/cloudcommon/types" - "yunion.io/x/onecloud/pkg/hostman/options" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/util/coreosutils" "yunion.io/x/onecloud/pkg/util/fileutils2" "yunion.io/x/onecloud/pkg/util/fstabutils" @@ -117,7 +116,7 @@ func (l *sLinuxRootFs) ChangeUserPasswd(rootFs IDiskPartition, account, gid, pub return secret, err } -func (l *sLinuxRootFs) DeployPublicKey(rootFs IDiskPartition, selUsr string, pubkeys *sshkeys.SSHKeys) error { +func (l *sLinuxRootFs) DeployPublicKey(rootFs IDiskPartition, selUsr string, pubkeys *deployapi.SSHKeys) error { var usrDir string if selUsr == "root" { usrDir = "/root" @@ -127,7 +126,7 @@ func (l *sLinuxRootFs) DeployPublicKey(rootFs IDiskPartition, selUsr string, pub return DeployAuthorizedKeys(rootFs, usrDir, pubkeys, false) } -func (l *sLinuxRootFs) DeployYunionroot(rootFs IDiskPartition, pubkeys *sshkeys.SSHKeys, isInit, enableCloudInit bool) error { +func (l *sLinuxRootFs) DeployYunionroot(rootFs IDiskPartition, pubkeys *deployapi.SSHKeys, isInit, enableCloudInit bool) error { l.DisableSelinux(rootFs) if !enableCloudInit && isInit { l.DisableCloudinit(rootFs) @@ -191,7 +190,7 @@ func (l *sLinuxRootFs) DisableCloudinit(rootFs IDiskPartition) { } } -func (l *sLinuxRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []jsonutils.JSONObject) error { +func (l *sLinuxRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []*deployapi.Disk) error { fstabcont, err := rootFs.FileGetContents("/etc/fstab", false) if err != nil { return err @@ -203,18 +202,18 @@ func (l *sLinuxRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []jsonuti fstab.RemoveDevices(len(disks)) for i := 1; i < len(disks); i++ { - diskId, err := disks[i].GetString("disk_id") - if err != nil { + diskId := disks[i].DiskId + if len(diskId) == 0 { diskId = "None" } dev := fmt.Sprintf("UUID=%s", diskId) if !fstab.IsExists(dev) { - fs, _ := disks[i].GetString("fs") + fs := disks[i].Fs if len(fs) > 0 { if fs == "swap" { rec = fmt.Sprintf("%s none %s sw 0 0", dev, fs) } else { - mtPath, _ := disks[i].GetString("mountpoint") + mtPath := disks[i].Mountpoint if len(mtPath) == 0 { mtPath = "/data" if dataDiskIdx > 0 { @@ -237,7 +236,7 @@ func (l *sLinuxRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []jsonuti return rootFs.FilePutContents("/etc/fstab", cf, false, false) } -func (l *sLinuxRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (l *sLinuxRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { udevPath := "/etc/udev/rules.d/" if rootFs.Exists(udevPath, false) { rules := rootFs.ListDir(udevPath, false) @@ -254,9 +253,9 @@ func (l *sLinuxRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jso for _, nic := range nics { nicRules += `KERNEL=="*", SUBSYSTEM=="net", ACTION=="add", ` nicRules += `DRIVERS=="?*", ` - mac, _ := nic.GetString("mac") + mac := nic.Mac nicRules += fmt.Sprintf(`ATTR{address}=="%s", ATTR{type}=="1", `, strings.ToLower(mac)) - idx, _ := nic.Int("index") + idx := nic.Index nicRules += fmt.Sprintf("NAME=\"eth%d\"\n", idx) } if err := rootFs.FilePutContents(path.Join(udevPath, "70-persistent-net.rules"), nicRules, false, false); err != nil { @@ -274,17 +273,16 @@ func (l *sLinuxRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jso return nil } -func (l *sLinuxRootFs) DeployStandbyNetworkingScripts(rootFs IDiskPartition, nics, nicsStandby []jsonutils.JSONObject) error { +func (l *sLinuxRootFs) DeployStandbyNetworkingScripts(rootFs IDiskPartition, nics, nicsStandby []*deployapi.Nic) error { var udevPath = "/etc/udev/rules.d/" var nicRules string for _, nic := range nicsStandby { - nicType, _ := nic.GetString("nic_type") - if !nic.Contains("nic_type") || nicType != "impi" { + if len(nic.NicType) == 0 || nic.NicType != "impi" { nicRules += `KERNEL=="*", SUBSYSTEM=="net", ACTION=="add", ` nicRules += `DRIVERS=="?*", ` - mac, _ := nic.GetString("mac") + mac := nic.Mac nicRules += fmt.Sprintf(`ATTR{address}=="%s", ATTR{type}=="1", `, strings.ToLower(mac)) - idx, _ := nic.Int("index") + idx := nic.Index nicRules += fmt.Sprintf("NAME=\"eth%d\"\n", idx) } } @@ -474,14 +472,14 @@ func newDebianLikeRootFs(part IDiskPartition) *sDebianLikeRootFs { } } -func (d *sDebianLikeRootFs) GetReleaseInfo(rootFs IDiskPartition, driver IDebianRootFsDriver) *SReleaseInfo { +func (d *sDebianLikeRootFs) GetReleaseInfo(rootFs IDiskPartition, driver IDebianRootFsDriver) *deployapi.ReleaseInfo { version, err := rootFs.FileGetContents(driver.VersionFilePath(), false) if err != nil { log.Errorf("Get %s error: %v", driver.VersionFilePath(), err) return nil } versionStr := strings.TrimSpace(string(version)) - return &SReleaseInfo{ + return &deployapi.ReleaseInfo{ Distro: driver.DistroName(), Version: versionStr, Arch: d.GetArch(rootFs), @@ -512,7 +510,7 @@ func getNicTeamingConfigCmds(slaves []*types.SServerNic) string { return cmds.String() } -func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { if err := d.sLinuxRootFs.DeployNetworkingScripts(rootFs, nics); err != nil { return err } @@ -521,7 +519,7 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics cmds.WriteString("auto lo\n") cmds.WriteString("iface lo inet loopback\n\n") - allNics, _ := convertNicConfigs(nics) + allNics, _ := convertNicConfigs(ToServerNics(nics)) mainNic, err := getMainNic(allNics) if err != nil { return err @@ -543,7 +541,7 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics cmds.WriteString(" netmask 255.255.255.255\n") cmds.WriteString("\n") } else if nicDesc.Manual { - netmask := netutils2.Netlen2Mask(nicDesc.Masklen) + netmask := netutils2.Netlen2Mask(int(nicDesc.Masklen)) cmds.WriteString(fmt.Sprintf("iface %s inet static\n", nicDesc.Name)) cmds.WriteString(fmt.Sprintf(" address %s\n", nicDesc.Ip)) cmds.WriteString(fmt.Sprintf(" netmask %s\n", netmask)) @@ -551,7 +549,7 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics cmds.WriteString(fmt.Sprintf(" gateway %s\n", nicDesc.Gateway)) } var routes = make([][]string, 0) - netutils2.AddNicRoutes(&routes, nicDesc, mainIp, len(nics), options.HostOptions.PrivatePrefixes) + netutils2.AddNicRoutes(&routes, nicDesc, mainIp, len(nics), privatePrefixes) for _, r := range routes { cmds.WriteString(fmt.Sprintf(" up route add -net %s gw %s || true\n", r[0], r[1])) cmds.WriteString(fmt.Sprintf(" down route del -net %s gw %s || true\n", r[0], r[1])) @@ -615,7 +613,7 @@ func (d *SDebianRootFs) RootExcludeSignatures() []string { return []string{"/etc/lsb-release"} } -func (d *SDebianRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (d *SDebianRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { return d.sDebianLikeRootFs.GetReleaseInfo(rootFs, d) } @@ -645,7 +643,7 @@ func (d *SCirrosRootFs) VersionFilePath() string { return "/etc/br-version" } -func (d *SCirrosRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (d *SCirrosRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { return d.SDebianRootFs.sDebianLikeRootFs.GetReleaseInfo(rootFs, d) } @@ -683,7 +681,7 @@ func (d *SCirrosNewRootFs) RootSignatures() []string { return d.rootSignatures(d) } -func (d *SCirrosNewRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (d *SCirrosNewRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { return d.SDebianRootFs.sDebianLikeRootFs.GetReleaseInfo(rootFs, d) } @@ -710,7 +708,7 @@ func (d *SUbuntuRootFs) String() string { return "UbuntuRootFs" } -func (d *SUbuntuRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (d *SUbuntuRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { distroKey := "DISTRIB_RELEASE=" rel, err := rootFs.FileGetContents("/etc/lsb-release", false) if err != nil { @@ -724,7 +722,7 @@ func (d *SUbuntuRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { version = strings.TrimSpace(l[len(distroKey) : len(l)-1]) } } - return newReleaseInfo(d.GetName(), version, d.GetArch(rootFs)) + return deployapi.NewReleaseInfo(d.GetName(), version, d.GetArch(rootFs)) } func (d *SUbuntuRootFs) EnableSerialConsole(rootFs IDiskPartition, sysInfo *jsonutils.JSONDict) error { @@ -778,18 +776,14 @@ func (r *sRedhatLikeRootFs) DeployHostname(rootFs IDiskPartition, hn, domain str return nil } -func (r *sRedhatLikeRootFs) Centos5DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (r *sRedhatLikeRootFs) Centos5DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { var udevPath = "/etc/udev/rules.d/" if rootFs.Exists(udevPath, false) { var nicRules = "" for _, nic := range nics { - var nicdesc = new(types.SServerNic) - if err := nic.Unmarshal(nicdesc); err != nil { - return err - } nicRules += `KERNEL=="*", ` - nicRules += fmt.Sprintf(`SYSFS{address}=="%s", `, strings.ToLower(nicdesc.Mac)) - nicRules += fmt.Sprintf("NAME=\"eth%d\"\n", nicdesc.Index) + nicRules += fmt.Sprintf(`SYSFS{address}=="%s", `, strings.ToLower(nic.Mac)) + nicRules += fmt.Sprintf("NAME=\"eth%d\"\n", nic.Index) } return rootFs.FilePutContents(path.Join(udevPath, "60-net.rules"), nicRules, false, false) @@ -830,7 +824,7 @@ func (r *sRedhatLikeRootFs) enableBondingModule(rootFs IDiskPartition, bondNics return rootFs.FilePutContents("/etc/modprobe.d/bonding.conf", content.String(), false, false) } -func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject, relInfo *SReleaseInfo) error { +func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic, relInfo *deployapi.ReleaseInfo) error { if err := r.sLinuxRootFs.DeployNetworkingScripts(rootFs, nics); err != nil { return err } @@ -848,7 +842,7 @@ func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics if err != nil { return err } - allNics, bondNics := convertNicConfigs(nics) + allNics, bondNics := convertNicConfigs(ToServerNics(nics)) if len(bondNics) > 0 { err = r.enableBondingModule(rootFs, bondNics) if err != nil { @@ -896,7 +890,7 @@ func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics cmds.WriteString(netutils2.PSEUDO_VIP) cmds.WriteString("\n") } else if nicDesc.Manual { - netmask := netutils2.Netlen2Mask(nicDesc.Masklen) + netmask := netutils2.Netlen2Mask(int(nicDesc.Masklen)) cmds.WriteString("BOOTPROTO=none\n") cmds.WriteString("NETMASK=") cmds.WriteString(netmask) @@ -910,7 +904,7 @@ func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics cmds.WriteString("\n") } var routes = make([][]string, 0) - netutils2.AddNicRoutes(&routes, nicDesc, mainIp, len(nics), options.HostOptions.PrivatePrefixes) + netutils2.AddNicRoutes(&routes, nicDesc, mainIp, len(nics), privatePrefixes) var rtbl strings.Builder for _, r := range routes { rtbl.WriteString(r[0]) @@ -946,23 +940,19 @@ func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics return nil } -func (r *sRedhatLikeRootFs) DeployStandbyNetworkingScripts(rootFs IDiskPartition, nics, nicsStandby []jsonutils.JSONObject) error { +func (r *sRedhatLikeRootFs) DeployStandbyNetworkingScripts(rootFs IDiskPartition, nics, nicsStandby []*deployapi.Nic) error { if err := r.sLinuxRootFs.DeployStandbyNetworkingScripts(rootFs, nics, nicsStandby); err != nil { return err } for _, nic := range nicsStandby { var cmds string - var nicdesc = new(types.SServerNic) - if err := nic.Unmarshal(nicdesc); err != nil { - return err - } - if nicType, err := nic.GetString("nic_type"); err != nil && nicType != "ipmi" { - cmds += fmt.Sprintf("DEVICE=eth%d\n", nicdesc.Index) - cmds += fmt.Sprintf("NAME=eth%d\n", nicdesc.Index) - cmds += fmt.Sprintf("HWADDR=%s\n", nicdesc.Mac) - cmds += fmt.Sprintf("MACADDR=%s\n", nicdesc.Mac) + if len(nic.NicType) == 0 || nic.NicType != "ipmi" { + cmds += fmt.Sprintf("DEVICE=eth%d\n", nic.Index) + cmds += fmt.Sprintf("NAME=eth%d\n", nic.Index) + cmds += fmt.Sprintf("HWADDR=%s\n", nic.Mac) + cmds += fmt.Sprintf("MACADDR=%s\n", nic.Mac) cmds += "ONBOOT=no\n" - var fn = fmt.Sprintf("/etc/sysconfig/network-scripts/ifcfg-eth%d", nicdesc.Index) + var fn = fmt.Sprintf("/etc/sysconfig/network-scripts/ifcfg-eth%d", nic.Index) if err := rootFs.FilePutContents(fn, cmds, false, false); err != nil { return err } @@ -1029,7 +1019,7 @@ func (c *SCentosRootFs) RootSignatures() []string { return append([]string{"/etc/centos-release"}, sig...) } -func (c *SCentosRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (c *SCentosRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { rel, _ := rootFs.FileGetContents("/etc/centos-release", false) var version string if len(rel) > 0 { @@ -1042,10 +1032,10 @@ func (c *SCentosRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { } } } - return newReleaseInfo(c.GetName(), version, c.GetArch(rootFs)) + return deployapi.NewReleaseInfo(c.GetName(), version, c.GetArch(rootFs)) } -func (c *SCentosRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (c *SCentosRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { relInfo := c.GetReleaseInfo(rootFs) if err := c.sRedhatLikeRootFs.deployNetworkingScripts(rootFs, nics, relInfo); err != nil { return err @@ -1092,7 +1082,7 @@ func (c *SFedoraRootFs) RootSignatures() []string { return append([]string{"/etc/fedora-release"}, sig...) } -func (c *SFedoraRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (c *SFedoraRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { rel, _ := rootFs.FileGetContents("/etc/fedora-release", false) var version string if len(rel) > 0 { @@ -1105,10 +1095,10 @@ func (c *SFedoraRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { } } } - return newReleaseInfo(c.GetName(), version, c.GetArch(rootFs)) + return deployapi.NewReleaseInfo(c.GetName(), version, c.GetArch(rootFs)) } -func (c *SFedoraRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (c *SFedoraRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { relInfo := c.GetReleaseInfo(rootFs) if err := c.sRedhatLikeRootFs.deployNetworkingScripts(rootFs, nics, relInfo); err != nil { return err @@ -1140,7 +1130,7 @@ func (d *SRhelRootFs) String() string { return "RhelRootFs" } -func (d *SRhelRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (d *SRhelRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { rel, _ := rootFs.FileGetContents("/etc/redhat-release", false) var version string if len(rel) > 0 { @@ -1149,10 +1139,10 @@ func (d *SRhelRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { version = dat[6] } } - return newReleaseInfo(d.GetName(), version, d.GetArch(rootFs)) + return deployapi.NewReleaseInfo(d.GetName(), version, d.GetArch(rootFs)) } -func (d *SRhelRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (d *SRhelRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { relInfo := d.GetReleaseInfo(rootFs) if err := d.sRedhatLikeRootFs.deployNetworkingScripts(rootFs, nics, relInfo); err != nil { return err @@ -1199,7 +1189,7 @@ func (d *SGentooRootFs) DeployHostname(rootFs IDiskPartition, hn, domain string) return rootFs.FilePutContents(spath, content, false, false) } -func (l *SGentooRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (l *SGentooRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { if err := l.sLinuxRootFs.DeployNetworkingScripts(rootFs, nics); err != nil { return err } @@ -1210,8 +1200,8 @@ func (l *SGentooRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []js ) for _, nic := range nics { - nicIndex, _ := nic.Int("index") - if jsonutils.QueryBoolean(nic, "virtual", false) { + nicIndex := nic.Index + if nic.Virtual { cmds += fmt.Sprintf(`config_eth%d="`, nicIndex) cmds += fmt.Sprintf("%s netmask 255.255.255.255", netutils2.PSEUDO_VIP) cmds += `"\n` @@ -1223,7 +1213,7 @@ func (l *SGentooRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []js return err } for _, nic := range nics { - nicIndex, _ := nic.Int("index") + nicIndex := nic.Index netname := fmt.Sprintf("net.eth%d", nicIndex) procutils.NewCommand("ln", "-s", "net.lo", fmt.Sprintf("%s/etc/init.d/%s", rootFs.GetMountPath(), netname)).Run() @@ -1233,8 +1223,8 @@ func (l *SGentooRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []js return nil } -func (d *SGentooRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { - return &SReleaseInfo{ +func (d *SGentooRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { + return &deployapi.ReleaseInfo{ Distro: "Gentoo", Arch: d.GetArch(rootFs), } @@ -1269,8 +1259,8 @@ func (d *SArchLinuxRootFs) DeployHostname(rootFs IDiskPartition, hn, domain stri return rootFs.FilePutContents("/etc/hostname", hn, false, false) } -func (d *SArchLinuxRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { - return &SReleaseInfo{ +func (d *SArchLinuxRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { + return &deployapi.ReleaseInfo{ Distro: "ArchLinux", Arch: d.GetArch(rootFs), } @@ -1308,9 +1298,9 @@ func (d *SOpenWrtRootFs) DeployHostname(rootFs IDiskPartition, hn, domain string return rootFs.FilePutContents(spath, cont, false, false) } -func (d *SOpenWrtRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { +func (d *SOpenWrtRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { ver, _ := rootFs.FileGetContents("/etc/openwrt_version", false) - return &SReleaseInfo{ + return &deployapi.ReleaseInfo{ Distro: "OpenWRT", Version: string(ver), Arch: d.GetArch(rootFs), @@ -1338,8 +1328,8 @@ func (d *SCoreOsRootFs) GetOs() string { return "Linux" } -func (d *SCoreOsRootFs) GetReleaseInfo(rootFs IDiskPartition) *SReleaseInfo { - return &SReleaseInfo{ +func (d *SCoreOsRootFs) GetReleaseInfo(rootFs IDiskPartition) *deployapi.ReleaseInfo { + return &deployapi.ReleaseInfo{ Distro: "CoreOS", Version: "stable", } @@ -1367,7 +1357,7 @@ func (d *SCoreOsRootFs) DeployHostname(rootFs IDiskPartition, hn, domain string) return nil } -func (d *SCoreOsRootFs) DeployPublicKey(rootFs IDiskPartition, selUsr string, pubkeys *sshkeys.SSHKeys) error { +func (d *SCoreOsRootFs) DeployPublicKey(rootFs IDiskPartition, selUsr string, pubkeys *deployapi.SSHKeys) error { return nil } @@ -1376,7 +1366,7 @@ func (d *SCoreOsRootFs) DeployHosts(rootFs IDiskPartition, hostname, domain stri return nil } -func (d *SCoreOsRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []jsonutils.JSONObject) error { +func (d *SCoreOsRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*deployapi.Nic) error { cont := "[Match]\n" cont += "Name=eth*\n\n" cont += "[Network]\n" @@ -1386,17 +1376,16 @@ func (d *SCoreOsRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []js return nil } -func (d *SCoreOsRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []jsonutils.JSONObject) error { +func (d *SCoreOsRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []*deployapi.Disk) error { dataDiskIdx := 0 for i := 1; i < len(disks); i++ { - diskId, _ := disks[i].GetString("disk_id") - dev := fmt.Sprintf("UUID=%s", diskId) - fs, _ := disks[i].GetString("fs") + dev := fmt.Sprintf("UUID=%s", disks[i].DiskId) + fs := disks[i].Fs if len(fs) > 0 { if fs == "swap" { d.GetConfig().AddSwap(dev) } else { - mtPath, _ := disks[i].GetString("mountpoint") + mtPath := disks[i].Mountpoint if len(mtPath) == 0 { mtPath = "/data" if dataDiskIdx > 0 { @@ -1428,11 +1417,9 @@ func (d *SCoreOsRootFs) GetLoginAccount(rootFs IDiskPartition, defaultRootUser b return "core" } -func (d *SCoreOsRootFs) DeployFiles(deploys []jsonutils.JSONObject) error { +func (d *SCoreOsRootFs) DeployFiles(deploys []*deployapi.DeployContent) error { for _, deploy := range deploys { - spath, _ := deploy.GetString("path") - content, _ := deploy.GetString("content") - d.GetConfig().AddWriteFile(spath, content, "", "", false) + d.GetConfig().AddWriteFile(deploy.Path, deploy.Content, "", "", false) } return nil } diff --git a/pkg/hostman/guestfs/fsdriver/macos.go b/pkg/hostman/guestfs/fsdriver/macos.go index d6ac51bf0a..759aab420b 100644 --- a/pkg/hostman/guestfs/fsdriver/macos.go +++ b/pkg/hostman/guestfs/fsdriver/macos.go @@ -19,10 +19,9 @@ import ( "path" "strings" - "yunion.io/x/jsonutils" "yunion.io/x/pkg/utils" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/util/macutils" "yunion.io/x/onecloud/pkg/util/seclib2" "yunion.io/x/onecloud/pkg/util/stringutils2" @@ -72,7 +71,7 @@ func (m *SMacOSRootFs) RootSignatures() []string { } } -func (m *SMacOSRootFs) DeployPublicKey(rootfs IDiskPartition, uname string, pubkeys *sshkeys.SSHKeys) error { +func (m *SMacOSRootFs) DeployPublicKey(rootfs IDiskPartition, uname string, pubkeys *deployapi.SSHKeys) error { usrDir := fmt.Sprintf("/Users/%s", uname) return DeployAuthorizedKeys(m.rootFs, usrDir, pubkeys, false) } @@ -115,13 +114,13 @@ func (m *SMacOSRootFs) DeployHosts(part IDiskPartition, hn, domain string, ips [ return nil } -func (m *SMacOSRootFs) GetReleaseInfo(IDiskPartition) *SReleaseInfo { +func (m *SMacOSRootFs) GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo { spath := "/System/Library/CoreServices/SystemVersion.plist" sInfo, _ := m.rootFs.FileGetContents(spath, false) info := macutils.ParsePlist(sInfo) distro, _ := info["ProductName"] version, _ := info["ProductUserVisibleVersion"] - return &SReleaseInfo{ + return &deployapi.ReleaseInfo{ Distro: distro, Version: version, Arch: "x86_64", @@ -132,7 +131,7 @@ func (m *SMacOSRootFs) GetOs() string { return "macOs" } -func (m *SMacOSRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []jsonutils.JSONObject) error { +func (m *SMacOSRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []*deployapi.Nic) error { return nil } diff --git a/pkg/hostman/guestfs/fsdriver/nicteaming.go b/pkg/hostman/guestfs/fsdriver/nicteaming.go index 2dbcaf50a0..818906bd3c 100644 --- a/pkg/hostman/guestfs/fsdriver/nicteaming.go +++ b/pkg/hostman/guestfs/fsdriver/nicteaming.go @@ -20,6 +20,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudcommon/types" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" ) func unmarshalNicConfigs(jsonNics []jsonutils.JSONObject) []types.SServerNic { @@ -33,18 +34,24 @@ func unmarshalNicConfigs(jsonNics []jsonutils.JSONObject) []types.SServerNic { return nics } -func findTeamingNic(nics []types.SServerNic, mac string) *types.SServerNic { +func findTeamingNic(nics []*types.SServerNic, mac string) *types.SServerNic { for i := range nics { if nics[i].TeamWith == mac { - return &nics[i] + return nics[i] } } return nil } -func convertNicConfigs(jsonNics []jsonutils.JSONObject) ([]*types.SServerNic, []*types.SServerNic) { - nics := unmarshalNicConfigs(jsonNics) +func ToServerNics(nics []*deployapi.Nic) []*types.SServerNic { + ret := make([]*types.SServerNic, len(nics)) + for i := 0; i < len(nics); i++ { + ret[i] = &types.SServerNic{Nic: nics[i]} + } + return ret +} +func convertNicConfigs(nics []*types.SServerNic) ([]*types.SServerNic, []*types.SServerNic) { allNics := make([]*types.SServerNic, 0) bondNics := make([]*types.SServerNic, 0) @@ -61,25 +68,25 @@ func convertNicConfigs(jsonNics []jsonutils.JSONObject) ([]*types.SServerNic, [] if teamNic == nil { nnic := nics[i] nnic.Name = fmt.Sprintf("eth%d", nnic.Index) - allNics = append(allNics, &nnic) + allNics = append(allNics, nnic) continue } master := nics[i] nnic := nics[i] tnic := *teamNic nnic.Name = fmt.Sprintf("eth%d", nnic.Index) - nnic.TeamingMaster = &master + nnic.TeamingMaster = master nnic.Ip = "" nnic.Gateway = "" tnic.Name = fmt.Sprintf("eth%d", tnic.Index) - tnic.TeamingMaster = &master + tnic.TeamingMaster = master tnic.Ip = "" tnic.Gateway = "" master.Name = fmt.Sprintf("bond%d", len(bondNics)) - master.TeamingSlaves = []*types.SServerNic{&nnic, &tnic} + master.TeamingSlaves = []*types.SServerNic{nnic, &tnic} master.Mac = "" - allNics = append(allNics, &nnic, &tnic, &master) - bondNics = append(bondNics, &master) + allNics = append(allNics, nnic, &tnic, master) + bondNics = append(bondNics, master) } return allNics, bondNics } diff --git a/pkg/hostman/guestfs/fsdriver/windows.go b/pkg/hostman/guestfs/fsdriver/windows.go index 9b4b714e75..396840d46c 100644 --- a/pkg/hostman/guestfs/fsdriver/windows.go +++ b/pkg/hostman/guestfs/fsdriver/windows.go @@ -22,13 +22,11 @@ import ( "strings" "syscall" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/utils" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" "yunion.io/x/onecloud/pkg/cloudcommon/types" - "yunion.io/x/onecloud/pkg/hostman/options" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/util/fileutils2" "yunion.io/x/onecloud/pkg/util/netutils2" "yunion.io/x/onecloud/pkg/util/seclib2" @@ -76,7 +74,7 @@ func (w *SWindowsRootFs) String() string { return "WindowsRootFs" } -func (w *SWindowsRootFs) DeployPublicKey(IDiskPartition, string, *sshkeys.SSHKeys) error { +func (w *SWindowsRootFs) DeployPublicKey(IDiskPartition, string, *deployapi.SSHKeys) error { return nil } @@ -90,7 +88,7 @@ func (w *SWindowsRootFs) RootSignatures() []string { } } -func (w *SWindowsRootFs) GetReleaseInfo(IDiskPartition) *SReleaseInfo { +func (w *SWindowsRootFs) GetReleaseInfo(IDiskPartition) *deployapi.ReleaseInfo { confPath := w.rootFs.GetLocalPath("/windows/system32/config", true) tool := winutils.NewWinRegTool(confPath) if tool.CheckPath() { @@ -98,7 +96,12 @@ func (w *SWindowsRootFs) GetReleaseInfo(IDiskPartition) *SReleaseInfo { version := tool.GetVersion() arch := tool.GetArch() lan := tool.GetInstallLanguage() - return &SReleaseInfo{distro, version, arch, lan} + return &deployapi.ReleaseInfo{ + Distro: distro, + Version: version, + Arch: arch, + Language: lan, + } } else { return nil } @@ -228,14 +231,14 @@ func (w *SWindowsRootFs) DeployHosts(part IDiskPartition, hn, domain string, ips return w.rootFs.FilePutContents(ETC_HOSTS, hf.String(), false, true) } -func (w *SWindowsRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []jsonutils.JSONObject) error { - mainNic, err := netutils2.GetMainNic(nics) +func (w *SWindowsRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []*deployapi.Nic) error { + mainNic, err := netutils2.GetMainNicFromDeployApi(nics) if err != nil { return err } mainIp := "" if mainNic != nil { - mainIp, _ = mainNic.GetString("ip") + mainIp = mainNic.Ip } bootScript := strings.Join([]string{ `set NETCFG_SCRIPT=%SystemRoot%\netcfg.bat`, @@ -255,24 +258,19 @@ func (w *SWindowsRootFs) DeployNetworkingScripts(rootfs IDiskPartition, nics []j } for _, nic := range nics { - snic := &types.SServerNic{} - if err := nic.Unmarshal(snic); err != nil { - log.Errorln(err) - return err - } - + snic := &types.SServerNic{Nic: nic} mac := snic.Mac mac = strings.Replace(strings.ToUpper(mac), ":", "-", -1) lines = append(lines, fmt.Sprintf(` if "%%%%c" == "%s" (`, mac)) - if jsonutils.QueryBoolean(nic, "manual", false) { - netmask := netutils2.Netlen2Mask(snic.Masklen) + if snic.Manual { + netmask := netutils2.Netlen2Mask(int(snic.Masklen)) cfg := fmt.Sprintf(` netsh interface ip set address "%%%%b" static %s %s`, snic.Ip, netmask) if len(snic.Gateway) > 0 && snic.Ip == mainIp { cfg += fmt.Sprintf(" %s", snic.Gateway) } lines = append(lines, cfg) routes := [][]string{} - netutils2.AddNicRoutes(&routes, snic, mainIp, len(nics), options.HostOptions.PrivatePrefixes) + netutils2.AddNicRoutes(&routes, snic, mainIp, len(nics), privatePrefixes) for _, r := range routes { lines = append(lines, fmt.Sprintf(` netsh interface ip add route %s "%%%%b" %s`, r[0], r[1])) } @@ -449,7 +447,7 @@ func (w *SWindowsRootFs) deploySetupCompleteScripts(uname, passwd string) bool { return true } -func (w *SWindowsRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []jsonutils.JSONObject) error { +func (w *SWindowsRootFs) DeployFstabScripts(rootFs IDiskPartition, disks []*deployapi.Disk) error { if len(disks) == 1 { return nil } diff --git a/pkg/hostman/guestfs/kvmpart.go b/pkg/hostman/guestfs/kvmpart.go index 4812fb3a20..30e3f47a93 100644 --- a/pkg/hostman/guestfs/kvmpart.go +++ b/pkg/hostman/guestfs/kvmpart.go @@ -52,13 +52,11 @@ func NewKVMGuestDiskPartition(devPath, sourceDev string, isLVM bool) *SKVMGuestD func (p *SKVMGuestDiskPartition) GetPhysicalPartitionType() string { dev := p.partDev if p.IsLVMPart { - // for lvm part, sourceDev like /dev/nbdxpx - idx := strings.LastIndexByte(p.sourceDev, 'p') - if idx > 0 { - dev = p.sourceDev[:idx] - } else { - dev = p.sourceDev - } + dev = p.sourceDev + } + idxP := strings.LastIndexByte(dev, 'p') + if idxP > 0 { + dev = dev[:idxP] } cmd := fmt.Sprintf(`fdisk -l %s | grep "Disk label type:"`, dev) output, err := procutils.NewCommand("sh", "-c", cmd).Run() diff --git a/pkg/hostman/guestfs/localfs.go b/pkg/hostman/guestfs/localfs.go index 1489f1dacd..a3b28ae324 100644 --- a/pkg/hostman/guestfs/localfs.go +++ b/pkg/hostman/guestfs/localfs.go @@ -35,6 +35,12 @@ type SLocalGuestFS struct { mountPath string } +func NewLocalGuestFS(mountPath string) *SLocalGuestFS { + var ret = new(SLocalGuestFS) + ret.mountPath = mountPath + return ret +} + func (f *SLocalGuestFS) GetMountPath() string { return f.mountPath } @@ -256,9 +262,3 @@ func (f *SLocalGuestFS) FilePutContents(sPath, content string, modAppend, caseIn return fmt.Errorf("Cann't put content") } } - -func NewLocalGuestFS(mountPath string) *SLocalGuestFS { - var ret = new(SLocalGuestFS) - ret.mountPath = mountPath - return ret -} diff --git a/pkg/hostman/guesthandlers/doc.go b/pkg/hostman/guestman/guesthandlers/doc.go similarity index 96% rename from pkg/hostman/guesthandlers/doc.go rename to pkg/hostman/guestman/guesthandlers/doc.go index 0279fdb51d..ef3e0dcd32 100644 --- a/pkg/hostman/guesthandlers/doc.go +++ b/pkg/hostman/guestman/guesthandlers/doc.go @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -package guesthandlers // import "yunion.io/x/onecloud/pkg/hostman/guesthandlers" +package guesthandlers // import "yunion.io/x/onecloud/pkg/hostman/guestman/guesthandlers" diff --git a/pkg/hostman/guesthandlers/guesthandler.go b/pkg/hostman/guestman/guesthandlers/guesthandler.go similarity index 98% rename from pkg/hostman/guesthandlers/guesthandler.go rename to pkg/hostman/guestman/guesthandlers/guesthandler.go index 86dad1868b..a4e3483994 100644 --- a/pkg/hostman/guesthandlers/guesthandler.go +++ b/pkg/hostman/guestman/guesthandlers/guesthandler.go @@ -452,7 +452,7 @@ func guestReloadDiskSnapshot(ctx context.Context, sid string, body jsonutils.JSO return nil, httperrors.NewNotFoundError("Disk not found") } - hostutils.DelayTaskWithoutReqctx(ctx, guestman.GetGuestManager().ReloadDiskSnapshot, &guestman.SReloadDisk{sid, disk}) + hostutils.DelayTask(ctx, guestman.GetGuestManager().ReloadDiskSnapshot, &guestman.SReloadDisk{sid, disk}) return nil, nil } @@ -519,7 +519,7 @@ func guestDeleteSnapshot(ctx context.Context, sid string, body jsonutils.JSONObj Disk: disk, } - if !jsonutils.QueryBoolean(body, "auto_delete", false) { + if !jsonutils.QueryBoolean(body, "auto_deleted", false) { convertSnapshot, err := body.GetString("convert_snapshot") if err != nil { return nil, httperrors.NewMissingParameterError("convert_snapshot") diff --git a/pkg/hostman/guestman/guestman.go b/pkg/hostman/guestman/guestman.go index 7be2b23caa..b4bbd401a6 100644 --- a/pkg/hostman/guestman/guestman.go +++ b/pkg/hostman/guestman/guestman.go @@ -25,24 +25,24 @@ import ( "sync" "time" + "github.com/pkg/errors" "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/util/regutils" - "yunion.io/x/onecloud/pkg/apis/compute" - "yunion.io/x/onecloud/pkg/appsrv" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" - "yunion.io/x/onecloud/pkg/hostman/guestfs" - "yunion.io/x/onecloud/pkg/hostman/hostutils" - "yunion.io/x/onecloud/pkg/hostman/options" - "yunion.io/x/onecloud/pkg/hostman/storageman" - "yunion.io/x/onecloud/pkg/httperrors" - "yunion.io/x/onecloud/pkg/mcclient/modules" - "yunion.io/x/onecloud/pkg/util/cgrouputils" - "yunion.io/x/onecloud/pkg/util/fileutils2" - "yunion.io/x/onecloud/pkg/util/netutils2" - "yunion.io/x/onecloud/pkg/util/seclib2" - "yunion.io/x/onecloud/pkg/util/timeutils2" + compute "yunion.io/x/onecloud/pkg/apis/compute" + appsrv "yunion.io/x/onecloud/pkg/appsrv" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" + hostutils "yunion.io/x/onecloud/pkg/hostman/hostutils" + options "yunion.io/x/onecloud/pkg/hostman/options" + storageman "yunion.io/x/onecloud/pkg/hostman/storageman" + httperrors "yunion.io/x/onecloud/pkg/httperrors" + modules "yunion.io/x/onecloud/pkg/mcclient/modules" + cgrouputils "yunion.io/x/onecloud/pkg/util/cgrouputils" + fileutils2 "yunion.io/x/onecloud/pkg/util/fileutils2" + netutils2 "yunion.io/x/onecloud/pkg/util/netutils2" + seclib2 "yunion.io/x/onecloud/pkg/util/seclib2" + timeutils2 "yunion.io/x/onecloud/pkg/util/timeutils2" ) const ( @@ -323,7 +323,7 @@ func (m *SGuestManager) GuestDeploy(ctx context.Context, params interface{}) (js if jsonutils.QueryBoolean(deployParams.Body, "k8s_pod", false) { return nil, nil } - publicKey := sshkeys.GetKeys(deployParams.Body) + publicKey := deployapi.GetKeys(deployParams.Body) deploys, _ := deployParams.Body.GetArray("deploys") password, _ := deployParams.Body.GetString("password") resetPassword := jsonutils.QueryBoolean(deployParams.Body, "reset_password", false) @@ -332,12 +332,11 @@ func (m *SGuestManager) GuestDeploy(ctx context.Context, params interface{}) (js } enableCloudInit := jsonutils.QueryBoolean(deployParams.Body, "enable_cloud_init", false) - guestInfo, err := guest.DeployFs(guestfs.NewDeployInfo( - publicKey, deploys, password, deployParams.IsInit, false, + guestInfo, err := guest.DeployFs(deployapi.NewDeployInfo( + publicKey, deployapi.JsonDeploysToStructs(deploys), password, deployParams.IsInit, false, options.HostOptions.LinuxDefaultRootUser, options.HostOptions.WindowsDefaultAdminUser, enableCloudInit)) if err != nil { - log.Errorf("Deploy guest fs error: %s", err) - return nil, err + return nil, errors.Wrap(err, "Deploy guest fs") } else { return guestInfo, nil } diff --git a/pkg/hostman/guestman/guesttasks.go b/pkg/hostman/guestman/guesttasks.go index d20823a024..4aa33feaa3 100644 --- a/pkg/hostman/guestman/guesttasks.go +++ b/pkg/hostman/guestman/guesttasks.go @@ -587,8 +587,8 @@ func (s *SGuestStreamDisksTask) onBlockDrivesSucc(res *jsonutils.JSONArray) { if len(s.streamDevs) == 0 { s.taskComplete() } else { - s.SyncStatus() s.startDoBlockStream() + s.SyncStatus() } } @@ -679,8 +679,11 @@ func (s *SGuestReloadDiskTask) WaitSnapshotReplaced(callback func()) error { return fmt.Errorf( "SnapshotDeleteJob.deleting_disk_snapshot always has %s", s.disk.GetId()) } - if _, ok := storageman.DELETEING_SNAPSHOTS[s.disk.GetId()]; ok { + + if _, ok := storageman.DELETEING_SNAPSHOTS.Load(s.disk.GetId()); ok { time.Sleep(time.Second * 1) + } else { + break } } @@ -747,7 +750,9 @@ func (s *SGuestReloadDiskTask) onReloadSucc(err string) { func (s *SGuestReloadDiskTask) onResumeSucc(results string) { log.Infof("guest reload disk task resume succ %s", results) - hostutils.TaskComplete(s.ctx, nil) + params := jsonutils.NewDict() + params.Set("reopen", jsonutils.JSONTrue) + hostutils.TaskComplete(s.ctx, params) } func (s *SGuestReloadDiskTask) taskFailed(reason string) { @@ -803,8 +808,7 @@ func (s *SGuestDiskSnapshotTask) onSnapshotBlkdevFail(string) { func (s *SGuestDiskSnapshotTask) onResumeSucc(res string) { log.Infof("guest disk snapshot task resume succ %s", res) - snapshotDir := s.disk.GetSnapshotDir() - snapshotLocation := path.Join(snapshotDir, s.snapshotId) + snapshotLocation := path.Join(s.disk.GetSnapshotLocation(), s.snapshotId) body := jsonutils.NewDict() body.Set("location", jsonutils.NewString(snapshotLocation)) hostutils.TaskComplete(s.ctx, body) diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index 1b90b52c54..fb526151a4 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -32,7 +32,7 @@ import ( "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/appctx" - "yunion.io/x/onecloud/pkg/hostman/guestfs" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/hostman/hostinfo/hostbridge" "yunion.io/x/onecloud/pkg/hostman/hostutils" "yunion.io/x/onecloud/pkg/hostman/monitor" @@ -761,7 +761,7 @@ func (s *SKVMGuestInstance) StartGuest(ctx context.Context, params jsonutils.JSO func() { s.asyncScriptStart(ctx, jsonutils.NewDict()) }, nil, nil) } -func (s *SKVMGuestInstance) DeployFs(deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error) { +func (s *SKVMGuestInstance) DeployFs(deployInfo *deployapi.DeployInfo) (jsonutils.JSONObject, error) { disks, _ := s.Desc.GetArray("disks") if len(disks) > 0 { diskPath, _ := disks[0].GetString("path") diff --git a/pkg/hostman/host_services.go b/pkg/hostman/host_services.go index 77b189b6dc..201440969f 100644 --- a/pkg/hostman/host_services.go +++ b/pkg/hostman/host_services.go @@ -24,10 +24,10 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/cronman" common_options "yunion.io/x/onecloud/pkg/cloudcommon/options" "yunion.io/x/onecloud/pkg/cloudcommon/service" - "yunion.io/x/onecloud/pkg/hostman/diskhandlers" "yunion.io/x/onecloud/pkg/hostman/downloader" - "yunion.io/x/onecloud/pkg/hostman/guesthandlers" "yunion.io/x/onecloud/pkg/hostman/guestman" + "yunion.io/x/onecloud/pkg/hostman/guestman/guesthandlers" + "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" "yunion.io/x/onecloud/pkg/hostman/hostinfo" "yunion.io/x/onecloud/pkg/hostman/hostmetrics" "yunion.io/x/onecloud/pkg/hostman/hostutils" @@ -35,6 +35,8 @@ import ( "yunion.io/x/onecloud/pkg/hostman/metadata" "yunion.io/x/onecloud/pkg/hostman/options" "yunion.io/x/onecloud/pkg/hostman/storageman" + "yunion.io/x/onecloud/pkg/hostman/storageman/diskhandlers" + "yunion.io/x/onecloud/pkg/hostman/storageman/storagehandler" "yunion.io/x/onecloud/pkg/util/sysutils" ) @@ -49,7 +51,12 @@ func (host *SHostService) InitService() { log.Fatalf("host service must running with root permissions") } + if len(options.HostOptions.DeployServerSocketPath) == 0 { + log.Fatalf("missing deploy server socket path") + } + options.HostOptions.EnableRbac = false // disable rbac + // init base option for pid file host.SServiceBase.O = &options.HostOptions.BaseOptions } @@ -64,6 +71,7 @@ func (host *SHostService) RunService() { log.Fatalf(err.Error()) } + deployclient.Init(options.HostOptions.DeployServerSocketPath) if err := storageman.Init(hostInstance); err != nil { log.Fatalf(err.Error()) } @@ -104,7 +112,7 @@ func (host *SHostService) RunService() { func (host *SHostService) initHandlers(app *appsrv.Application) { guesthandlers.AddGuestTaskHandler("", app) - storageman.AddStorageHandler("", app) + storagehandler.AddStorageHandler("", app) diskhandlers.AddDiskHandler("", app) downloader.AddDownloadHandler("", app) kubehandlers.AddKubeAgentHandler("", app) diff --git a/pkg/hostman/hostdeployer/apis/deploy.pb.go b/pkg/hostman/hostdeployer/apis/deploy.pb.go new file mode 100644 index 0000000000..890e8f3515 --- /dev/null +++ b/pkg/hostman/hostdeployer/apis/deploy.pb.go @@ -0,0 +1,1673 @@ +// 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: deploy.proto + +package apis + +import ( + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type GuestDesc struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Uuid string `protobuf:"bytes,2,opt,name=uuid,proto3" json:"uuid,omitempty"` + Domain string `protobuf:"bytes,3,opt,name=domain,proto3" json:"domain,omitempty"` + Nics []*Nic `protobuf:"bytes,4,rep,name=nics,proto3" json:"nics,omitempty"` + NicsStandby []*Nic `protobuf:"bytes,5,rep,name=nics_standby,json=nicsStandby,proto3" json:"nics_standby,omitempty"` + Disks []*Disk `protobuf:"bytes,6,rep,name=disks,proto3" json:"disks,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GuestDesc) Reset() { *m = GuestDesc{} } +func (m *GuestDesc) String() string { return proto.CompactTextString(m) } +func (*GuestDesc) ProtoMessage() {} +func (*GuestDesc) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{0} +} + +func (m *GuestDesc) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GuestDesc.Unmarshal(m, b) +} +func (m *GuestDesc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GuestDesc.Marshal(b, m, deterministic) +} +func (m *GuestDesc) XXX_Merge(src proto.Message) { + xxx_messageInfo_GuestDesc.Merge(m, src) +} +func (m *GuestDesc) XXX_Size() int { + return xxx_messageInfo_GuestDesc.Size(m) +} +func (m *GuestDesc) XXX_DiscardUnknown() { + xxx_messageInfo_GuestDesc.DiscardUnknown(m) +} + +var xxx_messageInfo_GuestDesc proto.InternalMessageInfo + +func (m *GuestDesc) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *GuestDesc) GetUuid() string { + if m != nil { + return m.Uuid + } + return "" +} + +func (m *GuestDesc) GetDomain() string { + if m != nil { + return m.Domain + } + return "" +} + +func (m *GuestDesc) GetNics() []*Nic { + if m != nil { + return m.Nics + } + return nil +} + +func (m *GuestDesc) GetNicsStandby() []*Nic { + if m != nil { + return m.NicsStandby + } + return nil +} + +func (m *GuestDesc) GetDisks() []*Disk { + if m != nil { + return m.Disks + } + return nil +} + +type Disk struct { + DiskId string `protobuf:"bytes,1,opt,name=disk_id,json=diskId,proto3" json:"disk_id,omitempty"` + Driver string `protobuf:"bytes,2,opt,name=driver,proto3" json:"driver,omitempty"` + CacheMode string `protobuf:"bytes,3,opt,name=cache_mode,json=cacheMode,proto3" json:"cache_mode,omitempty"` + AioMode string `protobuf:"bytes,4,opt,name=aio_mode,json=aioMode,proto3" json:"aio_mode,omitempty"` + Size int64 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` + TemplateId string `protobuf:"bytes,6,opt,name=template_id,json=templateId,proto3" json:"template_id,omitempty"` + ImagePath string `protobuf:"bytes,7,opt,name=image_path,json=imagePath,proto3" json:"image_path,omitempty"` + StorageId string `protobuf:"bytes,8,opt,name=storage_id,json=storageId,proto3" json:"storage_id,omitempty"` + Migrating bool `protobuf:"varint,9,opt,name=migrating,proto3" json:"migrating,omitempty"` + TargetStorageId string `protobuf:"bytes,10,opt,name=target_storage_id,json=targetStorageId,proto3" json:"target_storage_id,omitempty"` + Path string `protobuf:"bytes,11,opt,name=path,proto3" json:"path,omitempty"` + Format string `protobuf:"bytes,12,opt,name=format,proto3" json:"format,omitempty"` + Index int32 `protobuf:"varint,13,opt,name=index,proto3" json:"index,omitempty"` + MergeSnapshot bool `protobuf:"varint,14,opt,name=merge_snapshot,json=mergeSnapshot,proto3" json:"merge_snapshot,omitempty"` + Fs string `protobuf:"bytes,15,opt,name=fs,proto3" json:"fs,omitempty"` + Mountpoint string `protobuf:"bytes,16,opt,name=mountpoint,proto3" json:"mountpoint,omitempty"` + Dev string `protobuf:"bytes,17,opt,name=dev,proto3" json:"dev,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Disk) Reset() { *m = Disk{} } +func (m *Disk) String() string { return proto.CompactTextString(m) } +func (*Disk) ProtoMessage() {} +func (*Disk) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{1} +} + +func (m *Disk) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Disk.Unmarshal(m, b) +} +func (m *Disk) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Disk.Marshal(b, m, deterministic) +} +func (m *Disk) XXX_Merge(src proto.Message) { + xxx_messageInfo_Disk.Merge(m, src) +} +func (m *Disk) XXX_Size() int { + return xxx_messageInfo_Disk.Size(m) +} +func (m *Disk) XXX_DiscardUnknown() { + xxx_messageInfo_Disk.DiscardUnknown(m) +} + +var xxx_messageInfo_Disk proto.InternalMessageInfo + +func (m *Disk) GetDiskId() string { + if m != nil { + return m.DiskId + } + return "" +} + +func (m *Disk) GetDriver() string { + if m != nil { + return m.Driver + } + return "" +} + +func (m *Disk) GetCacheMode() string { + if m != nil { + return m.CacheMode + } + return "" +} + +func (m *Disk) GetAioMode() string { + if m != nil { + return m.AioMode + } + return "" +} + +func (m *Disk) GetSize() int64 { + if m != nil { + return m.Size + } + return 0 +} + +func (m *Disk) GetTemplateId() string { + if m != nil { + return m.TemplateId + } + return "" +} + +func (m *Disk) GetImagePath() string { + if m != nil { + return m.ImagePath + } + return "" +} + +func (m *Disk) GetStorageId() string { + if m != nil { + return m.StorageId + } + return "" +} + +func (m *Disk) GetMigrating() bool { + if m != nil { + return m.Migrating + } + return false +} + +func (m *Disk) GetTargetStorageId() string { + if m != nil { + return m.TargetStorageId + } + return "" +} + +func (m *Disk) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *Disk) GetFormat() string { + if m != nil { + return m.Format + } + return "" +} + +func (m *Disk) GetIndex() int32 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *Disk) GetMergeSnapshot() bool { + if m != nil { + return m.MergeSnapshot + } + return false +} + +func (m *Disk) GetFs() string { + if m != nil { + return m.Fs + } + return "" +} + +func (m *Disk) GetMountpoint() string { + if m != nil { + return m.Mountpoint + } + return "" +} + +func (m *Disk) GetDev() string { + if m != nil { + return m.Dev + } + return "" +} + +type Nic struct { + Mac string `protobuf:"bytes,1,opt,name=mac,proto3" json:"mac,omitempty"` + Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` + Net string `protobuf:"bytes,3,opt,name=net,proto3" json:"net,omitempty"` + NetId string `protobuf:"bytes,4,opt,name=net_id,json=netId,proto3" json:"net_id,omitempty"` + Virtual bool `protobuf:"varint,5,opt,name=virtual,proto3" json:"virtual,omitempty"` + Gateway string `protobuf:"bytes,6,opt,name=gateway,proto3" json:"gateway,omitempty"` + Dns string `protobuf:"bytes,7,opt,name=dns,proto3" json:"dns,omitempty"` + Domain string `protobuf:"bytes,8,opt,name=domain,proto3" json:"domain,omitempty"` + Routes []*Routes `protobuf:"bytes,9,rep,name=routes,proto3" json:"routes,omitempty"` + Ifname string `protobuf:"bytes,10,opt,name=ifname,proto3" json:"ifname,omitempty"` + Masklen int32 `protobuf:"varint,11,opt,name=masklen,proto3" json:"masklen,omitempty"` + Driver string `protobuf:"bytes,12,opt,name=driver,proto3" json:"driver,omitempty"` + Bridge string `protobuf:"bytes,13,opt,name=bridge,proto3" json:"bridge,omitempty"` + WireId string `protobuf:"bytes,14,opt,name=wire_id,json=wireId,proto3" json:"wire_id,omitempty"` + Vlan int32 `protobuf:"varint,15,opt,name=vlan,proto3" json:"vlan,omitempty"` + Interface string `protobuf:"bytes,16,opt,name=interface,proto3" json:"interface,omitempty"` + Bw int32 `protobuf:"varint,17,opt,name=bw,proto3" json:"bw,omitempty"` + Index int32 `protobuf:"varint,18,opt,name=index,proto3" json:"index,omitempty"` + VirtualIps []string `protobuf:"bytes,19,rep,name=virtual_ips,json=virtualIps,proto3" json:"virtual_ips,omitempty"` + ExternelId string `protobuf:"bytes,20,opt,name=externel_id,json=externelId,proto3" json:"externel_id,omitempty"` + TeamWith string `protobuf:"bytes,21,opt,name=team_with,json=teamWith,proto3" json:"team_with,omitempty"` + Manual bool `protobuf:"varint,22,opt,name=manual,proto3" json:"manual,omitempty"` + NicType string `protobuf:"bytes,23,opt,name=nic_type,json=nicType,proto3" json:"nic_type,omitempty"` + LinkUp bool `protobuf:"varint,24,opt,name=link_up,json=linkUp,proto3" json:"link_up,omitempty"` + Mtu int64 `protobuf:"varint,25,opt,name=mtu,proto3" json:"mtu,omitempty"` + Name string `protobuf:"bytes,26,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Nic) Reset() { *m = Nic{} } +func (m *Nic) String() string { return proto.CompactTextString(m) } +func (*Nic) ProtoMessage() {} +func (*Nic) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{2} +} + +func (m *Nic) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nic.Unmarshal(m, b) +} +func (m *Nic) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nic.Marshal(b, m, deterministic) +} +func (m *Nic) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nic.Merge(m, src) +} +func (m *Nic) XXX_Size() int { + return xxx_messageInfo_Nic.Size(m) +} +func (m *Nic) XXX_DiscardUnknown() { + xxx_messageInfo_Nic.DiscardUnknown(m) +} + +var xxx_messageInfo_Nic proto.InternalMessageInfo + +func (m *Nic) GetMac() string { + if m != nil { + return m.Mac + } + return "" +} + +func (m *Nic) GetIp() string { + if m != nil { + return m.Ip + } + return "" +} + +func (m *Nic) GetNet() string { + if m != nil { + return m.Net + } + return "" +} + +func (m *Nic) GetNetId() string { + if m != nil { + return m.NetId + } + return "" +} + +func (m *Nic) GetVirtual() bool { + if m != nil { + return m.Virtual + } + return false +} + +func (m *Nic) GetGateway() string { + if m != nil { + return m.Gateway + } + return "" +} + +func (m *Nic) GetDns() string { + if m != nil { + return m.Dns + } + return "" +} + +func (m *Nic) GetDomain() string { + if m != nil { + return m.Domain + } + return "" +} + +func (m *Nic) GetRoutes() []*Routes { + if m != nil { + return m.Routes + } + return nil +} + +func (m *Nic) GetIfname() string { + if m != nil { + return m.Ifname + } + return "" +} + +func (m *Nic) GetMasklen() int32 { + if m != nil { + return m.Masklen + } + return 0 +} + +func (m *Nic) GetDriver() string { + if m != nil { + return m.Driver + } + return "" +} + +func (m *Nic) GetBridge() string { + if m != nil { + return m.Bridge + } + return "" +} + +func (m *Nic) GetWireId() string { + if m != nil { + return m.WireId + } + return "" +} + +func (m *Nic) GetVlan() int32 { + if m != nil { + return m.Vlan + } + return 0 +} + +func (m *Nic) GetInterface() string { + if m != nil { + return m.Interface + } + return "" +} + +func (m *Nic) GetBw() int32 { + if m != nil { + return m.Bw + } + return 0 +} + +func (m *Nic) GetIndex() int32 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *Nic) GetVirtualIps() []string { + if m != nil { + return m.VirtualIps + } + return nil +} + +func (m *Nic) GetExternelId() string { + if m != nil { + return m.ExternelId + } + return "" +} + +func (m *Nic) GetTeamWith() string { + if m != nil { + return m.TeamWith + } + return "" +} + +func (m *Nic) GetManual() bool { + if m != nil { + return m.Manual + } + return false +} + +func (m *Nic) GetNicType() string { + if m != nil { + return m.NicType + } + return "" +} + +func (m *Nic) GetLinkUp() bool { + if m != nil { + return m.LinkUp + } + return false +} + +func (m *Nic) GetMtu() int64 { + if m != nil { + return m.Mtu + } + return 0 +} + +func (m *Nic) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type Routes struct { + Route []string `protobuf:"bytes,1,rep,name=route,proto3" json:"route,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Routes) Reset() { *m = Routes{} } +func (m *Routes) String() string { return proto.CompactTextString(m) } +func (*Routes) ProtoMessage() {} +func (*Routes) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{3} +} + +func (m *Routes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Routes.Unmarshal(m, b) +} +func (m *Routes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Routes.Marshal(b, m, deterministic) +} +func (m *Routes) XXX_Merge(src proto.Message) { + xxx_messageInfo_Routes.Merge(m, src) +} +func (m *Routes) XXX_Size() int { + return xxx_messageInfo_Routes.Size(m) +} +func (m *Routes) XXX_DiscardUnknown() { + xxx_messageInfo_Routes.DiscardUnknown(m) +} + +var xxx_messageInfo_Routes proto.InternalMessageInfo + +func (m *Routes) GetRoute() []string { + if m != nil { + return m.Route + } + return nil +} + +type DeployInfo struct { + PublicKey *SSHKeys `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + Deploys []*DeployContent `protobuf:"bytes,2,rep,name=deploys,proto3" json:"deploys,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` + IsInit bool `protobuf:"varint,4,opt,name=is_init,json=isInit,proto3" json:"is_init,omitempty"` + EnableTty bool `protobuf:"varint,5,opt,name=enable_tty,json=enableTty,proto3" json:"enable_tty,omitempty"` + DefaultRootUser bool `protobuf:"varint,6,opt,name=default_root_user,json=defaultRootUser,proto3" json:"default_root_user,omitempty"` + WindowsDefaultAdminUser bool `protobuf:"varint,7,opt,name=windows_default_admin_user,json=windowsDefaultAdminUser,proto3" json:"windows_default_admin_user,omitempty"` + EnableCloudInit bool `protobuf:"varint,8,opt,name=enable_cloud_init,json=enableCloudInit,proto3" json:"enable_cloud_init,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeployInfo) Reset() { *m = DeployInfo{} } +func (m *DeployInfo) String() string { return proto.CompactTextString(m) } +func (*DeployInfo) ProtoMessage() {} +func (*DeployInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{4} +} + +func (m *DeployInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeployInfo.Unmarshal(m, b) +} +func (m *DeployInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeployInfo.Marshal(b, m, deterministic) +} +func (m *DeployInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeployInfo.Merge(m, src) +} +func (m *DeployInfo) XXX_Size() int { + return xxx_messageInfo_DeployInfo.Size(m) +} +func (m *DeployInfo) XXX_DiscardUnknown() { + xxx_messageInfo_DeployInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_DeployInfo proto.InternalMessageInfo + +func (m *DeployInfo) GetPublicKey() *SSHKeys { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *DeployInfo) GetDeploys() []*DeployContent { + if m != nil { + return m.Deploys + } + return nil +} + +func (m *DeployInfo) GetPassword() string { + if m != nil { + return m.Password + } + return "" +} + +func (m *DeployInfo) GetIsInit() bool { + if m != nil { + return m.IsInit + } + return false +} + +func (m *DeployInfo) GetEnableTty() bool { + if m != nil { + return m.EnableTty + } + return false +} + +func (m *DeployInfo) GetDefaultRootUser() bool { + if m != nil { + return m.DefaultRootUser + } + return false +} + +func (m *DeployInfo) GetWindowsDefaultAdminUser() bool { + if m != nil { + return m.WindowsDefaultAdminUser + } + return false +} + +func (m *DeployInfo) GetEnableCloudInit() bool { + if m != nil { + return m.EnableCloudInit + } + return false +} + +type SSHKeys struct { + PublicKey string `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + DeletePublicKey string `protobuf:"bytes,2,opt,name=delete_public_key,json=deletePublicKey,proto3" json:"delete_public_key,omitempty"` + AdminPublicKey string `protobuf:"bytes,3,opt,name=admin_public_key,json=adminPublicKey,proto3" json:"admin_public_key,omitempty"` + ProjectPublicKey string `protobuf:"bytes,4,opt,name=project_public_key,json=projectPublicKey,proto3" json:"project_public_key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SSHKeys) Reset() { *m = SSHKeys{} } +func (m *SSHKeys) String() string { return proto.CompactTextString(m) } +func (*SSHKeys) ProtoMessage() {} +func (*SSHKeys) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{5} +} + +func (m *SSHKeys) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SSHKeys.Unmarshal(m, b) +} +func (m *SSHKeys) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SSHKeys.Marshal(b, m, deterministic) +} +func (m *SSHKeys) XXX_Merge(src proto.Message) { + xxx_messageInfo_SSHKeys.Merge(m, src) +} +func (m *SSHKeys) XXX_Size() int { + return xxx_messageInfo_SSHKeys.Size(m) +} +func (m *SSHKeys) XXX_DiscardUnknown() { + xxx_messageInfo_SSHKeys.DiscardUnknown(m) +} + +var xxx_messageInfo_SSHKeys proto.InternalMessageInfo + +func (m *SSHKeys) GetPublicKey() string { + if m != nil { + return m.PublicKey + } + return "" +} + +func (m *SSHKeys) GetDeletePublicKey() string { + if m != nil { + return m.DeletePublicKey + } + return "" +} + +func (m *SSHKeys) GetAdminPublicKey() string { + if m != nil { + return m.AdminPublicKey + } + return "" +} + +func (m *SSHKeys) GetProjectPublicKey() string { + if m != nil { + return m.ProjectPublicKey + } + return "" +} + +type DeployContent struct { + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` + Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeployContent) Reset() { *m = DeployContent{} } +func (m *DeployContent) String() string { return proto.CompactTextString(m) } +func (*DeployContent) ProtoMessage() {} +func (*DeployContent) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{6} +} + +func (m *DeployContent) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeployContent.Unmarshal(m, b) +} +func (m *DeployContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeployContent.Marshal(b, m, deterministic) +} +func (m *DeployContent) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeployContent.Merge(m, src) +} +func (m *DeployContent) XXX_Size() int { + return xxx_messageInfo_DeployContent.Size(m) +} +func (m *DeployContent) XXX_DiscardUnknown() { + xxx_messageInfo_DeployContent.DiscardUnknown(m) +} + +var xxx_messageInfo_DeployContent proto.InternalMessageInfo + +func (m *DeployContent) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *DeployContent) GetContent() string { + if m != nil { + return m.Content + } + return "" +} + +func (m *DeployContent) GetAction() string { + if m != nil { + return m.Action + } + return "" +} + +type Empty struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{7} +} + +func (m *Empty) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Empty.Unmarshal(m, b) +} +func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Empty.Marshal(b, m, deterministic) +} +func (m *Empty) XXX_Merge(src proto.Message) { + xxx_messageInfo_Empty.Merge(m, src) +} +func (m *Empty) XXX_Size() int { + return xxx_messageInfo_Empty.Size(m) +} +func (m *Empty) XXX_DiscardUnknown() { + xxx_messageInfo_Empty.DiscardUnknown(m) +} + +var xxx_messageInfo_Empty proto.InternalMessageInfo + +type DeployGuestFsResponse struct { + Distro string `protobuf:"bytes,1,opt,name=distro,proto3" json:"distro,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Arch string `protobuf:"bytes,3,opt,name=arch,proto3" json:"arch,omitempty"` + Language string `protobuf:"bytes,4,opt,name=language,proto3" json:"language,omitempty"` + Os string `protobuf:"bytes,5,opt,name=os,proto3" json:"os,omitempty"` + Account string `protobuf:"bytes,6,opt,name=account,proto3" json:"account,omitempty"` + Key string `protobuf:"bytes,7,opt,name=key,proto3" json:"key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeployGuestFsResponse) Reset() { *m = DeployGuestFsResponse{} } +func (m *DeployGuestFsResponse) String() string { return proto.CompactTextString(m) } +func (*DeployGuestFsResponse) ProtoMessage() {} +func (*DeployGuestFsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{8} +} + +func (m *DeployGuestFsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeployGuestFsResponse.Unmarshal(m, b) +} +func (m *DeployGuestFsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeployGuestFsResponse.Marshal(b, m, deterministic) +} +func (m *DeployGuestFsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeployGuestFsResponse.Merge(m, src) +} +func (m *DeployGuestFsResponse) XXX_Size() int { + return xxx_messageInfo_DeployGuestFsResponse.Size(m) +} +func (m *DeployGuestFsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeployGuestFsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeployGuestFsResponse proto.InternalMessageInfo + +func (m *DeployGuestFsResponse) GetDistro() string { + if m != nil { + return m.Distro + } + return "" +} + +func (m *DeployGuestFsResponse) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *DeployGuestFsResponse) GetArch() string { + if m != nil { + return m.Arch + } + return "" +} + +func (m *DeployGuestFsResponse) GetLanguage() string { + if m != nil { + return m.Language + } + return "" +} + +func (m *DeployGuestFsResponse) GetOs() string { + if m != nil { + return m.Os + } + return "" +} + +func (m *DeployGuestFsResponse) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +func (m *DeployGuestFsResponse) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +type DeployParams struct { + DiskPath string `protobuf:"bytes,1,opt,name=disk_path,json=diskPath,proto3" json:"disk_path,omitempty"` + GuestDesc *GuestDesc `protobuf:"bytes,2,opt,name=guest_desc,json=guestDesc,proto3" json:"guest_desc,omitempty"` + DeployInfo *DeployInfo `protobuf:"bytes,3,opt,name=deploy_info,json=deployInfo,proto3" json:"deploy_info,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeployParams) Reset() { *m = DeployParams{} } +func (m *DeployParams) String() string { return proto.CompactTextString(m) } +func (*DeployParams) ProtoMessage() {} +func (*DeployParams) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{9} +} + +func (m *DeployParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeployParams.Unmarshal(m, b) +} +func (m *DeployParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeployParams.Marshal(b, m, deterministic) +} +func (m *DeployParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeployParams.Merge(m, src) +} +func (m *DeployParams) XXX_Size() int { + return xxx_messageInfo_DeployParams.Size(m) +} +func (m *DeployParams) XXX_DiscardUnknown() { + xxx_messageInfo_DeployParams.DiscardUnknown(m) +} + +var xxx_messageInfo_DeployParams proto.InternalMessageInfo + +func (m *DeployParams) GetDiskPath() string { + if m != nil { + return m.DiskPath + } + return "" +} + +func (m *DeployParams) GetGuestDesc() *GuestDesc { + if m != nil { + return m.GuestDesc + } + return nil +} + +func (m *DeployParams) GetDeployInfo() *DeployInfo { + if m != nil { + return m.DeployInfo + } + return nil +} + +type ResizeFsParams struct { + DiskPath string `protobuf:"bytes,1,opt,name=disk_path,json=diskPath,proto3" json:"disk_path,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ResizeFsParams) Reset() { *m = ResizeFsParams{} } +func (m *ResizeFsParams) String() string { return proto.CompactTextString(m) } +func (*ResizeFsParams) ProtoMessage() {} +func (*ResizeFsParams) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{10} +} + +func (m *ResizeFsParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ResizeFsParams.Unmarshal(m, b) +} +func (m *ResizeFsParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ResizeFsParams.Marshal(b, m, deterministic) +} +func (m *ResizeFsParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResizeFsParams.Merge(m, src) +} +func (m *ResizeFsParams) XXX_Size() int { + return xxx_messageInfo_ResizeFsParams.Size(m) +} +func (m *ResizeFsParams) XXX_DiscardUnknown() { + xxx_messageInfo_ResizeFsParams.DiscardUnknown(m) +} + +var xxx_messageInfo_ResizeFsParams proto.InternalMessageInfo + +func (m *ResizeFsParams) GetDiskPath() string { + if m != nil { + return m.DiskPath + } + return "" +} + +type FormatFsParams struct { + DiskPath string `protobuf:"bytes,1,opt,name=disk_path,json=diskPath,proto3" json:"disk_path,omitempty"` + FsFormat string `protobuf:"bytes,2,opt,name=fs_format,json=fsFormat,proto3" json:"fs_format,omitempty"` + Uuid string `protobuf:"bytes,3,opt,name=uuid,proto3" json:"uuid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FormatFsParams) Reset() { *m = FormatFsParams{} } +func (m *FormatFsParams) String() string { return proto.CompactTextString(m) } +func (*FormatFsParams) ProtoMessage() {} +func (*FormatFsParams) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{11} +} + +func (m *FormatFsParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FormatFsParams.Unmarshal(m, b) +} +func (m *FormatFsParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FormatFsParams.Marshal(b, m, deterministic) +} +func (m *FormatFsParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_FormatFsParams.Merge(m, src) +} +func (m *FormatFsParams) XXX_Size() int { + return xxx_messageInfo_FormatFsParams.Size(m) +} +func (m *FormatFsParams) XXX_DiscardUnknown() { + xxx_messageInfo_FormatFsParams.DiscardUnknown(m) +} + +var xxx_messageInfo_FormatFsParams proto.InternalMessageInfo + +func (m *FormatFsParams) GetDiskPath() string { + if m != nil { + return m.DiskPath + } + return "" +} + +func (m *FormatFsParams) GetFsFormat() string { + if m != nil { + return m.FsFormat + } + return "" +} + +func (m *FormatFsParams) GetUuid() string { + if m != nil { + return m.Uuid + } + return "" +} + +type ReleaseInfo struct { + Distro string `protobuf:"bytes,1,opt,name=distro,proto3" json:"distro,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Arch string `protobuf:"bytes,3,opt,name=arch,proto3" json:"arch,omitempty"` + Language string `protobuf:"bytes,4,opt,name=language,proto3" json:"language,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ReleaseInfo) Reset() { *m = ReleaseInfo{} } +func (m *ReleaseInfo) String() string { return proto.CompactTextString(m) } +func (*ReleaseInfo) ProtoMessage() {} +func (*ReleaseInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{12} +} + +func (m *ReleaseInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ReleaseInfo.Unmarshal(m, b) +} +func (m *ReleaseInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ReleaseInfo.Marshal(b, m, deterministic) +} +func (m *ReleaseInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReleaseInfo.Merge(m, src) +} +func (m *ReleaseInfo) XXX_Size() int { + return xxx_messageInfo_ReleaseInfo.Size(m) +} +func (m *ReleaseInfo) XXX_DiscardUnknown() { + xxx_messageInfo_ReleaseInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_ReleaseInfo proto.InternalMessageInfo + +func (m *ReleaseInfo) GetDistro() string { + if m != nil { + return m.Distro + } + return "" +} + +func (m *ReleaseInfo) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *ReleaseInfo) GetArch() string { + if m != nil { + return m.Arch + } + return "" +} + +func (m *ReleaseInfo) GetLanguage() string { + if m != nil { + return m.Language + } + return "" +} + +type SaveToGlanceParams struct { + DiskPath string `protobuf:"bytes,1,opt,name=disk_path,json=diskPath,proto3" json:"disk_path,omitempty"` + Compress bool `protobuf:"varint,2,opt,name=compress,proto3" json:"compress,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SaveToGlanceParams) Reset() { *m = SaveToGlanceParams{} } +func (m *SaveToGlanceParams) String() string { return proto.CompactTextString(m) } +func (*SaveToGlanceParams) ProtoMessage() {} +func (*SaveToGlanceParams) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{13} +} + +func (m *SaveToGlanceParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SaveToGlanceParams.Unmarshal(m, b) +} +func (m *SaveToGlanceParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SaveToGlanceParams.Marshal(b, m, deterministic) +} +func (m *SaveToGlanceParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_SaveToGlanceParams.Merge(m, src) +} +func (m *SaveToGlanceParams) XXX_Size() int { + return xxx_messageInfo_SaveToGlanceParams.Size(m) +} +func (m *SaveToGlanceParams) XXX_DiscardUnknown() { + xxx_messageInfo_SaveToGlanceParams.DiscardUnknown(m) +} + +var xxx_messageInfo_SaveToGlanceParams proto.InternalMessageInfo + +func (m *SaveToGlanceParams) GetDiskPath() string { + if m != nil { + return m.DiskPath + } + return "" +} + +func (m *SaveToGlanceParams) GetCompress() bool { + if m != nil { + return m.Compress + } + return false +} + +type SaveToGlanceResponse struct { + OsInfo string `protobuf:"bytes,1,opt,name=os_info,json=osInfo,proto3" json:"os_info,omitempty"` + ReleaseInfo *ReleaseInfo `protobuf:"bytes,2,opt,name=release_info,json=releaseInfo,proto3" json:"release_info,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SaveToGlanceResponse) Reset() { *m = SaveToGlanceResponse{} } +func (m *SaveToGlanceResponse) String() string { return proto.CompactTextString(m) } +func (*SaveToGlanceResponse) ProtoMessage() {} +func (*SaveToGlanceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{14} +} + +func (m *SaveToGlanceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SaveToGlanceResponse.Unmarshal(m, b) +} +func (m *SaveToGlanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SaveToGlanceResponse.Marshal(b, m, deterministic) +} +func (m *SaveToGlanceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SaveToGlanceResponse.Merge(m, src) +} +func (m *SaveToGlanceResponse) XXX_Size() int { + return xxx_messageInfo_SaveToGlanceResponse.Size(m) +} +func (m *SaveToGlanceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SaveToGlanceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SaveToGlanceResponse proto.InternalMessageInfo + +func (m *SaveToGlanceResponse) GetOsInfo() string { + if m != nil { + return m.OsInfo + } + return "" +} + +func (m *SaveToGlanceResponse) GetReleaseInfo() *ReleaseInfo { + if m != nil { + return m.ReleaseInfo + } + return nil +} + +type ProbeImageInfoPramas struct { + DiskPath string `protobuf:"bytes,1,opt,name=disk_path,json=diskPath,proto3" json:"disk_path,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ProbeImageInfoPramas) Reset() { *m = ProbeImageInfoPramas{} } +func (m *ProbeImageInfoPramas) String() string { return proto.CompactTextString(m) } +func (*ProbeImageInfoPramas) ProtoMessage() {} +func (*ProbeImageInfoPramas) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{15} +} + +func (m *ProbeImageInfoPramas) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProbeImageInfoPramas.Unmarshal(m, b) +} +func (m *ProbeImageInfoPramas) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProbeImageInfoPramas.Marshal(b, m, deterministic) +} +func (m *ProbeImageInfoPramas) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProbeImageInfoPramas.Merge(m, src) +} +func (m *ProbeImageInfoPramas) XXX_Size() int { + return xxx_messageInfo_ProbeImageInfoPramas.Size(m) +} +func (m *ProbeImageInfoPramas) XXX_DiscardUnknown() { + xxx_messageInfo_ProbeImageInfoPramas.DiscardUnknown(m) +} + +var xxx_messageInfo_ProbeImageInfoPramas proto.InternalMessageInfo + +func (m *ProbeImageInfoPramas) GetDiskPath() string { + if m != nil { + return m.DiskPath + } + return "" +} + +type ImageInfo struct { + OsInfo *ReleaseInfo `protobuf:"bytes,1,opt,name=os_info,json=osInfo,proto3" json:"os_info,omitempty"` + OsType string `protobuf:"bytes,2,opt,name=os_type,json=osType,proto3" json:"os_type,omitempty"` + IsUefiSupport bool `protobuf:"varint,3,opt,name=is_uefi_support,json=isUefiSupport,proto3" json:"is_uefi_support,omitempty"` + IsLvmPartition bool `protobuf:"varint,4,opt,name=is_lvm_partition,json=isLvmPartition,proto3" json:"is_lvm_partition,omitempty"` + IsReadonly bool `protobuf:"varint,5,opt,name=is_readonly,json=isReadonly,proto3" json:"is_readonly,omitempty"` + PhysicalPartitionType string `protobuf:"bytes,6,opt,name=physical_partition_type,json=physicalPartitionType,proto3" json:"physical_partition_type,omitempty"` + IsInstalledCloudInit bool `protobuf:"varint,7,opt,name=is_installed_cloud_init,json=isInstalledCloudInit,proto3" json:"is_installed_cloud_init,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ImageInfo) Reset() { *m = ImageInfo{} } +func (m *ImageInfo) String() string { return proto.CompactTextString(m) } +func (*ImageInfo) ProtoMessage() {} +func (*ImageInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_05f09e103004e384, []int{16} +} + +func (m *ImageInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ImageInfo.Unmarshal(m, b) +} +func (m *ImageInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ImageInfo.Marshal(b, m, deterministic) +} +func (m *ImageInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_ImageInfo.Merge(m, src) +} +func (m *ImageInfo) XXX_Size() int { + return xxx_messageInfo_ImageInfo.Size(m) +} +func (m *ImageInfo) XXX_DiscardUnknown() { + xxx_messageInfo_ImageInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_ImageInfo proto.InternalMessageInfo + +func (m *ImageInfo) GetOsInfo() *ReleaseInfo { + if m != nil { + return m.OsInfo + } + return nil +} + +func (m *ImageInfo) GetOsType() string { + if m != nil { + return m.OsType + } + return "" +} + +func (m *ImageInfo) GetIsUefiSupport() bool { + if m != nil { + return m.IsUefiSupport + } + return false +} + +func (m *ImageInfo) GetIsLvmPartition() bool { + if m != nil { + return m.IsLvmPartition + } + return false +} + +func (m *ImageInfo) GetIsReadonly() bool { + if m != nil { + return m.IsReadonly + } + return false +} + +func (m *ImageInfo) GetPhysicalPartitionType() string { + if m != nil { + return m.PhysicalPartitionType + } + return "" +} + +func (m *ImageInfo) GetIsInstalledCloudInit() bool { + if m != nil { + return m.IsInstalledCloudInit + } + return false +} + +func init() { + proto.RegisterType((*GuestDesc)(nil), "apis.GuestDesc") + proto.RegisterType((*Disk)(nil), "apis.Disk") + proto.RegisterType((*Nic)(nil), "apis.Nic") + proto.RegisterType((*Routes)(nil), "apis.Routes") + proto.RegisterType((*DeployInfo)(nil), "apis.DeployInfo") + proto.RegisterType((*SSHKeys)(nil), "apis.SSHKeys") + proto.RegisterType((*DeployContent)(nil), "apis.DeployContent") + proto.RegisterType((*Empty)(nil), "apis.Empty") + proto.RegisterType((*DeployGuestFsResponse)(nil), "apis.DeployGuestFsResponse") + proto.RegisterType((*DeployParams)(nil), "apis.DeployParams") + proto.RegisterType((*ResizeFsParams)(nil), "apis.ResizeFsParams") + proto.RegisterType((*FormatFsParams)(nil), "apis.FormatFsParams") + proto.RegisterType((*ReleaseInfo)(nil), "apis.ReleaseInfo") + proto.RegisterType((*SaveToGlanceParams)(nil), "apis.SaveToGlanceParams") + proto.RegisterType((*SaveToGlanceResponse)(nil), "apis.SaveToGlanceResponse") + proto.RegisterType((*ProbeImageInfoPramas)(nil), "apis.ProbeImageInfoPramas") + proto.RegisterType((*ImageInfo)(nil), "apis.ImageInfo") +} + +func init() { proto.RegisterFile("deploy.proto", fileDescriptor_05f09e103004e384) } + +var fileDescriptor_05f09e103004e384 = []byte{ + // 1535 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x5f, 0x6f, 0x23, 0xb7, + 0x11, 0x87, 0x64, 0xfd, 0x59, 0x8d, 0x64, 0xd9, 0xc7, 0xf8, 0xce, 0x1b, 0xa5, 0x49, 0x8c, 0x45, + 0x5b, 0x18, 0x87, 0xbb, 0x03, 0xea, 0xb4, 0x7d, 0x29, 0x0a, 0x34, 0x88, 0x7b, 0xa9, 0x90, 0x26, + 0x30, 0xd6, 0x77, 0xe8, 0x5b, 0x17, 0xd4, 0x2e, 0x25, 0xb3, 0xde, 0x25, 0x17, 0x24, 0x65, 0x45, + 0xfd, 0x10, 0xfd, 0x24, 0x7d, 0x0a, 0xd0, 0x97, 0x7e, 0x8c, 0xbe, 0xf5, 0x9b, 0xf4, 0xb1, 0x98, + 0x21, 0x77, 0xb5, 0xbe, 0x1c, 0xd0, 0x7b, 0xe9, 0x93, 0x38, 0xbf, 0x19, 0x92, 0xc3, 0xf9, 0xf3, + 0x9b, 0x15, 0xcc, 0x0a, 0x51, 0x97, 0x7a, 0xff, 0xaa, 0x36, 0xda, 0x69, 0x36, 0xe0, 0xb5, 0xb4, + 0xc9, 0x3f, 0x7b, 0x30, 0xf9, 0x7a, 0x2b, 0xac, 0xbb, 0x16, 0x36, 0x67, 0x0c, 0x06, 0x8a, 0x57, + 0x22, 0xee, 0x5d, 0xf4, 0x2e, 0x27, 0x29, 0xad, 0x11, 0xdb, 0x6e, 0x65, 0x11, 0xf7, 0x3d, 0x86, + 0x6b, 0xf6, 0x0c, 0x46, 0x85, 0xae, 0xb8, 0x54, 0xf1, 0x11, 0xa1, 0x41, 0x62, 0x9f, 0xc2, 0x40, + 0xc9, 0xdc, 0xc6, 0x83, 0x8b, 0xa3, 0xcb, 0xe9, 0xd5, 0xe4, 0x15, 0x5e, 0xf1, 0xea, 0x3b, 0x99, + 0xa7, 0x04, 0xb3, 0x17, 0x30, 0xc3, 0xdf, 0xcc, 0x3a, 0xae, 0x8a, 0xd5, 0x3e, 0x1e, 0xbe, 0x6b, + 0x36, 0x45, 0xf5, 0xad, 0xd7, 0xb2, 0x0b, 0x18, 0x16, 0xd2, 0xde, 0xdb, 0x78, 0x44, 0x66, 0xe0, + 0xcd, 0xae, 0xa5, 0xbd, 0x4f, 0xbd, 0x22, 0xf9, 0xf7, 0x11, 0x0c, 0x50, 0x66, 0xe7, 0x30, 0x46, + 0x24, 0x93, 0x45, 0x70, 0x7d, 0x84, 0xe2, 0xd2, 0x3b, 0x6a, 0xe4, 0x83, 0x30, 0xc1, 0xfd, 0x20, + 0xb1, 0x4f, 0x01, 0x72, 0x9e, 0xdf, 0x89, 0xac, 0xd2, 0x85, 0x08, 0x8f, 0x98, 0x10, 0xf2, 0xad, + 0x2e, 0x04, 0xfb, 0x18, 0x22, 0x2e, 0xb5, 0x57, 0x0e, 0x48, 0x39, 0xe6, 0x52, 0x93, 0x8a, 0xc1, + 0xc0, 0xca, 0xbf, 0x8a, 0x78, 0x78, 0xd1, 0xbb, 0x3c, 0x4a, 0x69, 0xcd, 0x3e, 0x87, 0xa9, 0x13, + 0x55, 0x5d, 0x72, 0x27, 0xd0, 0x85, 0x11, 0xed, 0x80, 0x06, 0x5a, 0x16, 0x78, 0x9d, 0xac, 0xf8, + 0x46, 0x64, 0x35, 0x77, 0x77, 0xf1, 0xd8, 0x5f, 0x47, 0xc8, 0x0d, 0x77, 0x77, 0xa8, 0xb6, 0x4e, + 0x1b, 0x34, 0x90, 0x45, 0x1c, 0x79, 0x75, 0x40, 0x96, 0x05, 0xfb, 0x09, 0x4c, 0x2a, 0xb9, 0x31, + 0xdc, 0x49, 0xb5, 0x89, 0x27, 0x17, 0xbd, 0xcb, 0x28, 0x3d, 0x00, 0xec, 0x39, 0x3c, 0x71, 0xdc, + 0x6c, 0x84, 0xcb, 0x3a, 0x67, 0x00, 0x9d, 0x71, 0xe2, 0x15, 0xb7, 0xed, 0x49, 0x0c, 0x06, 0xe4, + 0xc1, 0xd4, 0xe7, 0x12, 0xd7, 0x18, 0xa2, 0xb5, 0x36, 0x15, 0x77, 0xf1, 0xcc, 0x87, 0xc8, 0x4b, + 0xec, 0x0c, 0x86, 0x52, 0x15, 0xe2, 0xfb, 0xf8, 0xf8, 0xa2, 0x77, 0x39, 0x4c, 0xbd, 0xc0, 0x7e, + 0x06, 0xf3, 0x4a, 0x98, 0x8d, 0xc8, 0xac, 0xe2, 0xb5, 0xbd, 0xd3, 0x2e, 0x9e, 0x93, 0x43, 0xc7, + 0x84, 0xde, 0x06, 0x90, 0xcd, 0xa1, 0xbf, 0xb6, 0xf1, 0x09, 0x1d, 0xd8, 0x5f, 0x5b, 0xf6, 0x19, + 0x40, 0xa5, 0xb7, 0xca, 0xd5, 0x5a, 0x2a, 0x17, 0x9f, 0xfa, 0x00, 0x1d, 0x10, 0x76, 0x0a, 0x47, + 0x85, 0x78, 0x88, 0x9f, 0x90, 0x02, 0x97, 0xc9, 0x7f, 0x06, 0x70, 0xf4, 0x9d, 0xcc, 0x51, 0x53, + 0xf1, 0x3c, 0xa4, 0x15, 0x97, 0x78, 0xb6, 0xac, 0x43, 0x3e, 0xfb, 0xb2, 0x46, 0x0b, 0x25, 0x5c, + 0x48, 0x22, 0x2e, 0xd9, 0x53, 0x18, 0x29, 0xe1, 0x30, 0x0e, 0x3e, 0x79, 0x43, 0x25, 0xdc, 0xb2, + 0x60, 0x31, 0x8c, 0x1f, 0xa4, 0x71, 0x5b, 0x5e, 0x52, 0xf6, 0xa2, 0xb4, 0x11, 0x51, 0xb3, 0xe1, + 0x4e, 0xec, 0xf8, 0x3e, 0x24, 0xaf, 0x11, 0xc9, 0x31, 0x65, 0x43, 0xca, 0x70, 0xd9, 0xa9, 0xfd, + 0xe8, 0x51, 0xed, 0xff, 0x14, 0x46, 0x46, 0x6f, 0x9d, 0xb0, 0xf1, 0x84, 0xea, 0x75, 0xe6, 0xeb, + 0x35, 0x25, 0x2c, 0x0d, 0x3a, 0xdc, 0x2d, 0xd7, 0xd4, 0x63, 0x3e, 0x45, 0x41, 0x42, 0x0f, 0x2a, + 0x6e, 0xef, 0x4b, 0xa1, 0x28, 0x39, 0xc3, 0xb4, 0x11, 0x3b, 0x25, 0x3c, 0x7b, 0x54, 0xc2, 0xcf, + 0x60, 0xb4, 0x32, 0xb2, 0xd8, 0x08, 0x4a, 0xd0, 0x24, 0x0d, 0x12, 0xf6, 0xc2, 0x4e, 0x1a, 0xaa, + 0x82, 0xb9, 0x57, 0xa0, 0xe8, 0x93, 0xff, 0x50, 0x72, 0x45, 0x59, 0x19, 0xa6, 0xb4, 0xc6, 0xd2, + 0x92, 0xca, 0x09, 0xb3, 0xe6, 0xb9, 0x08, 0x69, 0x39, 0x00, 0x18, 0xe9, 0xd5, 0x8e, 0x92, 0x32, + 0x4c, 0xfb, 0xab, 0xdd, 0xa1, 0x24, 0x58, 0xb7, 0x24, 0x3e, 0x87, 0x69, 0x88, 0x63, 0x26, 0x6b, + 0x1b, 0x7f, 0x74, 0x71, 0x84, 0xc9, 0x0d, 0xd0, 0xb2, 0xb6, 0x68, 0x20, 0xbe, 0x77, 0xc2, 0x28, + 0x51, 0xa2, 0x57, 0x67, 0x3e, 0xfb, 0x0d, 0xb4, 0x2c, 0xd8, 0x27, 0x30, 0x71, 0x82, 0x57, 0xd9, + 0x4e, 0xba, 0xbb, 0xf8, 0x29, 0xa9, 0x23, 0x04, 0xfe, 0x24, 0x7d, 0x7d, 0x56, 0x5c, 0x61, 0xd2, + 0x9e, 0x51, 0xd2, 0x82, 0x84, 0x3d, 0xaa, 0x64, 0x9e, 0xb9, 0x7d, 0x2d, 0xe2, 0x73, 0x9f, 0x34, + 0x25, 0xf3, 0x37, 0xfb, 0x9a, 0x42, 0x50, 0x4a, 0x75, 0x9f, 0x6d, 0xeb, 0x38, 0xf6, 0x7b, 0x50, + 0x7c, 0x4b, 0xa5, 0x52, 0xb9, 0x6d, 0xfc, 0x31, 0xf5, 0x2e, 0x2e, 0x5b, 0xc6, 0x5b, 0x1c, 0x18, + 0x2f, 0xf9, 0x0c, 0x46, 0x3e, 0x6b, 0xf8, 0x60, 0xca, 0x5b, 0xdc, 0xa3, 0x47, 0x79, 0x21, 0xf9, + 0x57, 0x1f, 0xe0, 0x9a, 0xa8, 0x74, 0xa9, 0xd6, 0x9a, 0xbd, 0x00, 0xa8, 0xb7, 0xab, 0x52, 0xe6, + 0xd9, 0xbd, 0xd8, 0x53, 0xa1, 0x4e, 0xaf, 0x8e, 0x7d, 0xf2, 0x6f, 0x6f, 0xff, 0xf0, 0x8d, 0xd8, + 0xdb, 0x74, 0xe2, 0x0d, 0xbe, 0x11, 0x7b, 0xf6, 0x12, 0xc6, 0x9e, 0x86, 0x6d, 0xdc, 0xa7, 0x3a, + 0xf9, 0x28, 0xf0, 0x1a, 0x81, 0x5f, 0x69, 0xe5, 0x84, 0x72, 0x69, 0x63, 0xc3, 0x16, 0x10, 0xd5, + 0xdc, 0xda, 0x9d, 0x36, 0x45, 0xa8, 0xf0, 0x56, 0xc6, 0x67, 0x4a, 0x9b, 0x49, 0x25, 0x1d, 0xd5, + 0x79, 0x94, 0x8e, 0xa4, 0x5d, 0x2a, 0xe9, 0x90, 0x4f, 0x84, 0xe2, 0xab, 0x52, 0x64, 0xce, 0xed, + 0x43, 0xad, 0x4f, 0x3c, 0xf2, 0xc6, 0xed, 0x91, 0x31, 0x0a, 0xb1, 0xe6, 0xdb, 0xd2, 0x65, 0x46, + 0x6b, 0x97, 0x6d, 0xad, 0x30, 0x54, 0xf7, 0x51, 0x7a, 0x12, 0x14, 0xa9, 0xd6, 0xee, 0xad, 0x15, + 0x86, 0xfd, 0x06, 0x16, 0x3b, 0xa9, 0x0a, 0xbd, 0xb3, 0x59, 0xb3, 0x87, 0x17, 0x95, 0x54, 0x7e, + 0xd3, 0x98, 0x36, 0x9d, 0x07, 0x8b, 0x6b, 0x6f, 0xf0, 0x25, 0xea, 0x69, 0xf3, 0x73, 0x78, 0x12, + 0xfc, 0xc8, 0x4b, 0xbd, 0x2d, 0xbc, 0xab, 0x91, 0xbf, 0xc8, 0x2b, 0xbe, 0x42, 0x1c, 0x7d, 0x4e, + 0xfe, 0xde, 0x83, 0x71, 0x08, 0x17, 0xfa, 0xff, 0x4e, 0x44, 0x27, 0xdd, 0x10, 0x92, 0xff, 0xa5, + 0x70, 0x22, 0xeb, 0x58, 0x79, 0x3e, 0x38, 0xf1, 0x8a, 0x9b, 0xd6, 0xf6, 0x12, 0x4e, 0xbd, 0xbf, + 0x1d, 0x53, 0x1f, 0xc7, 0x39, 0xe1, 0x07, 0xcb, 0x17, 0xc0, 0x6a, 0xa3, 0xff, 0x22, 0x72, 0xd7, + 0xb5, 0xf5, 0x04, 0x72, 0x1a, 0x34, 0xad, 0x75, 0xf2, 0x16, 0x8e, 0x1f, 0x65, 0xac, 0xa5, 0xd6, + 0x5e, 0x87, 0x5a, 0x63, 0x18, 0xe7, 0x5e, 0x1d, 0xdc, 0x6b, 0x44, 0x2c, 0x6a, 0x9e, 0x3b, 0xa9, + 0xdb, 0x01, 0xea, 0xa5, 0x64, 0x0c, 0xc3, 0xdf, 0x57, 0xb5, 0xdb, 0x27, 0xff, 0xe8, 0xc1, 0x53, + 0x7f, 0x01, 0x4d, 0xe7, 0xd7, 0x36, 0x15, 0xb6, 0xd6, 0xca, 0x0a, 0xe2, 0x03, 0x69, 0x9d, 0xd1, + 0x9d, 0x51, 0xe7, 0x8c, 0x26, 0x76, 0x13, 0xc6, 0xe2, 0x99, 0xe1, 0xb2, 0x20, 0xa2, 0x6b, 0xdc, + 0xe4, 0x77, 0xe1, 0x2a, 0x5a, 0x63, 0x5d, 0x95, 0x5c, 0x6d, 0xb6, 0x7c, 0xd3, 0x4c, 0xb8, 0x56, + 0xc6, 0xb6, 0xd7, 0x96, 0xca, 0x66, 0x92, 0xf6, 0xb5, 0xc5, 0x93, 0x79, 0x9e, 0x23, 0x59, 0x37, + 0xec, 0x18, 0x44, 0xec, 0x27, 0x0c, 0x52, 0x60, 0xc7, 0x7b, 0xb1, 0x4f, 0xfe, 0xd6, 0x83, 0x99, + 0xf7, 0xfb, 0x86, 0x1b, 0x5e, 0x59, 0xec, 0x6d, 0x1a, 0xcd, 0x9d, 0xe0, 0x44, 0x08, 0xd0, 0xe0, + 0x7b, 0x05, 0xb0, 0xc1, 0xe7, 0x65, 0x85, 0xb0, 0x39, 0xb9, 0x3d, 0xbd, 0x3a, 0xf1, 0xfd, 0xd0, + 0x7e, 0x94, 0xa4, 0x93, 0x4d, 0xfb, 0x7d, 0xf2, 0x0b, 0x98, 0xfa, 0xc6, 0xc8, 0xa4, 0x5a, 0x6b, + 0x7a, 0xd0, 0xf4, 0xea, 0xb4, 0xdb, 0x40, 0xd8, 0x91, 0x29, 0x14, 0xed, 0x3a, 0x79, 0x09, 0xf3, + 0x54, 0xe0, 0x94, 0x7e, 0x6d, 0x3f, 0xc0, 0xa3, 0xe4, 0xcf, 0x30, 0x7f, 0x4d, 0xf3, 0xef, 0x83, + 0xcc, 0x51, 0xb9, 0xb6, 0x59, 0x98, 0x9f, 0x3e, 0xec, 0xd1, 0xda, 0xfa, 0x13, 0xda, 0x2f, 0xa7, + 0xa3, 0xc3, 0x97, 0x53, 0xa2, 0x61, 0x9a, 0x8a, 0x52, 0x70, 0x2b, 0x88, 0x3b, 0xfe, 0xef, 0xc9, + 0x4c, 0xbe, 0x05, 0x76, 0xcb, 0x1f, 0xc4, 0x1b, 0xfd, 0x75, 0xc9, 0x55, 0x2e, 0x3e, 0xe4, 0x51, + 0x0b, 0x88, 0x72, 0x5d, 0xd5, 0x46, 0x58, 0x4b, 0xb7, 0x47, 0x69, 0x2b, 0x27, 0x02, 0xce, 0xba, + 0xc7, 0xb5, 0x55, 0x79, 0x0e, 0x63, 0x6d, 0x7d, 0x56, 0xc2, 0x4b, 0xb4, 0xa5, 0x17, 0xfe, 0x12, + 0x66, 0xc6, 0x3f, 0xd8, 0x6b, 0x7d, 0x92, 0x9f, 0x84, 0xe1, 0x78, 0x08, 0x45, 0x3a, 0x35, 0x07, + 0x21, 0xf9, 0x02, 0xce, 0x6e, 0x8c, 0x5e, 0x89, 0x25, 0x7e, 0x23, 0x21, 0x72, 0x63, 0x78, 0xc5, + 0xff, 0x47, 0xee, 0x7e, 0xe8, 0xc3, 0xa4, 0xdd, 0xc0, 0x9e, 0x3f, 0xf6, 0xe8, 0xbd, 0x77, 0x36, + 0x4e, 0x7a, 0xef, 0x69, 0x94, 0xf4, 0x1b, 0xef, 0x69, 0x92, 0xfc, 0x1c, 0x4e, 0xa4, 0xcd, 0xb6, + 0x62, 0x2d, 0x33, 0xbb, 0xad, 0x6b, 0x6d, 0xfc, 0x77, 0x46, 0x94, 0x1e, 0x4b, 0xfb, 0x56, 0xac, + 0xe5, 0xad, 0x07, 0x91, 0x66, 0xa4, 0xcd, 0xca, 0x87, 0x2a, 0xab, 0xb9, 0x71, 0x92, 0x3a, 0xdb, + 0x73, 0xf2, 0x5c, 0xda, 0x3f, 0x3e, 0x54, 0x37, 0x0d, 0x8a, 0xc3, 0x50, 0xda, 0xcc, 0x08, 0x5e, + 0x68, 0x55, 0x36, 0xe4, 0x0c, 0xd2, 0xa6, 0x01, 0x61, 0xbf, 0x86, 0xf3, 0xfa, 0x6e, 0x6f, 0x65, + 0xce, 0xcb, 0xc3, 0x61, 0xde, 0x37, 0xdf, 0x7d, 0x4f, 0x1b, 0x75, 0x7b, 0x28, 0xb9, 0xfa, 0x2b, + 0x38, 0xa7, 0x69, 0x60, 0x1d, 0x2f, 0x4b, 0x51, 0x74, 0x29, 0xd7, 0xd3, 0xf4, 0x19, 0x4e, 0x87, + 0xa0, 0x6d, 0x79, 0xf7, 0xea, 0x87, 0x3e, 0x4c, 0x7d, 0xeb, 0x7c, 0xb9, 0x41, 0x66, 0xfa, 0x5d, + 0x43, 0x6c, 0x81, 0x77, 0x18, 0xeb, 0xb6, 0x97, 0x2f, 0x9f, 0xc5, 0x27, 0x5d, 0xec, 0x5d, 0x82, + 0x7a, 0x09, 0x51, 0xd3, 0x71, 0xec, 0xac, 0x89, 0x79, 0xb7, 0x03, 0x17, 0x53, 0x8f, 0x12, 0xd3, + 0xa1, 0x79, 0xd3, 0x71, 0x8d, 0xf9, 0xe3, 0x0e, 0x7c, 0x6c, 0x7e, 0x0d, 0xb3, 0x6e, 0x01, 0xb2, + 0x38, 0x4c, 0xda, 0x1f, 0xd5, 0xf8, 0x62, 0xf1, 0x63, 0x4d, 0xeb, 0xe3, 0x6f, 0x61, 0xfe, 0xb8, + 0xbe, 0x58, 0xb0, 0x7e, 0x5f, 0xd5, 0x2d, 0x02, 0x25, 0xb5, 0xf0, 0x6a, 0x44, 0x7f, 0xa1, 0xbe, + 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0xf1, 0x62, 0xcb, 0x52, 0x0d, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// DeployAgentClient is the client API for DeployAgent service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type DeployAgentClient interface { + DeployGuestFs(ctx context.Context, in *DeployParams, opts ...grpc.CallOption) (*DeployGuestFsResponse, error) + ResizeFs(ctx context.Context, in *ResizeFsParams, opts ...grpc.CallOption) (*Empty, error) + FormatFs(ctx context.Context, in *FormatFsParams, opts ...grpc.CallOption) (*Empty, error) + SaveToGlance(ctx context.Context, in *SaveToGlanceParams, opts ...grpc.CallOption) (*SaveToGlanceResponse, error) + ProbeImageInfo(ctx context.Context, in *ProbeImageInfoPramas, opts ...grpc.CallOption) (*ImageInfo, error) +} + +type deployAgentClient struct { + cc *grpc.ClientConn +} + +func NewDeployAgentClient(cc *grpc.ClientConn) DeployAgentClient { + return &deployAgentClient{cc} +} + +func (c *deployAgentClient) DeployGuestFs(ctx context.Context, in *DeployParams, opts ...grpc.CallOption) (*DeployGuestFsResponse, error) { + out := new(DeployGuestFsResponse) + err := c.cc.Invoke(ctx, "/apis.DeployAgent/DeployGuestFs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deployAgentClient) ResizeFs(ctx context.Context, in *ResizeFsParams, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/apis.DeployAgent/ResizeFs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deployAgentClient) FormatFs(ctx context.Context, in *FormatFsParams, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/apis.DeployAgent/FormatFs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deployAgentClient) SaveToGlance(ctx context.Context, in *SaveToGlanceParams, opts ...grpc.CallOption) (*SaveToGlanceResponse, error) { + out := new(SaveToGlanceResponse) + err := c.cc.Invoke(ctx, "/apis.DeployAgent/SaveToGlance", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *deployAgentClient) ProbeImageInfo(ctx context.Context, in *ProbeImageInfoPramas, opts ...grpc.CallOption) (*ImageInfo, error) { + out := new(ImageInfo) + err := c.cc.Invoke(ctx, "/apis.DeployAgent/ProbeImageInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DeployAgentServer is the server API for DeployAgent service. +type DeployAgentServer interface { + DeployGuestFs(context.Context, *DeployParams) (*DeployGuestFsResponse, error) + ResizeFs(context.Context, *ResizeFsParams) (*Empty, error) + FormatFs(context.Context, *FormatFsParams) (*Empty, error) + SaveToGlance(context.Context, *SaveToGlanceParams) (*SaveToGlanceResponse, error) + ProbeImageInfo(context.Context, *ProbeImageInfoPramas) (*ImageInfo, error) +} + +// UnimplementedDeployAgentServer can be embedded to have forward compatible implementations. +type UnimplementedDeployAgentServer struct { +} + +func (*UnimplementedDeployAgentServer) DeployGuestFs(ctx context.Context, req *DeployParams) (*DeployGuestFsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeployGuestFs not implemented") +} +func (*UnimplementedDeployAgentServer) ResizeFs(ctx context.Context, req *ResizeFsParams) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResizeFs not implemented") +} +func (*UnimplementedDeployAgentServer) FormatFs(ctx context.Context, req *FormatFsParams) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method FormatFs not implemented") +} +func (*UnimplementedDeployAgentServer) SaveToGlance(ctx context.Context, req *SaveToGlanceParams) (*SaveToGlanceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SaveToGlance not implemented") +} +func (*UnimplementedDeployAgentServer) ProbeImageInfo(ctx context.Context, req *ProbeImageInfoPramas) (*ImageInfo, error) { + return nil, status.Errorf(codes.Unimplemented, "method ProbeImageInfo not implemented") +} + +func RegisterDeployAgentServer(s *grpc.Server, srv DeployAgentServer) { + s.RegisterService(&_DeployAgent_serviceDesc, srv) +} + +func _DeployAgent_DeployGuestFs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeployParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeployAgentServer).DeployGuestFs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/apis.DeployAgent/DeployGuestFs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeployAgentServer).DeployGuestFs(ctx, req.(*DeployParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeployAgent_ResizeFs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResizeFsParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeployAgentServer).ResizeFs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/apis.DeployAgent/ResizeFs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeployAgentServer).ResizeFs(ctx, req.(*ResizeFsParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeployAgent_FormatFs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FormatFsParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeployAgentServer).FormatFs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/apis.DeployAgent/FormatFs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeployAgentServer).FormatFs(ctx, req.(*FormatFsParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeployAgent_SaveToGlance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SaveToGlanceParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeployAgentServer).SaveToGlance(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/apis.DeployAgent/SaveToGlance", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeployAgentServer).SaveToGlance(ctx, req.(*SaveToGlanceParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _DeployAgent_ProbeImageInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ProbeImageInfoPramas) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeployAgentServer).ProbeImageInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/apis.DeployAgent/ProbeImageInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeployAgentServer).ProbeImageInfo(ctx, req.(*ProbeImageInfoPramas)) + } + return interceptor(ctx, in, info, handler) +} + +var _DeployAgent_serviceDesc = grpc.ServiceDesc{ + ServiceName: "apis.DeployAgent", + HandlerType: (*DeployAgentServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "DeployGuestFs", + Handler: _DeployAgent_DeployGuestFs_Handler, + }, + { + MethodName: "ResizeFs", + Handler: _DeployAgent_ResizeFs_Handler, + }, + { + MethodName: "FormatFs", + Handler: _DeployAgent_FormatFs_Handler, + }, + { + MethodName: "SaveToGlance", + Handler: _DeployAgent_SaveToGlance_Handler, + }, + { + MethodName: "ProbeImageInfo", + Handler: _DeployAgent_ProbeImageInfo_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "deploy.proto", +} diff --git a/pkg/hostman/hostdeployer/apis/deploy.proto b/pkg/hostman/hostdeployer/apis/deploy.proto new file mode 100644 index 0000000000..fbb94d9ba1 --- /dev/null +++ b/pkg/hostman/hostdeployer/apis/deploy.proto @@ -0,0 +1,159 @@ +syntax = "proto3"; + +package apis; + +message GuestDesc { + string name = 1; + string uuid = 2; + string domain = 3; + + repeated Nic nics = 4; + repeated Nic nics_standby = 5; + repeated Disk disks = 6; +} + +message Disk { + string disk_id = 1; + string driver = 2; + string cache_mode = 3; + string aio_mode = 4; + int64 size = 5; + string template_id = 6; + string image_path = 7; + string storage_id = 8; + bool migrating = 9; + string target_storage_id = 10; + string path = 11; + string format = 12; + int32 index = 13; + bool merge_snapshot = 14; + string fs = 15; + string mountpoint = 16; + string dev = 17; +} + + +message Nic { + string mac = 1; + string ip = 2; + string net = 3; + string net_id = 4; + bool virtual = 5; + string gateway = 6; + string dns = 7; + string domain = 8; + repeated Routes routes = 9; + string ifname = 10; + int32 masklen = 11; + string driver = 12; + string bridge = 13; + string wire_id = 14; + int32 vlan = 15; + string interface = 16; + int32 bw = 17; + int32 index = 18; + repeated string virtual_ips = 19; + string externel_id = 20; + string team_with = 21; + bool manual = 22; + string nic_type = 23; + bool link_up = 24; + int64 mtu = 25; + string name = 26; +} + +message Routes { + repeated string route = 1; +} + +message DeployInfo { + SSHKeys public_key = 1; + repeated DeployContent deploys = 2; + string password = 3; + bool is_init = 4; + bool enable_tty = 5; + bool default_root_user = 6; + bool windows_default_admin_user = 7; + bool enable_cloud_init = 8; +} + +message SSHKeys { + string public_key = 1; + string delete_public_key = 2; + string admin_public_key = 3; + string project_public_key = 4; +} + +message DeployContent { + string path = 1; + string content = 2; + string action = 3; +} + +message Empty { +} + +message DeployGuestFsResponse { + string distro = 1; + string version = 2; + string arch = 3; + string language = 4; + string os = 5; + string account = 6; + string key = 7; +} + +message DeployParams { + string disk_path = 1; + GuestDesc guest_desc = 2; + DeployInfo deploy_info = 3; +} + +message ResizeFsParams { + string disk_path = 1; +} + +message FormatFsParams { + string disk_path = 1; + string fs_format = 2; + string uuid = 3; +} + +message ReleaseInfo { + string distro = 1; + string version = 2; + string arch = 3; + string language = 4; +} + +message SaveToGlanceParams { + string disk_path = 1; + bool compress = 2; +} + +message SaveToGlanceResponse { + string os_info = 1; + ReleaseInfo release_info = 2; +} + +message ProbeImageInfoPramas { + string disk_path = 1; +} + +message ImageInfo { + ReleaseInfo os_info = 1; + string os_type = 2; + bool is_uefi_support = 3; + bool is_lvm_partition = 4; + bool is_readonly = 5; + string physical_partition_type = 6; + bool is_installed_cloud_init = 7; +} + +service DeployAgent { + rpc DeployGuestFs (DeployParams) returns (DeployGuestFsResponse); + rpc ResizeFs (ResizeFsParams) returns (Empty); + rpc FormatFs (FormatFsParams) returns (Empty); + rpc SaveToGlance (SaveToGlanceParams) returns (SaveToGlanceResponse); + rpc ProbeImageInfo(ProbeImageInfoPramas) returns (ImageInfo); +} \ No newline at end of file diff --git a/pkg/hostman/hostdeployer/apis/doc.go b/pkg/hostman/hostdeployer/apis/doc.go new file mode 100644 index 0000000000..577a579cfc --- /dev/null +++ b/pkg/hostman/hostdeployer/apis/doc.go @@ -0,0 +1 @@ +package apis // import "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" diff --git a/pkg/hostman/hostdeployer/apis/utils.go b/pkg/hostman/hostdeployer/apis/utils.go new file mode 100644 index 0000000000..7aa92f5d05 --- /dev/null +++ b/pkg/hostman/hostdeployer/apis/utils.go @@ -0,0 +1,114 @@ +// 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 apis + +import ( + "yunion.io/x/jsonutils" +) + +func NewDeployInfo( + publicKey *SSHKeys, + deploys []*DeployContent, + password string, + isInit bool, + enableTty bool, + defaultRootUser bool, + windowsDefaultAdminUser bool, + enableCloudInit bool, +) *DeployInfo { + return &DeployInfo{ + PublicKey: publicKey, + Deploys: deploys, + Password: password, + IsInit: isInit, + EnableTty: enableTty, + DefaultRootUser: defaultRootUser, + WindowsDefaultAdminUser: windowsDefaultAdminUser, + EnableCloudInit: enableCloudInit, + } +} + +func JsonDeploysToStructs(jdeploys []jsonutils.JSONObject) []*DeployContent { + ret := []*DeployContent{} + for i := 0; i < len(jdeploys); i++ { + d := new(DeployContent) + path, err := jdeploys[i].GetString("path") + if err == nil { + d.Path = path + } + content, err := jdeploys[i].GetString("content") + if err == nil { + d.Content = content + } + ret = append(ret, d) + } + return ret +} + +func GetKeys(data jsonutils.JSONObject) *SSHKeys { + var ret = new(SSHKeys) + ret.PublicKey, _ = data.GetString("public_key") + ret.DeletePublicKey, _ = data.GetString("delete_public_key") + ret.AdminPublicKey, _ = data.GetString("admin_public_key") + ret.ProjectPublicKey, _ = data.GetString("project_public_key") + return ret +} + +func GuestDescToDeployDesc(guestDesc *jsonutils.JSONDict) (*GuestDesc, error) { + ret := new(GuestDesc) + ret.Name, _ = guestDesc.GetString("name") + ret.Domain, _ = guestDesc.GetString("domain") + ret.Uuid, _ = guestDesc.GetString("uuid") + jnics, _ := guestDesc.Get("nics") + jdisks, _ := guestDesc.Get("disks") + jnicsStandby, _ := guestDesc.Get("nics_standby") + + if jnics != nil { + nics := make([]*Nic, 0) + err := jnics.Unmarshal(&nics) + if err != nil { + return nil, err + } + ret.Nics = nics + } + + if jdisks != nil { + disks := make([]*Disk, 0) + err := jdisks.Unmarshal(&disks) + if err != nil { + return nil, err + } + ret.Disks = disks + } + + if jnicsStandby != nil { + nicsStandby := make([]*Nic, 0) + err := jnicsStandby.Unmarshal(nicsStandby) + if err != nil { + return nil, err + } + ret.NicsStandby = nicsStandby + } + + return ret, nil +} + +func NewReleaseInfo(distro, version, arch string) *ReleaseInfo { + return &ReleaseInfo{ + Distro: distro, + Version: version, + Arch: arch, + } +} diff --git a/pkg/hostman/hostdeployer/deployclient/deployclient.go b/pkg/hostman/hostdeployer/deployclient/deployclient.go new file mode 100644 index 0000000000..7a8ede7098 --- /dev/null +++ b/pkg/hostman/hostdeployer/deployclient/deployclient.go @@ -0,0 +1,105 @@ +// 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 deployclient + +import ( + "context" + "net" + "time" + + "google.golang.org/grpc" + + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" +) + +var ( + deployClient *DeployClient + _ deployapi.DeployAgentClient = deployClient +) + +func Init(socketPath string) { + deployClient = NewDeployClient(socketPath) +} + +type DeployClient struct { + socketPath string +} + +func NewDeployClient(socketPath string) *DeployClient { + return &DeployClient{socketPath} +} + +func GetDeployClient() *DeployClient { + return deployClient +} + +func grcpDialWithUnixSocket(ctx context.Context, socketPath string) (*grpc.ClientConn, error) { + return grpc.DialContext(ctx, socketPath, grpc.WithInsecure(), grpc.WithBlock(), + grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { + return net.DialTimeout("unix", addr, timeout) + }), + ) +} + +func (c *DeployClient) DeployGuestFs(ctx context.Context, in *deployapi.DeployParams, opts ...grpc.CallOption) (*deployapi.DeployGuestFsResponse, error) { + conn, err := grcpDialWithUnixSocket(ctx, c.socketPath) + if err != nil { + return nil, err + } + defer conn.Close() + client := deployapi.NewDeployAgentClient(conn) + ret, err := client.DeployGuestFs(ctx, in, opts...) + return ret, err +} + +func (c *DeployClient) ResizeFs(ctx context.Context, in *deployapi.ResizeFsParams, opts ...grpc.CallOption) (*deployapi.Empty, error) { + conn, err := grcpDialWithUnixSocket(ctx, c.socketPath) + if err != nil { + return nil, err + } + defer conn.Close() + client := deployapi.NewDeployAgentClient(conn) + return client.ResizeFs(ctx, in, opts...) +} + +func (c *DeployClient) FormatFs(ctx context.Context, in *deployapi.FormatFsParams, opts ...grpc.CallOption) (*deployapi.Empty, error) { + conn, err := grcpDialWithUnixSocket(ctx, c.socketPath) + if err != nil { + return nil, err + } + defer conn.Close() + client := deployapi.NewDeployAgentClient(conn) + return client.FormatFs(ctx, in, opts...) +} + +func (c *DeployClient) SaveToGlance(ctx context.Context, in *deployapi.SaveToGlanceParams, opts ...grpc.CallOption) (*deployapi.SaveToGlanceResponse, error) { + conn, err := grcpDialWithUnixSocket(ctx, c.socketPath) + if err != nil { + return nil, err + } + defer conn.Close() + client := deployapi.NewDeployAgentClient(conn) + return client.SaveToGlance(ctx, in, opts...) +} + +func (c *DeployClient) ProbeImageInfo(ctx context.Context, in *deployapi.ProbeImageInfoPramas, opts ...grpc.CallOption) (*deployapi.ImageInfo, error) { + conn, err := grcpDialWithUnixSocket(ctx, c.socketPath) + if err != nil { + return nil, err + } + defer conn.Close() + client := deployapi.NewDeployAgentClient(conn) + return client.ProbeImageInfo(ctx, in, opts...) +} diff --git a/pkg/hostman/hostdeployer/deployclient/doc.go b/pkg/hostman/hostdeployer/deployclient/doc.go new file mode 100644 index 0000000000..3778fee40b --- /dev/null +++ b/pkg/hostman/hostdeployer/deployclient/doc.go @@ -0,0 +1 @@ +package deployclient // import "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" diff --git a/pkg/hostman/hostdeployer/deployserver/deployserver.go b/pkg/hostman/hostdeployer/deployserver/deployserver.go new file mode 100644 index 0000000000..f944abc638 --- /dev/null +++ b/pkg/hostman/hostdeployer/deployserver/deployserver.go @@ -0,0 +1,254 @@ +// 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 deployserver + +import ( + "context" + "errors" + "fmt" + "net" + "os" + "strings" + + "google.golang.org/grpc" + "yunion.io/x/log" + + common_options "yunion.io/x/onecloud/pkg/cloudcommon/options" + service "yunion.io/x/onecloud/pkg/cloudcommon/service" + diskutils "yunion.io/x/onecloud/pkg/hostman/diskutils" + nbd "yunion.io/x/onecloud/pkg/hostman/diskutils/nbd" + guestfs "yunion.io/x/onecloud/pkg/hostman/guestfs" + fsdriver "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" + fileutils2 "yunion.io/x/onecloud/pkg/util/fileutils2" + "yunion.io/x/onecloud/pkg/util/procutils" + "yunion.io/x/onecloud/pkg/util/sysutils" + "yunion.io/x/onecloud/pkg/util/winutils" +) + +type DeployerServer struct{} + +func (*DeployerServer) DeployGuestFs(ctx context.Context, req *deployapi.DeployParams, +) (*deployapi.DeployGuestFsResponse, error) { + log.Infof("Deploy guest fs on %s", req.DiskPath) + var kvmDisk = diskutils.NewKVMGuestDisk(req.DiskPath) + defer kvmDisk.Disconnect() + if !kvmDisk.Connect() { + log.Infof("Failed to connect kvm disk") + return new(deployapi.DeployGuestFsResponse), nil + } + + root := kvmDisk.MountKvmRootfs() + if root == nil { + log.Infof("Failed mounting rootfs for kvm disk") + return new(deployapi.DeployGuestFsResponse), nil + } + defer kvmDisk.UmountKvmRootfs(root) + + ret, err := guestfs.DoDeployGuestFs(root, req.GuestDesc, req.DeployInfo) + if err != nil { + return new(deployapi.DeployGuestFsResponse), err + } + if ret == nil { + return new(deployapi.DeployGuestFsResponse), nil + } + return ret, nil +} + +func (*DeployerServer) ResizeFs(ctx context.Context, req *deployapi.ResizeFsParams, +) (*deployapi.Empty, error) { + log.Infof("Resize fs on %s", req.DiskPath) + disk := diskutils.NewKVMGuestDisk(req.DiskPath) + defer disk.Disconnect() + if disk.Connect() { + if err := disk.ResizePartition(); err != nil { + return new(deployapi.Empty), err + } + } + return new(deployapi.Empty), nil +} + +func (*DeployerServer) FormatFs(ctx context.Context, req *deployapi.FormatFsParams) (*deployapi.Empty, error) { + log.Infof("Format fs on %s", req.DiskPath) + gd := diskutils.NewKVMGuestDisk(req.DiskPath) + defer gd.Disconnect() + if gd.Connect() { + if err := gd.MakePartition(req.FsFormat); err == nil { + err = gd.FormatPartition(req.FsFormat, req.Uuid) + if err != nil { + return new(deployapi.Empty), err + } + } else { + return new(deployapi.Empty), err + } + } + return new(deployapi.Empty), nil +} + +func (*DeployerServer) SaveToGlance(ctx context.Context, req *deployapi.SaveToGlanceParams) (*deployapi.SaveToGlanceResponse, error) { + log.Infof("%s save to glance", req.DiskPath) + var ( + kvmDisk = diskutils.NewKVMGuestDisk(req.DiskPath) + osInfo string + relInfo *deployapi.ReleaseInfo + ) + defer kvmDisk.Disconnect() + if kvmDisk.Connect() { + var err error + func() { + if root := kvmDisk.MountKvmRootfs(); root != nil { + defer kvmDisk.UmountKvmRootfs(root) + + osInfo = root.GetOs() + relInfo = root.GetReleaseInfo(root.GetPartition()) + if req.Compress { + err = root.PrepareFsForTemplate(root.GetPartition()) + } + } + }() + if err != nil { + log.Errorln(err) + return new(deployapi.SaveToGlanceResponse), err + } + + if req.Compress { + kvmDisk.Zerofree() + } + } + return &deployapi.SaveToGlanceResponse{ + OsInfo: osInfo, + ReleaseInfo: relInfo, + }, nil +} + +func getImageInfo(kvmDisk *diskutils.SKVMGuestDisk, rootfs fsdriver.IRootFsDriver) *deployapi.ImageInfo { + partition := rootfs.GetPartition() + return &deployapi.ImageInfo{ + OsInfo: rootfs.GetReleaseInfo(partition), + OsType: rootfs.GetOs(), + IsUefiSupport: kvmDisk.DetectIsUEFISupport(rootfs), + IsLvmPartition: kvmDisk.IsLVMPartition(), + IsReadonly: partition.IsReadonly(), + PhysicalPartitionType: partition.GetPhysicalPartitionType(), + IsInstalledCloudInit: rootfs.IsCloudinitInstall(), + } +} + +func (*DeployerServer) ProbeImageInfo(ctx context.Context, req *deployapi.ProbeImageInfoPramas) (*deployapi.ImageInfo, error) { + log.Infof("%s probe image info", req.DiskPath) + kvmDisk := diskutils.NewKVMGuestDisk(req.DiskPath) + defer kvmDisk.Disconnect() + if !kvmDisk.Connect() { + log.Infof("Failed to connect kvm disk") + return new(deployapi.ImageInfo), errors.New("Disk connector failed to connect image") + } + + // Fsck is executed during mount + rootfs := kvmDisk.MountKvmRootfs() + if rootfs == nil { + return new(deployapi.ImageInfo), fmt.Errorf("Failed mounting rootfs for kvm disk") + } + defer kvmDisk.UmountKvmRootfs(rootfs) + imageInfo := getImageInfo(kvmDisk, rootfs) + log.Infof("ProbeImageInfo response %s", imageInfo) + return imageInfo, nil +} + +type SDeployService struct { + *service.SServiceBase +} + +func NewDeployService() *SDeployService { + deployer := &SDeployService{} + deployer.SServiceBase = service.NewBaseService(deployer) + return deployer +} + +func (s *SDeployService) RunService() { + grpcServer := grpc.NewServer() + deployapi.RegisterDeployAgentServer(grpcServer, &DeployerServer{}) + if fileutils2.Exists(DeployOption.DeployServerSocketPath) { + if err := os.Remove(DeployOption.DeployServerSocketPath); err != nil { + log.Fatalln(err) + } + } + listener, err := net.Listen("unix", DeployOption.DeployServerSocketPath) + if err != nil { + log.Fatalln(err) + } + defer listener.Close() + log.Infof("Init net listener on %s succ", DeployOption.DeployServerSocketPath) + grpcServer.Serve(listener) +} + +func (s *SDeployService) FixPathEnv() error { + var paths = []string{ + "/usr/local/sbin", + "/usr/local/bin", + "/sbin", + "/bin", + "/usr/sbin", + "/usr/bin", + } + return os.Setenv("PATH", strings.Join(paths, ":")) +} + +func (s *SDeployService) PrepareEnv() error { + if err := s.FixPathEnv(); err != nil { + return err + } + output, err := procutils.NewCommand("rmmod", "nbd").Run() + if err != nil { + log.Errorf("rmmod error: %s", output) + } + output, err = procutils.NewCommand("modprobe", "nbd", "max_part=16").Run() + if err != nil { + log.Errorf("Failed to activate nbd device: %s", output) + } + nbd.Init() + + for i := 0; i < 16; i++ { + nbdBdi := fmt.Sprintf("/sys/block/nbd%d/bdi/", i) + sysutils.SetSysConfig(nbdBdi+"max_ratio", "0") + sysutils.SetSysConfig(nbdBdi+"min_ratio", "0") + } + + if !winutils.CheckTool(DeployOption.ChntpwPath) { + return fmt.Errorf("Failed to find chntpw tool") + } + + output, err = procutils.NewCommand("pvscan").Run() + if err != nil { + log.Errorf("Failed exec lvm command pvscan: %s", output) + } + return nil +} + +func (s *SDeployService) InitService() { + common_options.ParseOptions(&DeployOption, os.Args, "host.conf", "deploy-server") + if err := s.PrepareEnv(); err != nil { + log.Fatalln(err) + } + + fsdriver.Init(DeployOption.PrivatePrefixes) + s.O = &DeployOption.BaseOptions + if len(DeployOption.DeployServerSocketPath) == 0 { + log.Fatalf("missing deploy server socket path") + } + // TODO implentment func onExit + s.SignalTrap(nil) +} + +func (s *SDeployService) OnExitService() {} diff --git a/pkg/hostman/hostdeployer/deployserver/doc.go b/pkg/hostman/hostdeployer/deployserver/doc.go new file mode 100644 index 0000000000..e1f3eaba12 --- /dev/null +++ b/pkg/hostman/hostdeployer/deployserver/doc.go @@ -0,0 +1 @@ +package deployserver // import "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployserver" diff --git a/pkg/hostman/hostdeployer/deployserver/options.go b/pkg/hostman/hostdeployer/deployserver/options.go new file mode 100644 index 0000000000..1173f9f33f --- /dev/null +++ b/pkg/hostman/hostdeployer/deployserver/options.go @@ -0,0 +1,27 @@ +// 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 deployserver + +import "yunion.io/x/onecloud/pkg/cloudcommon/options" + +type SDeployOptions struct { + options.BaseOptions + + DeployServerSocketPath string `help:"Deploy server listen socket path"` + PrivatePrefixes []string `help:"IPv4 private prefixes"` + ChntpwPath string `help:"path to chntpw tool" default:"/usr/local/bin/chntpw.static"` +} + +var DeployOption SDeployOptions diff --git a/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go b/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go index 47796ab019..e945ae3e11 100644 --- a/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go +++ b/pkg/hostman/hostinfo/hostdhcp/dhcpserver.go @@ -98,7 +98,7 @@ func (s *SGuestDHCPServer) getGuestConfig(guestDesc, guestNic jsonutils.JSONObje masklen := nicdesc.Masklen conf.ServerIP = net.ParseIP(v4Ip.NetAddr(int8(masklen)).String()) - conf.SubnetMask = net.ParseIP(netutils2.Netlen2Mask(masklen)) + conf.SubnetMask = net.ParseIP(netutils2.Netlen2Mask(int(masklen))) conf.BroadcastAddr = v4Ip.BroadcastAddr(int8(masklen)).ToBytes() conf.Hostname, _ = guestDesc.GetString("name") conf.Domain = nicdesc.Domain diff --git a/pkg/hostman/hostinfo/hostinfo.go b/pkg/hostman/hostinfo/hostinfo.go index c6dc53257f..5038b6c6e6 100644 --- a/pkg/hostman/hostinfo/hostinfo.go +++ b/pkg/hostman/hostinfo/hostinfo.go @@ -31,14 +31,13 @@ import ( "yunion.io/x/pkg/utils" api "yunion.io/x/onecloud/pkg/apis/compute" - "yunion.io/x/onecloud/pkg/cloudcommon/sshkeys" "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/hostman/hostinfo/hostbridge" "yunion.io/x/onecloud/pkg/hostman/hostutils" "yunion.io/x/onecloud/pkg/hostman/isolated_device" "yunion.io/x/onecloud/pkg/hostman/options" "yunion.io/x/onecloud/pkg/hostman/storageman" - "yunion.io/x/onecloud/pkg/hostman/storageman/nbd" "yunion.io/x/onecloud/pkg/hostman/system_service" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules" @@ -50,7 +49,6 @@ import ( "yunion.io/x/onecloud/pkg/util/qemutils" "yunion.io/x/onecloud/pkg/util/sysutils" "yunion.io/x/onecloud/pkg/util/timeutils2" - "yunion.io/x/onecloud/pkg/util/winutils" ) type SHostInfo struct { @@ -214,25 +212,6 @@ func (h *SHostInfo) prepareEnv() error { return fmt.Errorf("Cannot initialize control group subsystem") } - output, err = procutils.NewCommand("rmmod", "nbd").Run() - if err != nil { - log.Errorf("rmmod error: %s", output) - } - output, err = procutils.NewCommand("modprobe", "nbd", "max_part=16").Run() - if err != nil { - log.Errorf("Failed to activate nbd device: %s", output) - } - nbd.Init() - - if !winutils.CheckTool(options.HostOptions.ChntpwPath) { - return fmt.Errorf("Failed to find chntpw tool") - } - - output, err = procutils.NewCommand("pvscan").Run() - if err != nil { - log.Errorf("Failed exec lvm command pvscan: %s", output) - } - if err := hostbridge.Prepare(options.HostOptions.BridgeDriver); err != nil { log.Errorln(err) return err @@ -261,11 +240,7 @@ func (h *SHostInfo) prepareEnv() error { default: return fmt.Errorf("Invalid hugepages option") } - for i := 0; i < 16; i++ { - nbdBdi := fmt.Sprintf("/sys/block/nbd%d/bdi/", i) - h.setSysConfig(nbdBdi+"max_ratio", "0") - h.setSysConfig(nbdBdi+"min_ratio", "0") - } + h.PreventArpFlux() h.TuneSystem() return nil @@ -312,7 +287,7 @@ func (h *SHostInfo) checkSystemServices() error { } } - for _, srv := range []string{"host_sdnagent"} { + for _, srv := range []string{"host_sdnagent", "host-deployer"} { srvinst := system_service.GetService(srv) if !srvinst.IsInstalled() { log.Warningf("Service %s not installed", srv) @@ -350,7 +325,7 @@ func (h *SHostInfo) DisableHugepages() { "/sys/kernel/mm/transparent_hugepage/defrag": "never", } for k, v := range kv { - h.setSysConfig(k, v) + sysutils.SetSysConfig(k, v) } } @@ -361,7 +336,7 @@ func (h *SHostInfo) EnableTransparentHugepages() { "/sys/kernel/mm/transparent_hugepage/defrag": "always", } for k, v := range kv { - h.setSysConfig(k, v) + sysutils.SetSysConfig(k, v) } } @@ -380,7 +355,7 @@ func (h *SHostInfo) EnableNativeHugepages() error { "/sys/kernel/mm/transparent_hugepage/defrag": "never", } for k, v := range kv { - h.setSysConfig(k, v) + sysutils.SetSysConfig(k, v) } preAllocPagesNum := h.GetMemory()/h.Mem.GetHugepagesizeMb() + 1 err := timeutils2.CommandWithTimeout(1, "sh", "-c", fmt.Sprintf("echo %d > /proc/sys/vm/nr_hugepages", preAllocPagesNum)).Run() @@ -397,36 +372,18 @@ func (h *SHostInfo) EnableNativeHugepages() error { return nil } -func (h *SHostInfo) setSysConfig(cpath, val string) bool { - if fileutils2.Exists(cpath) { - oval, err := ioutil.ReadFile(cpath) - if err != nil { - log.Errorln(err) - return false - } - if string(oval) != val { - err = fileutils2.FilePutContents(cpath, val, false) - if err == nil { - return true - } - log.Errorln(err) - } - } - return false -} - func (h *SHostInfo) EnableKsm(sleepSec int) { - h.setSysConfig("/sys/kernel/mm/ksm/run", "1") - h.setSysConfig("/sys/kernel/mm/ksm/sleep_millisecs", + sysutils.SetSysConfig("/sys/kernel/mm/ksm/run", "1") + sysutils.SetSysConfig("/sys/kernel/mm/ksm/sleep_millisecs", fmt.Sprintf("%d", sleepSec*1000)) } func (h *SHostInfo) DisableKsm() { - h.setSysConfig("/sys/kernel/mm/ksm/run", "0") + sysutils.SetSysConfig("/sys/kernel/mm/ksm/run", "0") } func (h *SHostInfo) PreventArpFlux() { - h.setSysConfig("/proc/sys/net/ipv4/conf/all/arp_filter", "1") + sysutils.SetSysConfig("/proc/sys/net/ipv4/conf/all/arp_filter", "1") } // Any system wide optimizations @@ -436,7 +393,7 @@ func (h *SHostInfo) TuneSystem() { "/sys/module/kvm/parameters/ignore_msrs": "1", } for k, v := range kv { - h.setSysConfig(k, v) + sysutils.SetSysConfig(k, v) } } @@ -1158,7 +1115,7 @@ func (h *SHostInfo) deployAdminAuthorizedKeys() { } keys := ret.Data[0] adminPublicKey, _ := keys.GetString("public_key") - pubKeys := &sshkeys.SSHKeys{AdminPublicKey: adminPublicKey} + pubKeys := &deployapi.SSHKeys{AdminPublicKey: adminPublicKey} authFile := path.Join(sshDir, "authorized_keys") oldKeysBytes, _ := fileutils2.FileGetContents(authFile) diff --git a/pkg/hostman/options/options.go b/pkg/hostman/options/options.go index 272f03028b..c520ce9a78 100644 --- a/pkg/hostman/options/options.go +++ b/pkg/hostman/options/options.go @@ -63,7 +63,7 @@ type SHostOptions struct { LocalImagePath []string `help:"Local image storage paths"` SharedStorages []string `help:"Path of shared storages"` - DefaultQemuVersion string `help:"Default qemu version" default:"2.9.1"` + DefaultQemuVersion string `help:"Default qemu version" default:"2.12.1"` DhcpRelay []string `help:"DHCP relay upstream"` DhcpLeaseTime int `default:"100663296" help:"DHCP lease time in seconds"` @@ -104,6 +104,8 @@ type SHostOptions struct { HostCpuPassthrough bool `default:"true" help:"if it is true, set qemu cpu type as -cpu host, otherwise, qemu64. default is true"` MaxReservedMemory int `default:"10240" help:"host reserved memory"` + + DeployServerSocketPath string `help:"Deploy server listen socket path"` } var HostOptions SHostOptions diff --git a/pkg/hostman/storageman/core.go b/pkg/hostman/storageman/core.go index 4e171ae3ec..4a9ea86280 100644 --- a/pkg/hostman/storageman/core.go +++ b/pkg/hostman/storageman/core.go @@ -61,7 +61,7 @@ func NewStorageManager(host hostutils.IHost) (*SStorageManager, error) { for i, d := range options.HostOptions.LocalImagePath { s := NewLocalStorage(ret, d, i) if s.Accessible() { - s.StartSnapshotRecycle() + StartSnapshotRecycle(s) ret.Storages = append(ret.Storages, s) if allFull && s.GetFreeSizeMb() > MINIMAL_FREE_SPACE { allFull = false diff --git a/pkg/hostman/storageman/disk_base.go b/pkg/hostman/storageman/disk_base.go index be1034d110..b9dadf2b10 100644 --- a/pkg/hostman/storageman/disk_base.go +++ b/pkg/hostman/storageman/disk_base.go @@ -19,10 +19,12 @@ import ( "fmt" "path" + "github.com/pkg/errors" "yunion.io/x/jsonutils" "yunion.io/x/log" - "yunion.io/x/onecloud/pkg/hostman/guestfs" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" + "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" ) type IDisk interface { @@ -33,6 +35,7 @@ type IDisk interface { GetSnapshotDir() string GetDiskDesc() jsonutils.JSONObject GetDiskSetupScripts(idx int) string + GetSnapshotLocation() string DeleteAllSnapshot() error Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) @@ -42,16 +45,17 @@ type IDisk interface { CleanupSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) PrepareMigrate(liveMigrate bool) (string, error) - CreateFromUrl(context.Context, string) error + CreateFromUrl(ctx context.Context, url string, size int64) error CreateFromTemplate(context.Context, string, string, int64) (jsonutils.JSONObject, error) - CreateFromImageFuse(context.Context, string) error + CreateFromSnapshotLocation(ctx context.Context, location string, size int64) error + CreateFromImageFuse(ctx context.Context, url string, size int64) error CreateRaw(ctx context.Context, sizeMb int, diskFromat string, fsFormat string, encryption bool, diskId string, back string) (jsonutils.JSONObject, error) PostCreateFromImageFuse() CreateSnapshot(snapshotId string) error DeleteSnapshot(snapshotId, convertSnapshot string, pendingDelete bool) error DeployGuestFs(diskPath string, guestDesc *jsonutils.JSONDict, - deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error) + deployInfo *deployapi.DeployInfo) (jsonutils.JSONObject, error) } type SBaseDisk struct { @@ -82,7 +86,7 @@ func (d *SBaseDisk) Delete(ctx context.Context, params interface{}) (jsonutils.J return nil, fmt.Errorf("Not implemented") } -func (d *SBaseDisk) CreateFromUrl(context.Context, string) error { +func (d *SBaseDisk) CreateFromUrl(ctx context.Context, url string, size int64) error { return fmt.Errorf("Not implemented") } @@ -90,6 +94,10 @@ func (d *SBaseDisk) CreateFromTemplate(context.Context, string, string, int64) ( return nil, fmt.Errorf("Not implemented") } +func (d *SBaseDisk) CreateFromSnapshotLocation(ctx context.Context, location string, size int64) error { + return fmt.Errorf("Not implemented") +} + func (d *SBaseDisk) Resize(context.Context, interface{}) (jsonutils.JSONObject, error) { return nil, fmt.Errorf("Not implemented") } @@ -99,36 +107,49 @@ func (d *SBaseDisk) GetZone() string { } func (d *SBaseDisk) DeployGuestFs(diskPath string, guestDesc *jsonutils.JSONDict, - deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error) { - var kvmDisk = NewKVMGuestDisk(diskPath) - - defer kvmDisk.Disconnect() - if !kvmDisk.Connect() { - log.Infof("Failed to connect kvm disk") - return nil, nil + deployInfo *deployapi.DeployInfo) (jsonutils.JSONObject, error) { + deployGuestDesc, err := deployapi.GuestDescToDeployDesc(guestDesc) + if err != nil { + return nil, errors.Wrap(err, "guest desc to deploy desc") } - - root := kvmDisk.MountKvmRootfs() - if root == nil { - log.Infof("Failed mounting rootfs for kvm disk") - return nil, nil + ret, err := deployclient.GetDeployClient().DeployGuestFs( + context.Background(), &deployapi.DeployParams{ + DiskPath: diskPath, + GuestDesc: deployGuestDesc, + DeployInfo: deployInfo, + }, + ) + if err != nil { + return nil, errors.Wrap(err, "request deploy guest fs") } - defer kvmDisk.UmountKvmRootfs(root) - - return guestfs.DeployGuestFs(root, guestDesc, deployInfo) + return jsonutils.Marshal(ret), nil } func (d *SBaseDisk) ResizeFs(diskPath string) error { - disk := NewKVMGuestDisk(diskPath) - defer disk.Disconnect() - if disk.Connect() { - if err := disk.ResizePartition(); err != nil { - return err - } - } - return nil + _, err := deployclient.GetDeployClient().ResizeFs( + context.Background(), &deployapi.ResizeFsParams{DiskPath: diskPath}) + return err } func (d *SBaseDisk) GetDiskSetupScripts(diskIndex int) string { return "" } + +func (d *SBaseDisk) GetSnapshotLocation() string { + return "" +} + +func (d *SBaseDisk) FormatFs(fsFormat, uuid, diskPath string) { + log.Infof("Make disk %s fs %s", uuid, fsFormat) + _, err := deployclient.GetDeployClient().FormatFs( + context.Background(), + &deployapi.FormatFsParams{ + DiskPath: diskPath, + FsFormat: fsFormat, + Uuid: uuid, + }, + ) + if err != nil { + log.Errorf("Format fs error : %s", err) + } +} diff --git a/pkg/hostman/storageman/disk_local.go b/pkg/hostman/storageman/disk_local.go index da622dc722..cb80daaa7f 100644 --- a/pkg/hostman/storageman/disk_local.go +++ b/pkg/hostman/storageman/disk_local.go @@ -73,6 +73,10 @@ func (d *SLocalDisk) GetSnapshotDir() string { return path.Join(d.Storage.GetSnapshotDir(), d.Id+options.HostOptions.SnapshotDirSuffix) } +func (d *SLocalDisk) GetSnapshotLocation() string { + return d.GetSnapshotDir() +} + func (d *SLocalDisk) Probe() error { if fileutils2.Exists(d.getPath()) { d.isAlter = false @@ -137,7 +141,7 @@ func (d *SLocalDisk) Resize(ctx context.Context, params interface{}) (jsonutils. return d.GetDiskDesc(), nil } -func (d *SLocalDisk) CreateFromImageFuse(ctx context.Context, url string) error { +func (d *SLocalDisk) CreateFromImageFuse(ctx context.Context, url string, size int64) error { log.Infof("Create from image fuse %s", url) var ( @@ -223,7 +227,7 @@ func (d *SLocalDisk) createFromTemplate( } } -func (d *SLocalDisk) CreateFromUrl(ctx context.Context, url string) error { +func (d *SLocalDisk) CreateFromUrl(ctx context.Context, url string, size int64) error { remoteFile := remotefile.NewRemoteFile(ctx, url, d.getPath(), false, "", -1, nil, "", "") if remoteFile.Fetch() { if options.HostOptions.EnableFallocateDisk { @@ -267,28 +271,12 @@ func (d *SLocalDisk) CreateRaw(ctx context.Context, sizeMB int, diskFormat, fsFo } if utils.IsInStringArray(fsFormat, []string{"swap", "ext2", "ext3", "ext4", "xfs"}) { - d.FormatFs(fsFormat, uuid) + d.FormatFs(fsFormat, uuid, d.GetPath()) } return d.GetDiskDesc(), nil } -func (d *SLocalDisk) FormatFs(fsFormat, uuid string) { - log.Infof("Make disk %s fs %s", uuid, fsFormat) - gd := NewKVMGuestDisk(d.GetPath()) - defer gd.Disconnect() - if gd.Connect() { - if err := gd.MakePartition(fsFormat); err == nil { - err = gd.FormatPartition(fsFormat, uuid) - if err != nil { - log.Errorln(err) - } - } else { - log.Errorln(err) - } - } -} - func (d *SLocalDisk) GetDiskDesc() jsonutils.JSONObject { qemuImg, err := qemuimg.NewQemuImage(d.getPath()) if err != nil { diff --git a/pkg/hostman/storageman/disk_nas.go b/pkg/hostman/storageman/disk_nas.go index ac555e9b31..1ee113347a 100644 --- a/pkg/hostman/storageman/disk_nas.go +++ b/pkg/hostman/storageman/disk_nas.go @@ -16,10 +16,15 @@ package storageman import ( "context" + "fmt" + "path" + "github.com/pkg/errors" "yunion.io/x/jsonutils" "yunion.io/x/log" + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/util/qemuimg" ) type SNasDisk struct { @@ -46,6 +51,41 @@ func (d *SNasDisk) CreateFromTemplate(ctx context.Context, imageId, format strin return ret, nil } +func (d *SNasDisk) CreateFromImageFuse(ctx context.Context, url string, size int64) error { + return fmt.Errorf("Not implemented") +} + +func (d *SNasDisk) CreateFromSnapshotLocation(ctx context.Context, snapshotLocation string, size int64) error { + snapshotPath := path.Join(d.Storage.GetPath(), snapshotLocation) + newImg, err := qemuimg.NewQemuImage(d.GetPath()) + if err != nil { + return errors.Wrap(err, "new image from snapshot") + } + if newImg.IsValid() { + if err := newImg.Delete(); err != nil { + log.Errorln(err) + return err + } + } + err = newImg.CreateQcow2(0, false, snapshotPath) + if err != nil { + return errors.Wrap(err, "create image from snapshot") + } + retSize, _ := d.GetDiskDesc().Int("disk_size") + log.Infof("REQSIZE: %d, RETSIZE: %d", size, retSize) + if size > retSize { + params := jsonutils.NewDict() + params.Set("size", jsonutils.NewInt(size)) + _, err = d.Resize(ctx, params) + return err + } + return nil +} + +func (d *SNasDisk) GetSnapshotLocation() string { + return d.GetSnapshotDir()[len(d.Storage.GetPath())+1:] +} + type SNFSDisk struct { SNasDisk } diff --git a/pkg/hostman/storageman/disk_rbd.go b/pkg/hostman/storageman/disk_rbd.go index abe6ea9d21..0287326da9 100644 --- a/pkg/hostman/storageman/disk_rbd.go +++ b/pkg/hostman/storageman/disk_rbd.go @@ -147,10 +147,6 @@ func (d *SRBDDisk) PrepareMigrate(liveMigrate bool) (string, error) { return "", fmt.Errorf("Not support") } -func (d *SRBDDisk) CreateFromUrl(context.Context, string) error { - return fmt.Errorf("Not impl") -} - func (d *SRBDDisk) CreateFromTemplate(ctx context.Context, imageId string, format string, size int64) (jsonutils.JSONObject, error) { ret, err := d.createFromTemplate(ctx, imageId, format) if err != nil { @@ -186,7 +182,7 @@ func (d *SRBDDisk) createFromTemplate(ctx context.Context, imageId, format strin return d.GetDiskDesc(), nil } -func (d *SRBDDisk) CreateFromImageFuse(context.Context, string) error { +func (d *SRBDDisk) CreateFromImageFuse(ctx context.Context, url string, size int64) error { return fmt.Errorf("Not support") } @@ -198,28 +194,12 @@ func (d *SRBDDisk) CreateRaw(ctx context.Context, sizeMb int, diskFromat string, } if utils.IsInStringArray(fsFormat, []string{"swap", "ext2", "ext3", "ext4", "xfs"}) { - d.FormatFs(fsFormat, diskId) + d.FormatFs(fsFormat, diskId, d.GetPath()) } return d.GetDiskDesc(), nil } -func (d *SRBDDisk) FormatFs(fsFormat, uuid string) { - log.Infof("Make disk %s fs %s", uuid, fsFormat) - gd := NewKVMGuestDisk(d.GetPath()) - defer gd.Disconnect() - if gd.Connect() { - if err := gd.MakePartition(fsFormat); err == nil { - err = gd.FormatPartition(fsFormat, uuid) - if err != nil { - log.Errorln(err) - } - } else { - log.Errorln(err) - } - } -} - func (d *SRBDDisk) PostCreateFromImageFuse() { log.Errorf("Not support PostCreateFromImageFuse") } diff --git a/pkg/hostman/diskhandlers/diskhandler.go b/pkg/hostman/storageman/diskhandlers/diskhandler.go similarity index 100% rename from pkg/hostman/diskhandlers/diskhandler.go rename to pkg/hostman/storageman/diskhandlers/diskhandler.go diff --git a/pkg/hostman/diskhandlers/doc.go b/pkg/hostman/storageman/diskhandlers/doc.go similarity index 96% rename from pkg/hostman/diskhandlers/doc.go rename to pkg/hostman/storageman/diskhandlers/doc.go index 65bb6b6b21..3d20263950 100644 --- a/pkg/hostman/diskhandlers/doc.go +++ b/pkg/hostman/storageman/diskhandlers/doc.go @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -package diskhandlers // import "yunion.io/x/onecloud/pkg/hostman/diskhandlers" +package diskhandlers // import "yunion.io/x/onecloud/pkg/hostman/storageman/diskhandlers" diff --git a/pkg/hostman/storageman/storage_base.go b/pkg/hostman/storageman/storage_base.go index 6205b0f5a9..444c6b7833 100644 --- a/pkg/hostman/storageman/storage_base.go +++ b/pkg/hostman/storageman/storage_base.go @@ -17,21 +17,37 @@ package storageman import ( "context" "fmt" + "io/ioutil" + "path" + "regexp" "strings" "sync" "syscall" + "time" "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/utils" + "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudcommon/cronman" "yunion.io/x/onecloud/pkg/hostman/hostutils" + "yunion.io/x/onecloud/pkg/hostman/options" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/mcclient/modules" + "yunion.io/x/onecloud/pkg/util/fileutils2" + "yunion.io/x/onecloud/pkg/util/procutils" + "yunion.io/x/onecloud/pkg/util/qemuimg" ) const ( _RECYCLE_BIN_ = "recycle_bin" _IMGSAVE_BACKUPS_ = "imgsave_backups" + _SNAPSHOT_PATH_ = "snapshots" ) +var DELETEING_SNAPSHOTS = sync.Map{} + type IStorageFactory interface { NewStorage(manager *SStorageManager, mountPoint string) IStorage StorageType() string @@ -275,30 +291,167 @@ func (s *SBaseStorage) CreateDiskFromSnpashot(ctx context.Context, disk IDisk, c // diskPath = path.Join(s.Path, createParams.DiskId) snapshotUrl, _ = createParams.DiskInfo.GetString("snapshot_url") transferProtocol, _ = createParams.DiskInfo.GetString("protocol") + diskSize, _ = createParams.DiskInfo.Int("size") ) if len(snapshotUrl) == 0 || len(transferProtocol) == 0 { return nil, fmt.Errorf("Create disk from snapshot missing params snapshot url or protocol") } - - if transferProtocol == "url" { - // TODO - // snapshotOutOfChain := jsonutils.QueryBoolean( - // createParams.DiskInfo, "snapshot_out_of_chain", false) - // // you wen ti... - // if err := s.CreateDiskFromUrl(ctx, snapshotUrl, diskPath, !snapshotOutOfChain); err != nil { - // return nil, err - // } - } else if transferProtocol == "fuse" { - if err := disk.CreateFromImageFuse(ctx, snapshotUrl); err != nil { - return nil, err + if createParams.Storage.StorageType() == compute.STORAGE_LOCAL { + if transferProtocol == "url" { + // not implement + } else if transferProtocol == "fuse" { + if err := disk.CreateFromImageFuse(ctx, snapshotUrl, diskSize); err != nil { + return nil, err + } + } else { + return nil, fmt.Errorf("Unkown protocol %s", transferProtocol) + } + } else if utils.IsInStringArray(createParams.Storage.StorageType(), compute.SHARED_FILE_STORAGE) { + if transferProtocol == "location" { + if err := disk.CreateFromSnapshotLocation(ctx, snapshotUrl, diskSize); err != nil { + return nil, err + } + } else { + return nil, fmt.Errorf("Unkown protocol %s", transferProtocol) } - } else { - return nil, fmt.Errorf("Unkown protocol %s", transferProtocol) } + return disk.GetDiskDesc(), nil } func (s *SBaseStorage) DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string, desc, disksBackingFile, srcSnapshots jsonutils.JSONObject) error { return nil } + +/*************************Background delete snapshot job****************************/ + +func StartSnapshotRecycle(storage IStorage) { + log.Infof("Snapshot recyle job started") + if !fileutils2.Exists(storage.GetSnapshotDir()) { + procutils.NewCommand("mkdir", "-p", storage.GetSnapshotDir()).Run() + } + cronman.GetCronJobManager(false).AddJob1( + "SnapshotRecycle", time.Hour*6, + func(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) { + snapshotRecycle(ctx, userCred, isStart, storage) + }) +} + +func snapshotRecycle(ctx context.Context, userCred mcclient.TokenCredential, isStart bool, storage IStorage) { + log.Infof("Snapshot Recycle Job Start, storage is %s, ss dir is %s", storage.GetStorageName(), storage.GetSnapshotDir()) + res, err := modules.Snapshots.GetById(hostutils.GetComputeSession(ctx), "max-count", nil) + if err != nil { + log.Errorln(err) + return + } + maxSnapshotCount, err := res.Int("max_count") + if err != nil { + log.Errorln("Request region get snapshot max count failed") + return + } + files, err := ioutil.ReadDir(storage.GetSnapshotDir()) + if err != nil { + log.Errorln(err) + return + } + for _, file := range files { + checkSnapshots(storage, file.Name(), int(maxSnapshotCount)) + } +} + +func checkSnapshots(storage IStorage, snapshotDir string, maxSnapshotCount int) { + re := regexp.MustCompile(`^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}_snap$`) + if !re.MatchString(snapshotDir) { + log.Warningf("snapshot_dir got unexcept file %s", snapshotDir) + return + } + diskId := snapshotDir[:len(snapshotDir)-len(options.HostOptions.SnapshotDirSuffix)] + snapshotPath := path.Join(storage.GetSnapshotDir(), snapshotDir) + + // If disk is Deleted, request delete this disk all snapshots + if !fileutils2.Exists(path.Join(storage.GetPath(), diskId)) && fileutils2.Exists(snapshotPath) { + params := jsonutils.NewDict() + params.Set("disk_id", jsonutils.NewString(diskId)) + _, err := modules.Snapshots.PerformClassAction( + hostutils.GetComputeSession(context.Background()), + "delete-disk-snapshots", params) + if err != nil { + log.Infof("Request delele disk %s snapshots failed %s", diskId, err) + } + return + } + + snapshots, err := ioutil.ReadDir(snapshotPath) + if err != nil { + log.Errorln(err) + return + } + + // if snapshot count greater than maxsnapshot count, do convert + if len(snapshots) >= maxSnapshotCount { + requestConvertSnapshot(snapshotPath, diskId) + } +} + +func requestConvertSnapshot(snapshotPath, diskId string) { + log.Infof("SNPASHOT path %s", snapshotPath) + res, err := modules.Disks.GetSpecific( + hostutils.GetComputeSession(context.Background()), diskId, "convert-snapshot", nil) + if err != nil { + log.Errorln(err) + return + } + + var ( + deleteSnapshot, _ = res.GetString("delete_snapshot") + convertSnapshot, _ = res.GetString("convert_snapshot") + pendingDelete, _ = res.Bool("pending_delete") + ) + log.Infof("start convert disk(%s) snapshot(%s), delete_snapshot is %s", + diskId, convertSnapshot, deleteSnapshot) + convertSnapshotPath := path.Join(snapshotPath, convertSnapshot) + outfile := convertSnapshotPath + ".tmp" + img, err := qemuimg.NewQemuImage(convertSnapshotPath) + if err != nil { + log.Errorln(err) + return + } + log.Infof("convertSnapshot path %s", convertSnapshotPath) + err = img.Convert2Qcow2To(outfile, true) + if err != nil { + log.Errorln(err) + return + } + requestDeleteSnapshot( + diskId, snapshotPath, deleteSnapshot, convertSnapshotPath, outfile, pendingDelete) +} + +func requestDeleteSnapshot( + diskId, snapshotPath, deleteSnapshot, convertSnapshotPath, + outfile string, pendingDelete bool, +) { + deleteSnapshotPath := path.Join(snapshotPath, deleteSnapshot) + DELETEING_SNAPSHOTS.Store(diskId, true) + defer DELETEING_SNAPSHOTS.Delete(diskId) + _, err := modules.Snapshots.PerformAction(hostutils.GetComputeSession(context.Background()), + deleteSnapshot, "deleted", nil) + if err != nil { + log.Errorln(err) + return + } + if out, err := procutils.NewCommand("rm", "-f", convertSnapshotPath).Run(); err != nil { + log.Errorf("%s", out) + return + } + if out, err := procutils.NewCommand("mv", "-f", outfile, convertSnapshotPath).Run(); err != nil { + log.Errorf("%s", out) + return + } + if !pendingDelete { + if out, err := procutils.NewCommand("rm", "-f", deleteSnapshotPath).Run(); err != nil { + log.Errorf("%s", out) + return + } + } +} diff --git a/pkg/hostman/storageman/storage_gpfs.go b/pkg/hostman/storageman/storage_gpfs.go index 5d44debf25..56dbd2aa29 100644 --- a/pkg/hostman/storageman/storage_gpfs.go +++ b/pkg/hostman/storageman/storage_gpfs.go @@ -48,5 +48,6 @@ func (s *SGPFSStorage) StorageType() string { func NewGPFSStorage(manager *SStorageManager, path string) *SGPFSStorage { ret := &SGPFSStorage{} ret.SNasStorage = *NewNasStorage(manager, path, ret) + StartSnapshotRecycle(ret) return ret } diff --git a/pkg/hostman/storageman/storage_local.go b/pkg/hostman/storageman/storage_local.go index 439142cfa4..854917ecd5 100644 --- a/pkg/hostman/storageman/storage_local.go +++ b/pkg/hostman/storageman/storage_local.go @@ -17,10 +17,8 @@ package storageman import ( "context" "fmt" - "io/ioutil" "os" "path" - "regexp" "time" "yunion.io/x/jsonutils" @@ -28,12 +26,11 @@ import ( "yunion.io/x/pkg/util/timeutils" api "yunion.io/x/onecloud/pkg/apis/compute" - "yunion.io/x/onecloud/pkg/cloudcommon/cronman" - "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" + "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" "yunion.io/x/onecloud/pkg/hostman/hostutils" "yunion.io/x/onecloud/pkg/hostman/options" "yunion.io/x/onecloud/pkg/hostman/storageman/remotefile" - "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/fileutils2" "yunion.io/x/onecloud/pkg/util/procutils" @@ -41,10 +38,8 @@ import ( ) var ( - _FUSE_MOUNT_PATH_ = "fusemnt" - _FUSE_TMP_PATH_ = "fusetmp" - _SNAPSHOT_PATH_ = "snapshots" - DELETEING_SNAPSHOTS = map[string]bool{} + _FUSE_MOUNT_PATH_ = "fusemnt" + _FUSE_TMP_PATH_ = "fusetmp" ) type SLocalStorage struct { @@ -229,38 +224,9 @@ func (s *SLocalStorage) SaveToGlance(ctx context.Context, params interface{}) (j func (s *SLocalStorage) saveToGlance(ctx context.Context, imageId, imagePath string, compress bool, format string) error { - var ( - kvmDisk = NewKVMGuestDisk(imagePath) - osInfo string - relInfo *fsdriver.SReleaseInfo - ) - - if err := func() error { - defer kvmDisk.Disconnect() - if kvmDisk.Connect() { - var err error - func() { - if root := kvmDisk.MountKvmRootfs(); root != nil { - defer kvmDisk.UmountKvmRootfs(root) - - osInfo = root.GetOs() - relInfo = root.GetReleaseInfo(root.GetPartition()) - if compress { - err = root.PrepareFsForTemplate(root.GetPartition()) - } - } - }() - if err != nil { - log.Errorln(err) - return err - } - - if compress { - kvmDisk.Zerofree() - } - } - return nil - }(); err != nil { + ret, err := deployclient.GetDeployClient().SaveToGlance(context.Background(), + &deployapi.SaveToGlanceParams{DiskPath: imagePath, Compress: compress}) + if err != nil { return err } @@ -298,9 +264,10 @@ func (s *SLocalStorage) saveToGlance(ctx context.Context, imageId, imagePath str size := finfo.Size() var params = jsonutils.NewDict() - if len(osInfo) > 0 { - params.Set("os_type", jsonutils.NewString(osInfo)) + if len(ret.OsInfo) > 0 { + params.Set("os_type", jsonutils.NewString(ret.OsInfo)) } + relInfo := ret.ReleaseInfo if relInfo != nil { params.Set("os_distribution", jsonutils.NewString(relInfo.Distro)) if len(relInfo.Version) > 0 { @@ -317,8 +284,6 @@ func (s *SLocalStorage) saveToGlance(ctx context.Context, imageId, imagePath str _, err = modules.Images.Upload(hostutils.GetImageSession(ctx, s.GetZone()), params, f, size) - // TODO - // notify_template_ready return err } @@ -357,132 +322,6 @@ func (s *SLocalStorage) DeleteSnapshots(ctx context.Context, params interface{}) return nil, nil } -/*************************Background delete snapshot job****************************/ - -func (s *SLocalStorage) StartSnapshotRecycle() { - log.Infof("Snapshot recyle job started") - if !fileutils2.Exists(s.GetSnapshotDir()) { - procutils.NewCommand("mkdir", "-p", s.GetSnapshotDir()).Run() - } - cronman.GetCronJobManager(false).AddJob2("SnapshotRecycle", options.HostOptions.SnapshotRecycleDay, 2, 0, 0, s.snapshotRecycle, true) -} - -func (s *SLocalStorage) snapshotRecycle(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) { - res, err := modules.Snapshots.GetById(hostutils.GetComputeSession(ctx), "max-count", nil) - if err != nil { - log.Errorln(err) - return - } - maxSnapshotCount, err := res.Int("max_count") - if err != nil { - log.Errorln("Request region get snapshot max count failed") - return - } - files, err := ioutil.ReadDir(s.GetSnapshotDir()) - if err != nil { - log.Errorln(err) - return - } - for _, file := range files { - s.checkSnapshots(file.Name(), int(maxSnapshotCount)) - } -} - -func (s *SLocalStorage) checkSnapshots(snapshotDir string, maxSnapshotCount int) { - re := regexp.MustCompile(`^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}_snap$`) - if !re.MatchString(snapshotDir) { - log.Warningf("snapshot_dir got unexcept file %s", snapshotDir) - return - } - - diskId := snapshotDir[:len(snapshotDir)-len(options.HostOptions.SnapshotDirSuffix)] - snapshotPath := path.Join(s.GetSnapshotDir(), snapshotDir) - - // If disk is Deleted, request delete this disk all snapshots - if !fileutils2.Exists(path.Join(s.Path, diskId)) && fileutils2.Exists(snapshotPath) { - params := jsonutils.NewDict() - params.Set("disk_id", jsonutils.NewString(diskId)) - _, err := modules.Snapshots.PerformClassAction( - hostutils.GetComputeSession(context.Background()), - "delete-disk-snapshots", params) - if err != nil { - log.Infof("Request delele disk %s snapshots failed %s", diskId, err) - } - return - } - - snapshots, err := ioutil.ReadDir(snapshotPath) - if err != nil { - log.Errorln(err) - return - } - - // if snapshot count greater than maxsnapshot count, do convert - if len(snapshots) >= maxSnapshotCount { - s.requestConvertSnapshot(snapshotPath, diskId) - } -} - -func (s *SLocalStorage) requestConvertSnapshot(snapshotPath, diskId string) { - res, err := modules.Disks.GetSpecific( - hostutils.GetComputeSession(context.Background()), diskId, "convert-snapshot", nil) - if err != nil { - log.Errorln(err) - return - } - - var ( - deleteSnapshot, _ = res.GetString("delete_snapshot") - convertSnapshot, _ = res.GetString("convert_snapshot") - pendingDelete, _ = res.Bool("pending_delete") - ) - log.Infof("start convert disk(%s) snapshot(%s), delete_snapshot is %s", - diskId, convertSnapshot, deleteSnapshot) - convertSnapshotPath := path.Join(snapshotPath, convertSnapshot) - outfile := convertSnapshotPath + ".tmp" - img, err := qemuimg.NewQemuImage(convertSnapshot) - if err != nil { - log.Errorln(err) - return - } - err = img.Convert2Qcow2To(outfile, true) - if err != nil { - log.Errorln(err) - return - } - s.requestDeleteSnapshot( - diskId, snapshotPath, deleteSnapshot, convertSnapshotPath, outfile, pendingDelete) -} - -func (s *SLocalStorage) requestDeleteSnapshot( - diskId, snapshotPath, deleteSnapshot, convertSnapshotPath, - outfile string, pendingDelete bool, -) { - deleteSnapshotPath := path.Join(snapshotPath, deleteSnapshot) - DELETEING_SNAPSHOTS[diskId] = true - defer delete(DELETEING_SNAPSHOTS, diskId) - _, err := modules.Snapshots.PerformAction(hostutils.GetComputeSession(context.Background()), - deleteSnapshot, "deleted", nil) - if err != nil { - log.Errorln(err) - return - } - if out, err := procutils.NewCommand("rm", "-f", convertSnapshotPath).Run(); err != nil { - log.Errorf("%s", out) - return - } - if out, err := procutils.NewCommand("mv", "-f", outfile, convertSnapshotPath).Run(); err != nil { - log.Errorf("%s", out) - return - } - if !pendingDelete { - if out, err := procutils.NewCommand("rm", "-f", deleteSnapshotPath).Run(); err != nil { - log.Errorf("%s", out) - return - } - } -} - func (s *SLocalStorage) DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string, desc, disksBackingFile, srcSnapshots jsonutils.JSONObject) error { disks, _ := desc.GetArray("disks") for i, diskinfo := range disks { @@ -529,7 +368,7 @@ func (s *SLocalStorage) DestinationPrepareMigrate(ctx context.Context, liveMigra } else { // download disk form remote url diskUrl := fmt.Sprintf("%s/%s/%s", disksUri, diskStorageId, diskId) - if err := disk.CreateFromUrl(ctx, diskUrl); err != nil { + if err := disk.CreateFromUrl(ctx, diskUrl, 0); err != nil { log.Errorln(err) return err } diff --git a/pkg/hostman/storageman/storage_nas.go b/pkg/hostman/storageman/storage_nas.go index 4d8b92605b..08304fdad0 100644 --- a/pkg/hostman/storageman/storage_nas.go +++ b/pkg/hostman/storageman/storage_nas.go @@ -17,6 +17,7 @@ package storageman import ( "context" "fmt" + "path" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -37,7 +38,16 @@ type SNasStorage struct { } func NewNasStorage(manager *SStorageManager, path string, ins INasStorage) *SNasStorage { - return &SNasStorage{*NewLocalStorage(manager, path, 0), ins} + ret := &SNasStorage{*NewLocalStorage(manager, path, 0), ins} + return ret +} + +func (s *SNasStorage) GetComposedName() string { + return fmt.Sprintf("host_%s_%s_storage_%d", s.Manager.host.GetMasterIp(), s.ins.StorageType(), s.Index) +} + +func (s *SNasStorage) GetSnapshotDir() string { + return path.Join(s.Path, s.GetComposedName(), _SNAPSHOT_PATH_) } func (s *SNasStorage) CreateDisk(diskId string) IDisk { diff --git a/pkg/hostman/storageman/storage_nfs.go b/pkg/hostman/storageman/storage_nfs.go index 0fe46b97ad..6cf33e8759 100644 --- a/pkg/hostman/storageman/storage_nfs.go +++ b/pkg/hostman/storageman/storage_nfs.go @@ -45,15 +45,16 @@ func (factory *SNFSStorageFactory) StorageType() string { } type SNFSStorage struct { - SLocalStorage + SNasStorage } func NewNFSStorage(manager *SStorageManager, path string) *SNFSStorage { ret := &SNFSStorage{} - ret.SLocalStorage = *NewLocalStorage(manager, path, 0) + ret.SNasStorage = *NewNasStorage(manager, path, ret) if !fileutils2.Exists(path) { procutils.NewCommand("mkdir", "-p", path).Run() } + StartSnapshotRecycle(ret) return ret } diff --git a/pkg/hostman/storageman/storage_rbd.go b/pkg/hostman/storageman/storage_rbd.go index 18c2543d20..9ca2eac8af 100644 --- a/pkg/hostman/storageman/storage_rbd.go +++ b/pkg/hostman/storageman/storage_rbd.go @@ -31,7 +31,8 @@ import ( "yunion.io/x/pkg/utils" api "yunion.io/x/onecloud/pkg/apis/compute" - "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" + "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" "yunion.io/x/onecloud/pkg/hostman/hostutils" "yunion.io/x/onecloud/pkg/hostman/options" "yunion.io/x/onecloud/pkg/mcclient/modules" @@ -466,34 +467,9 @@ func (s *SRbdStorage) onSaveToGlanceFailed(ctx context.Context, imageId string) } func (s *SRbdStorage) saveToGlance(ctx context.Context, imageId, imagePath string, compress bool, format string) error { - var ( - kvmDisk = NewKVMGuestDisk(imagePath) - osInfo string - relInfo *fsdriver.SReleaseInfo - ) - - if err := func() error { - defer kvmDisk.Disconnect() - if kvmDisk.Connect() { - if root := kvmDisk.MountKvmRootfs(); root != nil { - defer kvmDisk.UmountKvmRootfs(root) - - osInfo = root.GetOs() - relInfo = root.GetReleaseInfo(root.GetPartition()) - if compress { - if err := root.PrepareFsForTemplate(root.GetPartition()); err != nil { - log.Errorln(err) - return err - } - } - } - - if compress { - kvmDisk.Zerofree() - } - } - return nil - }(); err != nil { + ret, err := deployclient.GetDeployClient().SaveToGlance(context.Background(), + &deployapi.SaveToGlanceParams{DiskPath: imagePath, Compress: compress}) + if err != nil { return err } @@ -502,7 +478,7 @@ func (s *SRbdStorage) saveToGlance(ctx context.Context, imageId, imagePath strin format = options.HostOptions.DefaultImageSaveFormat } - _, err := procutils.NewCommand(qemutils.GetQemuImg(), "convert", "-f", "raw", "-O", format, imagePath, tmpImageFile).Run() + _, err = procutils.NewCommand(qemutils.GetQemuImg(), "convert", "-f", "raw", "-O", format, imagePath, tmpImageFile).Run() if err != nil { return err } @@ -511,8 +487,8 @@ func (s *SRbdStorage) saveToGlance(ctx context.Context, imageId, imagePath strin if err != nil { return err } - defer os.Remove(tmpImageFile) + defer f.Close() finfo, err := f.Stat() if err != nil { @@ -521,9 +497,10 @@ func (s *SRbdStorage) saveToGlance(ctx context.Context, imageId, imagePath strin size := finfo.Size() var params = jsonutils.NewDict() - if len(osInfo) > 0 { - params.Set("os_type", jsonutils.NewString(osInfo)) + if len(ret.OsInfo) > 0 { + params.Set("os_type", jsonutils.NewString(ret.OsInfo)) } + relInfo := ret.ReleaseInfo if relInfo != nil { params.Set("os_distribution", jsonutils.NewString(relInfo.Distro)) if len(relInfo.Version) > 0 { @@ -540,9 +517,6 @@ func (s *SRbdStorage) saveToGlance(ctx context.Context, imageId, imagePath strin _, err = modules.Images.Upload(hostutils.GetImageSession(ctx, s.GetZone()), params, f, size) - f.Close() - // TODO - // notify_template_ready return err } diff --git a/pkg/hostman/storageman/storagehandler/doc.go b/pkg/hostman/storageman/storagehandler/doc.go new file mode 100644 index 0000000000..ffde444e3e --- /dev/null +++ b/pkg/hostman/storageman/storagehandler/doc.go @@ -0,0 +1 @@ +package storagehandler // import "yunion.io/x/onecloud/pkg/hostman/storageman/storagehandler" diff --git a/pkg/hostman/storageman/storagehandler.go b/pkg/hostman/storageman/storagehandler/storagehandler.go similarity index 88% rename from pkg/hostman/storageman/storagehandler.go rename to pkg/hostman/storageman/storagehandler/storagehandler.go index 2aaf230dda..f2e6f7a7dd 100644 --- a/pkg/hostman/storageman/storagehandler.go +++ b/pkg/hostman/storageman/storagehandler/storagehandler.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package storageman +package storagehandler import ( "context" @@ -24,6 +24,7 @@ import ( "yunion.io/x/onecloud/pkg/appsrv" "yunion.io/x/onecloud/pkg/hostman/hostutils" + "yunion.io/x/onecloud/pkg/hostman/storageman" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/mcclient/modules" @@ -76,7 +77,7 @@ func storageAttach(ctx context.Context, body jsonutils.JSONObject) (interface{}, } storageType, _ := body.GetString("storage_type") - storage := storageManager.NewSharedStorageInstance(mountPoint, storageType) + storage := storageman.GetManager().NewSharedStorageInstance(mountPoint, storageType) if storage == nil { return nil, httperrors.NewBadRequestError("'Not Support Storage[%s] mount_point: %s", storageType, mountPoint) } @@ -92,8 +93,8 @@ func storageAttach(ctx context.Context, body jsonutils.JSONObject) (interface{}, if err != nil { return nil, err } - storageManager.InitSharedStorageImageCache(storageType, storagecacheId, imagecachePath, storage) - storageManager.Storages = append(storageManager.Storages, storage) + storageman.GetManager().InitSharedStorageImageCache(storageType, storagecacheId, imagecachePath, storage) + storageman.GetManager().Storages = append(storageman.GetManager().Storages, storage) return resp, nil } @@ -102,13 +103,13 @@ func storageDetach(ctx context.Context, body jsonutils.JSONObject) (interface{}, if err != nil { return nil, httperrors.NewMissingParameterError("mount_point") } - storage := storageManager.GetStorageByPath(mountPoint) + storage := storageman.GetManager().GetStorageByPath(mountPoint) name, _ := body.GetString("name") if storage == nil { return nil, httperrors.NewBadRequestError("ShareStorage[%s] Has detach from host ...", name) } - storageManager.Remove(storage) + storageman.GetManager().Remove(storage) return nil, nil } @@ -121,11 +122,11 @@ func storageUpdate(ctx context.Context, body jsonutils.JSONObject) (interface{}, if err != nil { return nil, httperrors.NewMissingParameterError("storage_conf") } - storage := storageManager.GetStorage(storageId) + storage := storageman.GetManager().GetStorage(storageId) params := jsonutils.NewDict() params.Set("details", jsonutils.JSONTrue) ret, err := modules.Hoststorages.Get(hostutils.GetComputeSession(context.Background()), - storageManager.GetHostId(), storageId, params) + storageman.GetManager().GetHostId(), storageId, params) if err != nil { log.Errorln(err) return nil, err @@ -143,7 +144,7 @@ func storageUpdate(ctx context.Context, body jsonutils.JSONObject) (interface{}, func storageDeleteSnapshots(ctx context.Context, w http.ResponseWriter, r *http.Request) { params, _, body := appsrv.FetchEnv(ctx, w, r) var storageId = params[""] - storage := storageManager.GetStorage(storageId) + storage := storageman.GetManager().GetStorage(storageId) if storage == nil { hostutils.Response(ctx, w, httperrors.NewNotFoundError("Stroage Not found")) return diff --git a/pkg/hostman/system_service/host_deployer.go b/pkg/hostman/system_service/host_deployer.go new file mode 100644 index 0000000000..7bb656a288 --- /dev/null +++ b/pkg/hostman/system_service/host_deployer.go @@ -0,0 +1,17 @@ +package system_service + +type SHostDeployer struct { + *SBaseSystemService +} + +func NewHostDeployerService() *SHostDeployer { + return &SHostDeployer{NewBaseSystemService("yunion-host-deployer", nil)} +} + +func (s *SHostDeployer) Reload(kwargs map[string]interface{}) error { + return s.reload(s.GetConfig(kwargs), s.GetConfigFile()) +} + +func (s *SHostDeployer) BgReload(kwargs map[string]interface{}) { + go s.reload(s.GetConfig(kwargs), s.GetConfigFile()) +} diff --git a/pkg/hostman/system_service/system_service.go b/pkg/hostman/system_service/system_service.go index 19c38212ce..28445eb958 100644 --- a/pkg/hostman/system_service/system_service.go +++ b/pkg/hostman/system_service/system_service.go @@ -45,6 +45,7 @@ var serviceMap = map[string]ISystemService{ "kube_agent": NewKubeAgentService(), "lxcfs": NewLxcfsService(), "docker": NewDockerService(), + "host-deployer": NewHostDeployerService(), } func GetService(name string) ISystemService { diff --git a/pkg/image/options/options.go b/pkg/image/options/options.go index 371e0013a7..bfc6760f15 100644 --- a/pkg/image/options/options.go +++ b/pkg/image/options/options.go @@ -38,7 +38,8 @@ type SImageOptions struct { TargetImageFormats []string `help:"target image formats that the system will automatically convert to" default:"qcow2,vmdk,vhd"` - TorrentClientPath string `help:"path to torrent executable" default:"/opt/yunion/bin/torrent"` + TorrentClientPath string `help:"path to torrent executable" default:"/opt/yunion/bin/torrent"` + DeployServerSocketPath string `help:"Deploy server listen socket path"` } var ( diff --git a/pkg/image/service/service.go b/pkg/image/service/service.go index b926d8a6f2..2272d6c32e 100644 --- a/pkg/image/service/service.go +++ b/pkg/image/service/service.go @@ -28,7 +28,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/cronman" "yunion.io/x/onecloud/pkg/cloudcommon/db" common_options "yunion.io/x/onecloud/pkg/cloudcommon/options" - "yunion.io/x/onecloud/pkg/hostman/storageman/nbd" + "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" "yunion.io/x/onecloud/pkg/image/models" "yunion.io/x/onecloud/pkg/image/options" _ "yunion.io/x/onecloud/pkg/image/tasks" @@ -104,7 +104,9 @@ func StartService() { go models.CheckImages() - nbd.Init() // init nbd module for image probe + if len(options.Options.DeployServerSocketPath) > 0 { + deployclient.Init(options.Options.DeployServerSocketPath) + } if !opts.IsSlaveNode { cron := cronman.GetCronJobManager(true) diff --git a/pkg/image/tasks/image_probe_task.go b/pkg/image/tasks/image_probe_task.go index 623a5c0acd..4fb4d3910d 100644 --- a/pkg/image/tasks/image_probe_task.go +++ b/pkg/image/tasks/image_probe_task.go @@ -25,8 +25,8 @@ import ( api "yunion.io/x/onecloud/pkg/apis/image" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" - "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver" - "yunion.io/x/onecloud/pkg/hostman/storageman" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" + "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" "yunion.io/x/onecloud/pkg/image/models" "yunion.io/x/onecloud/pkg/util/fileutils2" "yunion.io/x/onecloud/pkg/util/logclient" @@ -48,6 +48,7 @@ func (self *ImageProbeTask) OnInit(ctx context.Context, obj db.IStandaloneModel, func (self *ImageProbeTask) StartImageProbe(ctx context.Context, image *models.SImage) { probeErr := self.doProbe(ctx, image) + // save chksum first // if failed, set image unavailable, because size and chksum changed if err := self.updateImageMetadata(ctx, image); err != nil { image.SetStatus(self.UserCred, api.IMAGE_STATUS_KILLED, @@ -65,20 +66,13 @@ func (self *ImageProbeTask) StartImageProbe(ctx context.Context, image *models.S func (self *ImageProbeTask) doProbe(ctx context.Context, image *models.SImage) error { diskPath := image.GetPath("") - kvmDisk := storageman.NewKVMGuestDisk(diskPath) - defer kvmDisk.DisconnectWithoutLvm() - if !kvmDisk.ConnectWithoutDetectLvm() { - return fmt.Errorf("Disk connector failed to connect image") + if deployclient.GetDeployClient() == nil { + return fmt.Errorf("deploy client not init") } - - // Fsck is executed during mount - rootfs := kvmDisk.MountKvmRootfs() - if rootfs == nil { - return fmt.Errorf("Failed mounting rootfs for kvm disk") + imageInfo, err := deployclient.GetDeployClient().ProbeImageInfo(ctx, &deployapi.ProbeImageInfoPramas{DiskPath: diskPath}) + if err != nil { + return err } - defer kvmDisk.UmountKvmRootfs(rootfs) - - imageInfo := self.getImageInfo(kvmDisk, rootfs) self.updateImageInfo(ctx, image, imageInfo) return nil } @@ -120,15 +114,15 @@ func (self *ImageProbeTask) updateImageMetadata( return nil } -func (self *ImageProbeTask) updateImageInfo(ctx context.Context, image *models.SImage, imageInfo *sImageInfo) { - imageProperties := jsonutils.Marshal(imageInfo.osInfo).(*jsonutils.JSONDict) +func (self *ImageProbeTask) updateImageInfo(ctx context.Context, image *models.SImage, imageInfo *deployapi.ImageInfo) { + imageProperties := jsonutils.Marshal(imageInfo.OsInfo).(*jsonutils.JSONDict) if len(imageInfo.OsType) > 0 { imageProperties.Set(api.IMAGE_OS_TYPE, jsonutils.NewString(imageInfo.OsType)) } - if imageInfo.IsUEFISupport { + if imageInfo.IsUefiSupport { imageProperties.Set(api.IMAGE_UEFI_SUPPORT, jsonutils.JSONTrue) } - if imageInfo.IsLVMPartition { + if imageInfo.IsLvmPartition { imageProperties.Set(api.IMAGE_IS_LVM_PARTITION, jsonutils.JSONTrue) } if imageInfo.IsReadonly { @@ -145,7 +139,7 @@ func (self *ImageProbeTask) updateImageInfo(ctx context.Context, image *models.S } type sImageInfo struct { - osInfo *fsdriver.SReleaseInfo + osInfo *deployapi.ReleaseInfo OsType string IsUEFISupport bool @@ -155,19 +149,6 @@ type sImageInfo struct { IsInstalledCloudInit bool } -func (self *ImageProbeTask) getImageInfo(kvmDisk *storageman.SKVMGuestDisk, rootfs fsdriver.IRootFsDriver) *sImageInfo { - partition := rootfs.GetPartition() - return &sImageInfo{ - osInfo: rootfs.GetReleaseInfo(partition), - OsType: rootfs.GetOs(), - IsUEFISupport: kvmDisk.DetectIsUEFISupport(rootfs), - // IsLVMPartition: kvmDisk.IsLVMPartition(), - IsReadonly: partition.IsReadonly(), - PhysicalPartitionType: partition.GetPhysicalPartitionType(), - IsInstalledCloudInit: rootfs.IsCloudinitInstall(), - } -} - func (self *ImageProbeTask) OnProbeFailed(ctx context.Context, image *models.SImage, reason string) { log.Infof("Image %s Probe Failed: %s", image.Name, reason) db.OpsLog.LogEvent(image, db.ACT_PROBE_FAIL, reason, self.UserCred) diff --git a/pkg/util/netutils2/netutils.go b/pkg/util/netutils2/netutils.go index 59e52da788..ca14105452 100644 --- a/pkg/util/netutils2/netutils.go +++ b/pkg/util/netutils2/netutils.go @@ -30,6 +30,7 @@ import ( "yunion.io/x/pkg/util/regutils" "yunion.io/x/onecloud/pkg/cloudcommon/types" + deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/util/procutils" "yunion.io/x/onecloud/pkg/util/regutils2" ) @@ -78,6 +79,28 @@ func GetPrivatePrefixes(privatePrefixes []string) []string { } } +func GetMainNicFromDeployApi(nics []*deployapi.Nic) (*deployapi.Nic, error) { + var mainIp netutils.IPV4Addr + var mainNic *deployapi.Nic + for _, n := range nics { + if len(n.Gateway) > 0 { + ip := n.Ip + ipInt, err := netutils.NewIPV4Addr(ip) + if err != nil { + return nil, err + } + if mainIp == 0 { + mainIp = ipInt + mainNic = n + } else if !netutils.IsPrivate(ipInt) && netutils.IsPrivate(mainIp) { + mainIp = ipInt + mainNic = n + } + } + } + return mainNic, nil +} + func GetMainNic(nics []jsonutils.JSONObject) (jsonutils.JSONObject, error) { var mainIp netutils.IPV4Addr var mainNic jsonutils.JSONObject @@ -136,9 +159,9 @@ func addRoute(routes *[][]string, net, gw string) { *routes = append(*routes, []string{net, gw}) } -func extendRoutes(routes *[][]string, nicRoutes []types.SRoute) error { +func extendRoutes(routes *[][]string, nicRoutes []*deployapi.Routes) error { for i := 0; i < len(nicRoutes); i++ { - addRoute(routes, nicRoutes[i][0], nicRoutes[i][1]) + addRoute(routes, nicRoutes[i].Route[0], nicRoutes[i].Route[1]) } return nil } diff --git a/pkg/util/sysutils/kvm.go b/pkg/util/sysutils/kvm.go index 94417d5f17..7445cf7cc6 100644 --- a/pkg/util/sysutils/kvm.go +++ b/pkg/util/sysutils/kvm.go @@ -15,6 +15,7 @@ package sysutils import ( + "io/ioutil" "os" "path" "regexp" @@ -191,3 +192,21 @@ func IsKernelModuleLoaded(name string) bool { } return false } + +func SetSysConfig(cpath, val string) bool { + if fileutils2.Exists(cpath) { + oval, err := ioutil.ReadFile(cpath) + if err != nil { + log.Errorln(err) + return false + } + if string(oval) != val { + err = fileutils2.FilePutContents(cpath, val, false) + if err == nil { + return true + } + log.Errorln(err) + } + } + return false +} diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go index d9aa3c42d6..63b0f08bef 100644 --- a/vendor/github.com/golang/protobuf/proto/decode.go +++ b/vendor/github.com/golang/protobuf/proto/decode.go @@ -186,7 +186,6 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) { if b&0x80 == 0 { goto done } - // x -= 0x80 << 63 // Always zero. return 0, errOverflow diff --git a/vendor/github.com/golang/protobuf/proto/deprecated.go b/vendor/github.com/golang/protobuf/proto/deprecated.go new file mode 100644 index 0000000000..35b882c09a --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/deprecated.go @@ -0,0 +1,63 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2018 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import "errors" + +// Deprecated: do not use. +type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } + +// Deprecated: do not use. +func GetStats() Stats { return Stats{} } + +// Deprecated: do not use. +func MarshalMessageSet(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSet([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func MarshalMessageSetJSON(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func UnmarshalMessageSetJSON([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: do not use. +func RegisterMessageSetType(Message, int32, string) {} diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go index d4db5a1c14..f9b6e41b3c 100644 --- a/vendor/github.com/golang/protobuf/proto/equal.go +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -246,7 +246,8 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { return false } - m1, m2 := e1.value, e2.value + m1 := extensionAsLegacyType(e1.value) + m2 := extensionAsLegacyType(e2.value) if m1 == nil && m2 == nil { // Both have only encoded form. diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go index 816a3b9d6c..fa88add30a 100644 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -185,9 +185,25 @@ type Extension struct { // extension will have only enc set. When such an extension is // accessed using GetExtension (or GetExtensions) desc and value // will be set. - desc *ExtensionDesc + desc *ExtensionDesc + + // value is a concrete value for the extension field. Let the type of + // desc.ExtensionType be the "API type" and the type of Extension.value + // be the "storage type". The API type and storage type are the same except: + // * For scalars (except []byte), the API type uses *T, + // while the storage type uses T. + // * For repeated fields, the API type uses []T, while the storage type + // uses *[]T. + // + // The reason for the divergence is so that the storage type more naturally + // matches what is expected of when retrieving the values through the + // protobuf reflection APIs. + // + // The value may only be populated if desc is also populated. value interface{} - enc []byte + + // enc is the raw bytes for the extension field. + enc []byte } // SetRawExtension is for testing only. @@ -334,7 +350,7 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { // descriptors with the same field number. return nil, errors.New("proto: descriptor conflict") } - return e.value, nil + return extensionAsLegacyType(e.value), nil } if extension.ExtensionType == nil { @@ -349,11 +365,11 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { // Remember the decoded version and drop the encoded version. // That way it is safe to mutate what we return. - e.value = v + e.value = extensionAsStorageType(v) e.desc = extension e.enc = nil emap[extension.Field] = e - return e.value, nil + return extensionAsLegacyType(e.value), nil } // defaultExtensionValue returns the default value for extension. @@ -488,7 +504,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error } typ := reflect.TypeOf(extension.ExtensionType) if typ != reflect.TypeOf(value) { - return errors.New("proto: bad extension value type") + return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) } // nil extension values need to be caught early, because the // encoder can't distinguish an ErrNil due to a nil extension @@ -500,7 +516,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error } extmap := epb.extensionsWrite() - extmap[extension.Field] = Extension{desc: extension, value: value} + extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)} return nil } @@ -541,3 +557,51 @@ func RegisterExtension(desc *ExtensionDesc) { func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { return extensionMaps[reflect.TypeOf(pb).Elem()] } + +// extensionAsLegacyType converts an value in the storage type as the API type. +// See Extension.value. +func extensionAsLegacyType(v interface{}) interface{} { + switch rv := reflect.ValueOf(v); rv.Kind() { + case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: + // Represent primitive types as a pointer to the value. + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + case reflect.Ptr: + // Represent slice types as the value itself. + switch rv.Type().Elem().Kind() { + case reflect.Slice: + if rv.IsNil() { + v = reflect.Zero(rv.Type().Elem()).Interface() + } else { + v = rv.Elem().Interface() + } + } + } + return v +} + +// extensionAsStorageType converts an value in the API type as the storage type. +// See Extension.value. +func extensionAsStorageType(v interface{}) interface{} { + switch rv := reflect.ValueOf(v); rv.Kind() { + case reflect.Ptr: + // Represent slice types as the value itself. + switch rv.Type().Elem().Kind() { + case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: + if rv.IsNil() { + v = reflect.Zero(rv.Type().Elem()).Interface() + } else { + v = rv.Elem().Interface() + } + } + case reflect.Slice: + // Represent slice types as a pointer to the value. + if rv.Type().Elem().Kind() != reflect.Uint8 { + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + } + } + return v +} diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go index 75565cc6dc..fdd328bb7f 100644 --- a/vendor/github.com/golang/protobuf/proto/lib.go +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -341,26 +341,6 @@ type Message interface { ProtoMessage() } -// Stats records allocation details about the protocol buffer encoders -// and decoders. Useful for tuning the library itself. -type Stats struct { - Emalloc uint64 // mallocs in encode - Dmalloc uint64 // mallocs in decode - Encode uint64 // number of encodes - Decode uint64 // number of decodes - Chit uint64 // number of cache hits - Cmiss uint64 // number of cache misses - Size uint64 // number of sizes -} - -// Set to true to enable stats collection. -const collectStats = false - -var stats Stats - -// GetStats returns a copy of the global Stats structure. -func GetStats() Stats { return stats } - // A Buffer is a buffer manager for marshaling and unmarshaling // protocol buffers. It may be reused between invocations to // reduce memory usage. It is not necessary to use a Buffer; @@ -960,13 +940,19 @@ func isProto3Zero(v reflect.Value) bool { return false } -// ProtoPackageIsVersion2 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const ProtoPackageIsVersion2 = true +const ( + // ProtoPackageIsVersion3 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion3 = true -// ProtoPackageIsVersion1 is referenced from generated protocol buffer files -// to assert that that code is compatible with this version of the proto package. -const ProtoPackageIsVersion1 = true + // ProtoPackageIsVersion2 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion2 = true + + // ProtoPackageIsVersion1 is referenced from generated protocol buffer files + // to assert that that code is compatible with this version of the proto package. + ProtoPackageIsVersion1 = true +) // InternalMessageInfo is a type used internally by generated .pb.go files. // This type is not intended to be used by non-generated code. diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go index 3b6ca41d5e..f48a756761 100644 --- a/vendor/github.com/golang/protobuf/proto/message_set.go +++ b/vendor/github.com/golang/protobuf/proto/message_set.go @@ -36,13 +36,7 @@ package proto */ import ( - "bytes" - "encoding/json" "errors" - "fmt" - "reflect" - "sort" - "sync" ) // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. @@ -145,46 +139,9 @@ func skipVarint(buf []byte) []byte { return buf[i+1:] } -// MarshalMessageSet encodes the extension map represented by m in the message set wire format. -// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSet(exts interface{}) ([]byte, error) { - return marshalMessageSet(exts, false) -} - -// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal. -func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) { - switch exts := exts.(type) { - case *XXX_InternalExtensions: - var u marshalInfo - siz := u.sizeMessageSet(exts) - b := make([]byte, 0, siz) - return u.appendMessageSet(b, exts, deterministic) - - case map[int32]Extension: - // This is an old-style extension map. - // Wrap it in a new-style XXX_InternalExtensions. - ie := XXX_InternalExtensions{ - p: &struct { - mu sync.Mutex - extensionMap map[int32]Extension - }{ - extensionMap: exts, - }, - } - - var u marshalInfo - siz := u.sizeMessageSet(&ie) - b := make([]byte, 0, siz) - return u.appendMessageSet(b, &ie, deterministic) - - default: - return nil, errors.New("proto: not an extension map") - } -} - -// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. +// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. // It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSet(buf []byte, exts interface{}) error { +func unmarshalMessageSet(buf []byte, exts interface{}) error { var m map[int32]Extension switch exts := exts.(type) { case *XXX_InternalExtensions: @@ -222,93 +179,3 @@ func UnmarshalMessageSet(buf []byte, exts interface{}) error { } return nil } - -// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. -// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - var mu sync.Locker - m, mu = exts.extensionsRead() - if m != nil { - // Keep the extensions map locked until we're done marshaling to prevent - // races between marshaling and unmarshaling the lazily-{en,de}coded - // values. - mu.Lock() - defer mu.Unlock() - } - case map[int32]Extension: - m = exts - default: - return nil, errors.New("proto: not an extension map") - } - var b bytes.Buffer - b.WriteByte('{') - - // Process the map in key order for deterministic output. - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) // int32Slice defined in text.go - - for i, id := range ids { - ext := m[id] - msd, ok := messageSetMap[id] - if !ok { - // Unknown type; we can't render it, so skip it. - continue - } - - if i > 0 && b.Len() > 1 { - b.WriteByte(',') - } - - fmt.Fprintf(&b, `"[%s]":`, msd.name) - - x := ext.value - if x == nil { - x = reflect.New(msd.t.Elem()).Interface() - if err := Unmarshal(ext.enc, x.(Message)); err != nil { - return nil, err - } - } - d, err := json.Marshal(x) - if err != nil { - return nil, err - } - b.Write(d) - } - b.WriteByte('}') - return b.Bytes(), nil -} - -// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. -// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { - // Common-case fast path. - if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { - return nil - } - - // This is fairly tricky, and it's not clear that it is needed. - return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") -} - -// A global registry of types that can be used in a MessageSet. - -var messageSetMap = make(map[int32]messageSetDesc) - -type messageSetDesc struct { - t reflect.Type // pointer to struct - name string -} - -// RegisterMessageSetType is called from the generated code. -func RegisterMessageSetType(m Message, fieldNum int32, name string) { - messageSetMap[fieldNum] = messageSetDesc{ - t: reflect.TypeOf(m), - name: name, - } -} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go index b6cad90834..94fa9194a8 100644 --- a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go +++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go @@ -79,10 +79,13 @@ func toPointer(i *Message) pointer { // toAddrPointer converts an interface to a pointer that points to // the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { +func toAddrPointer(i *interface{}, isptr, deref bool) pointer { v := reflect.ValueOf(*i) u := reflect.New(v.Type()) u.Elem().Set(v) + if deref { + u = u.Elem() + } return pointer{v: u} } diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go index d55a335d94..dbfffe071b 100644 --- a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go +++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go @@ -85,16 +85,21 @@ func toPointer(i *Message) pointer { // toAddrPointer converts an interface to a pointer that points to // the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { +func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) { // Super-tricky - read or get the address of data word of interface value. if isptr { // The interface is of pointer type, thus it is a direct interface. // The data word is the pointer data itself. We take its address. - return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} + p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} + } else { + // The interface is not of pointer type. The data word is the pointer + // to the data. + p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} } - // The interface is not of pointer type. The data word is the pointer - // to the data. - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} + if deref { + p.p = *(*unsafe.Pointer)(p.p) + } + return p } // valToPointer converts v to a pointer. v must be of pointer type. diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go index 50b99b83a8..79668ff5c5 100644 --- a/vendor/github.com/golang/protobuf/proto/properties.go +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -334,9 +334,6 @@ func GetProperties(t reflect.Type) *StructProperties { sprop, ok := propertiesMap[t] propertiesMu.RUnlock() if ok { - if collectStats { - stats.Chit++ - } return sprop } @@ -346,17 +343,20 @@ func GetProperties(t reflect.Type) *StructProperties { return sprop } +type ( + oneofFuncsIface interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + oneofWrappersIface interface { + XXX_OneofWrappers() []interface{} + } +) + // getPropertiesLocked requires that propertiesMu is held. func getPropertiesLocked(t reflect.Type) *StructProperties { if prop, ok := propertiesMap[t]; ok { - if collectStats { - stats.Chit++ - } return prop } - if collectStats { - stats.Cmiss++ - } prop := new(StructProperties) // in case of recursive protos, fill this in now. @@ -391,13 +391,14 @@ func getPropertiesLocked(t reflect.Type) *StructProperties { // Re-order prop.order. sort.Sort(prop) - type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + var oots []interface{} + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: + _, _, _, oots = m.XXX_OneofFuncs() + case oneofWrappersIface: + oots = m.XXX_OneofWrappers() } - if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { - var oots []interface{} - _, _, _, oots = om.XXX_OneofFuncs() - + if len(oots) > 0 { // Interpret oneof metadata. prop.OneofTypes = make(map[string]*OneofProperties) for _, oot := range oots { diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go index b16794496f..5cb11fa955 100644 --- a/vendor/github.com/golang/protobuf/proto/table_marshal.go +++ b/vendor/github.com/golang/protobuf/proto/table_marshal.go @@ -87,6 +87,7 @@ type marshalElemInfo struct { sizer sizer marshaler marshaler isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) + deref bool // dereference the pointer before operating on it; implies isptr } var ( @@ -320,8 +321,11 @@ func (u *marshalInfo) computeMarshalInfo() { // get oneof implementers var oneofImplementers []interface{} - if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: _, _, _, oneofImplementers = m.XXX_OneofFuncs() + case oneofWrappersIface: + oneofImplementers = m.XXX_OneofWrappers() } n := t.NumField() @@ -407,13 +411,22 @@ func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { panic("tag is not an integer") } wt := wiretype(tags[0]) + if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct { + t = t.Elem() + } sizer, marshaler := typeMarshaler(t, tags, false, false) + var deref bool + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + t = reflect.PtrTo(t) + deref = true + } e = &marshalElemInfo{ wiretag: uint64(tag)<<3 | wt, tagsize: SizeVarint(uint64(tag) << 3), sizer: sizer, marshaler: marshaler, isptr: t.Kind() == reflect.Ptr, + deref: deref, } // update cache @@ -448,7 +461,7 @@ func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { fi.field = toField(f) - fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. + fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. fi.isPointer = true fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) @@ -476,10 +489,6 @@ func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofI } } -type oneofMessage interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) -} - // wiretype returns the wire encoding of the type. func wiretype(encoding string) uint64 { switch encoding { @@ -2310,8 +2319,8 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { for _, k := range m.MapKeys() { ki := k.Interface() vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + kaddr := toAddrPointer(&ki, false, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) n += siz + SizeVarint(uint64(siz)) + tagsize } @@ -2329,8 +2338,8 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { for _, k := range keys { ki := k.Interface() vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + kaddr := toAddrPointer(&ki, false, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value b = appendVarint(b, tag) siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) b = appendVarint(b, uint64(siz)) @@ -2399,7 +2408,7 @@ func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { // the last time this function was called. ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) n += ei.sizer(p, ei.tagsize) } mu.Unlock() @@ -2434,7 +2443,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, ei.wiretag, deterministic) if !nerr.Merge(err) { return b, err @@ -2465,7 +2474,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, ei.wiretag, deterministic) if !nerr.Merge(err) { return b, err @@ -2510,7 +2519,7 @@ func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) n += ei.sizer(p, 1) // message, tag = 3 (size=1) } mu.Unlock() @@ -2553,7 +2562,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) if !nerr.Merge(err) { return b, err @@ -2591,7 +2600,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) b = append(b, 1<<3|WireEndGroup) if !nerr.Merge(err) { @@ -2621,7 +2630,7 @@ func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) n += ei.sizer(p, ei.tagsize) } return n @@ -2656,7 +2665,7 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ ei := u.getExtElemInfo(e.desc) v := e.value - p := toAddrPointer(&v, ei.isptr) + p := toAddrPointer(&v, ei.isptr, ei.deref) b, err = ei.marshaler(b, p, ei.wiretag, deterministic) if !nerr.Merge(err) { return b, err diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go index ebf1caa56a..acee2fc529 100644 --- a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go +++ b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go @@ -136,7 +136,7 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error { u.computeUnmarshalInfo() } if u.isMessageSet { - return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions()) + return unmarshalMessageSet(b, m.offset(u.extensions).toExtensions()) } var reqMask uint64 // bitmask of required fields we've seen. var errLater error @@ -362,46 +362,48 @@ func (u *unmarshalInfo) computeUnmarshalInfo() { } // Find any types associated with oneof fields. - // TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it? - fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs") - if fn.IsValid() { - res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{} - for i := res.Len() - 1; i >= 0; i-- { - v := res.Index(i) // interface{} - tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X - typ := tptr.Elem() // Msg_X + var oneofImplementers []interface{} + switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { + case oneofFuncsIface: + _, _, _, oneofImplementers = m.XXX_OneofFuncs() + case oneofWrappersIface: + oneofImplementers = m.XXX_OneofWrappers() + } + for _, v := range oneofImplementers { + tptr := reflect.TypeOf(v) // *Msg_X + typ := tptr.Elem() // Msg_X - f := typ.Field(0) // oneof implementers have one field - baseUnmarshal := fieldUnmarshaler(&f) - tags := strings.Split(f.Tag.Get("protobuf"), ",") - fieldNum, err := strconv.Atoi(tags[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tags[1]) - } - var name string - for _, tag := range tags { - if strings.HasPrefix(tag, "name=") { - name = strings.TrimPrefix(tag, "name=") - break - } - } - - // Find the oneof field that this struct implements. - // Might take O(n^2) to process all of the oneofs, but who cares. - for _, of := range oneofFields { - if tptr.Implements(of.ityp) { - // We have found the corresponding interface for this struct. - // That lets us know where this struct should be stored - // when we encounter it during unmarshaling. - unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) - u.setTag(fieldNum, of.field, unmarshal, 0, name) - } + f := typ.Field(0) // oneof implementers have one field + baseUnmarshal := fieldUnmarshaler(&f) + tags := strings.Split(f.Tag.Get("protobuf"), ",") + fieldNum, err := strconv.Atoi(tags[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tags[1]) + } + var name string + for _, tag := range tags { + if strings.HasPrefix(tag, "name=") { + name = strings.TrimPrefix(tag, "name=") + break } } + + // Find the oneof field that this struct implements. + // Might take O(n^2) to process all of the oneofs, but who cares. + for _, of := range oneofFields { + if tptr.Implements(of.ityp) { + // We have found the corresponding interface for this struct. + // That lets us know where this struct should be stored + // when we encounter it during unmarshaling. + unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) + u.setTag(fieldNum, of.field, unmarshal, 0, name) + } + } + } // Get extension ranges, if any. - fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") + fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") if fn.IsValid() { if !u.extensions.IsValid() && !u.oldExtensions.IsValid() { panic("a message with extensions, but no extensions field in " + t.Name()) @@ -1948,7 +1950,7 @@ func encodeVarint(b []byte, x uint64) []byte { // If there is an error, it returns 0,0. func decodeVarint(b []byte) (uint64, int) { var x, y uint64 - if len(b) <= 0 { + if len(b) == 0 { goto bad } x = uint64(b[0]) diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go index e3c56d3ffa..78ee523349 100644 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go @@ -1,11 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/any.proto -package any // import "github.com/golang/protobuf/ptypes/any" +package any -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +18,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // `Any` contains an arbitrary serialized protocol buffer message along with a // URL that describes the type of the serialized message. @@ -99,17 +101,18 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // } // type Any struct { - // A URL/resource name whose content describes the type of the - // serialized protocol buffer message. + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). // - // For URLs which use the scheme `http`, `https`, or no scheme, the - // following restrictions and interpretations apply: + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: // // * If no scheme is provided, `https` is assumed. - // * The last segment of the URL's path must represent the fully - // qualified name of the type (as in `path/google.protobuf.Duration`). - // The name should be in a canonical form (e.g., leading "." is - // not accepted). // * An HTTP GET on the URL must yield a [google.protobuf.Type][] // value in binary format, or produce an error. // * Applications are allowed to cache lookup results based on the @@ -118,6 +121,10 @@ type Any struct { // on changes to types. (Use versioned type names to manage // breaking changes.) // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // // Schemes other than `http`, `https` (or the empty scheme) might be // used with implementation specific semantics. // @@ -133,17 +140,19 @@ func (m *Any) Reset() { *m = Any{} } func (m *Any) String() string { return proto.CompactTextString(m) } func (*Any) ProtoMessage() {} func (*Any) Descriptor() ([]byte, []int) { - return fileDescriptor_any_744b9ca530f228db, []int{0} + return fileDescriptor_b53526c13ae22eb4, []int{0} } + func (*Any) XXX_WellKnownType() string { return "Any" } + func (m *Any) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Any.Unmarshal(m, b) } func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Any.Marshal(b, m, deterministic) } -func (dst *Any) XXX_Merge(src proto.Message) { - xxx_messageInfo_Any.Merge(dst, src) +func (m *Any) XXX_Merge(src proto.Message) { + xxx_messageInfo_Any.Merge(m, src) } func (m *Any) XXX_Size() int { return xxx_messageInfo_Any.Size(m) @@ -172,9 +181,9 @@ func init() { proto.RegisterType((*Any)(nil), "google.protobuf.Any") } -func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_any_744b9ca530f228db) } +func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_b53526c13ae22eb4) } -var fileDescriptor_any_744b9ca530f228db = []byte{ +var fileDescriptor_b53526c13ae22eb4 = []byte{ // 185 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4, diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.proto b/vendor/github.com/golang/protobuf/ptypes/any/any.proto index c748667623..4932942558 100644 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.proto +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.proto @@ -120,17 +120,18 @@ option objc_class_prefix = "GPB"; // } // message Any { - // A URL/resource name whose content describes the type of the - // serialized protocol buffer message. + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). // - // For URLs which use the scheme `http`, `https`, or no scheme, the - // following restrictions and interpretations apply: + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: // // * If no scheme is provided, `https` is assumed. - // * The last segment of the URL's path must represent the fully - // qualified name of the type (as in `path/google.protobuf.Duration`). - // The name should be in a canonical form (e.g., leading "." is - // not accepted). // * An HTTP GET on the URL must yield a [google.protobuf.Type][] // value in binary format, or produce an error. // * Applications are allowed to cache lookup results based on the @@ -139,6 +140,10 @@ message Any { // on changes to types. (Use versioned type names to manage // breaking changes.) // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // // Schemes other than `http`, `https` (or the empty scheme) might be // used with implementation specific semantics. // diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go index 65cb0f8eb5..26d1ca2fb5 100644 --- a/vendor/github.com/golang/protobuf/ptypes/duration.go +++ b/vendor/github.com/golang/protobuf/ptypes/duration.go @@ -82,7 +82,7 @@ func Duration(p *durpb.Duration) (time.Duration, error) { return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) } if p.Nanos != 0 { - d += time.Duration(p.Nanos) + d += time.Duration(p.Nanos) * time.Nanosecond if (d < 0) != (p.Nanos < 0) { return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) } diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go index a7beb2c414..0d681ee21a 100644 --- a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go @@ -1,11 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/duration.proto -package duration // import "github.com/golang/protobuf/ptypes/duration" +package duration -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +18,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // A Duration represents a signed, fixed-length span of time represented // as a count of seconds and fractions of seconds at nanosecond @@ -99,17 +101,19 @@ func (m *Duration) Reset() { *m = Duration{} } func (m *Duration) String() string { return proto.CompactTextString(m) } func (*Duration) ProtoMessage() {} func (*Duration) Descriptor() ([]byte, []int) { - return fileDescriptor_duration_e7d612259e3f0613, []int{0} + return fileDescriptor_23597b2ebd7ac6c5, []int{0} } + func (*Duration) XXX_WellKnownType() string { return "Duration" } + func (m *Duration) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Duration.Unmarshal(m, b) } func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Duration.Marshal(b, m, deterministic) } -func (dst *Duration) XXX_Merge(src proto.Message) { - xxx_messageInfo_Duration.Merge(dst, src) +func (m *Duration) XXX_Merge(src proto.Message) { + xxx_messageInfo_Duration.Merge(m, src) } func (m *Duration) XXX_Size() int { return xxx_messageInfo_Duration.Size(m) @@ -138,11 +142,9 @@ func init() { proto.RegisterType((*Duration)(nil), "google.protobuf.Duration") } -func init() { - proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_duration_e7d612259e3f0613) -} +func init() { proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_23597b2ebd7ac6c5) } -var fileDescriptor_duration_e7d612259e3f0613 = []byte{ +var fileDescriptor_23597b2ebd7ac6c5 = []byte{ // 190 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a, diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go index 47f10dbc2c..8da0df01ac 100644 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp.go +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp.go @@ -111,11 +111,9 @@ func TimestampNow() *tspb.Timestamp { // TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. // It returns an error if the resulting Timestamp is invalid. func TimestampProto(t time.Time) (*tspb.Timestamp, error) { - seconds := t.Unix() - nanos := int32(t.Sub(time.Unix(seconds, 0))) ts := &tspb.Timestamp{ - Seconds: seconds, - Nanos: nanos, + Seconds: t.Unix(), + Nanos: int32(t.Nanosecond()), } if err := validateTimestamp(ts); err != nil { return nil, err diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go index 8e76ae9763..31cd846de9 100644 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go @@ -1,11 +1,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/timestamp.proto -package timestamp // import "github.com/golang/protobuf/ptypes/timestamp" +package timestamp -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +18,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // A Timestamp represents a point in time independent of any time zone // or calendar, represented as seconds and fractions of seconds at @@ -81,7 +83,9 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone -// is required, though only UTC (as indicated by "Z") is presently supported. +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). // // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past // 01:30 UTC on January 15, 2017. @@ -92,8 +96,8 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) // with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one // can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( -// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--) -// to obtain a formatter capable of generating timestamps in this format. +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- +// ) to obtain a formatter capable of generating timestamps in this format. // // type Timestamp struct { @@ -115,17 +119,19 @@ func (m *Timestamp) Reset() { *m = Timestamp{} } func (m *Timestamp) String() string { return proto.CompactTextString(m) } func (*Timestamp) ProtoMessage() {} func (*Timestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_timestamp_b826e8e5fba671a8, []int{0} + return fileDescriptor_292007bbfe81227e, []int{0} } + func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" } + func (m *Timestamp) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Timestamp.Unmarshal(m, b) } func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic) } -func (dst *Timestamp) XXX_Merge(src proto.Message) { - xxx_messageInfo_Timestamp.Merge(dst, src) +func (m *Timestamp) XXX_Merge(src proto.Message) { + xxx_messageInfo_Timestamp.Merge(m, src) } func (m *Timestamp) XXX_Size() int { return xxx_messageInfo_Timestamp.Size(m) @@ -154,11 +160,9 @@ func init() { proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp") } -func init() { - proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_timestamp_b826e8e5fba671a8) -} +func init() { proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_292007bbfe81227e) } -var fileDescriptor_timestamp_b826e8e5fba671a8 = []byte{ +var fileDescriptor_292007bbfe81227e = []byte{ // 191 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto index 06750ab1f1..eafb3fa03a 100644 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto @@ -103,7 +103,9 @@ option objc_class_prefix = "GPB"; // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone -// is required, though only UTC (as indicated by "Z") is presently supported. +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). // // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past // 01:30 UTC on January 15, 2017. @@ -114,8 +116,8 @@ option objc_class_prefix = "GPB"; // to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) // with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one // can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( -// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--) -// to obtain a formatter capable of generating timestamps in this format. +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- +// ) to obtain a formatter capable of generating timestamps in this format. // // message Timestamp { diff --git a/vendor/modules.txt b/vendor/modules.txt index e2ef16c6e7..6f0cdaf08a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -270,7 +270,7 @@ github.com/golang-plus/uuid/internal/random github.com/golang-plus/uuid/internal/timebased # github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/glog -# github.com/golang/protobuf v1.2.0 +# github.com/golang/protobuf v1.3.1 github.com/golang/protobuf/proto github.com/golang/protobuf/ptypes github.com/golang/protobuf/ptypes/any @@ -509,16 +509,16 @@ golang.org/x/net/bpf golang.org/x/net/ipv4 golang.org/x/net/proxy golang.org/x/net/ipv6 +golang.org/x/net/trace golang.org/x/net/internal/iana golang.org/x/net/internal/socket golang.org/x/net/http2 golang.org/x/net/context -golang.org/x/net/trace golang.org/x/net/internal/socks -golang.org/x/net/http/httpguts -golang.org/x/net/http2/hpack -golang.org/x/net/idna golang.org/x/net/internal/timeseries +golang.org/x/net/http2/hpack +golang.org/x/net/http/httpguts +golang.org/x/net/idna golang.org/x/net/context/ctxhttp # golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 golang.org/x/oauth2 @@ -551,14 +551,14 @@ google.golang.org/appengine/internal/urlfetch google.golang.org/genproto/googleapis/rpc/status # google.golang.org/grpc v1.19.0 google.golang.org/grpc +google.golang.org/grpc/codes +google.golang.org/grpc/status google.golang.org/grpc/peer google.golang.org/grpc/credentials -google.golang.org/grpc/codes google.golang.org/grpc/grpclog google.golang.org/grpc/health/grpc_health_v1 google.golang.org/grpc/keepalive google.golang.org/grpc/metadata -google.golang.org/grpc/status google.golang.org/grpc/balancer google.golang.org/grpc/balancer/roundrobin google.golang.org/grpc/connectivity From dc4b791f7e48c53f63685875cf2ce671605e9dfd Mon Sep 17 00:00:00 2001 From: wanyaoqi Date: Wed, 10 Jul 2019 19:01:22 +0800 Subject: [PATCH 2/2] add build file --- build/host-deployer/vars | 1 + pkg/hostman/guestman/qemu-kvm.go | 4 ++-- pkg/hostman/hostdeployer/deployserver/deployserver.go | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 build/host-deployer/vars diff --git a/build/host-deployer/vars b/build/host-deployer/vars new file mode 100644 index 0000000000..7190279c35 --- /dev/null +++ b/build/host-deployer/vars @@ -0,0 +1 @@ +DESCRIPTION="Yunion Host Deploy Agent" \ No newline at end of file diff --git a/pkg/hostman/guestman/qemu-kvm.go b/pkg/hostman/guestman/qemu-kvm.go index fb526151a4..d923348b38 100644 --- a/pkg/hostman/guestman/qemu-kvm.go +++ b/pkg/hostman/guestman/qemu-kvm.go @@ -1354,9 +1354,9 @@ func (s *SKVMGuestInstance) StaticSaveSnapshot( if err != nil { return nil, err } - location := path.Join(disk.GetSnapshotDir(), snapshotId) + location := path.Join(disk.GetSnapshotLocation(), snapshotId) res := jsonutils.NewDict() - res.Set("localtion", jsonutils.NewString(location)) + res.Set("location", jsonutils.NewString(location)) return res, nil } diff --git a/pkg/hostman/hostdeployer/deployserver/deployserver.go b/pkg/hostman/hostdeployer/deployserver/deployserver.go index f944abc638..66f5383613 100644 --- a/pkg/hostman/hostdeployer/deployserver/deployserver.go +++ b/pkg/hostman/hostdeployer/deployserver/deployserver.go @@ -226,7 +226,7 @@ func (s *SDeployService) PrepareEnv() error { } if !winutils.CheckTool(DeployOption.ChntpwPath) { - return fmt.Errorf("Failed to find chntpw tool") + log.Errorf("Failed to find chntpw tool") } output, err = procutils.NewCommand("pvscan").Run()