mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
fix(host,host-deployer): support lvm disk resize (#23333)
- add resize lvm disk support - support qga online resize disk partitions and filesystems
This commit is contained in:
@@ -148,7 +148,17 @@ func resizeHandler(ctx context.Context, w http.ResponseWriter, r *http.Request)
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
return
|
||||
}
|
||||
hostutils.DelayTask(ctx, disk.Resize, diskInfo)
|
||||
resizeDiskInfo := &storageman.SDiskResizeInput{
|
||||
DiskInfo: diskInfo,
|
||||
}
|
||||
resizeFunc := func(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
input, ok := params.(*storageman.SDiskResizeInput)
|
||||
if !ok {
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
return disk.Resize(ctx, input)
|
||||
}
|
||||
hostutils.DelayTask(ctx, resizeFunc, resizeDiskInfo)
|
||||
hostutils.ResponseOk(ctx, w)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@ import (
|
||||
)
|
||||
|
||||
type IDeployer interface {
|
||||
Connect(desc *apis.GuestDesc) error
|
||||
Connect(desc *apis.GuestDesc, diskId string) error
|
||||
Disconnect() error
|
||||
|
||||
GetPartitions() []fsdriver.IDiskPartition
|
||||
IsLVMPartition() bool
|
||||
Zerofree()
|
||||
ResizePartition() error
|
||||
ResizePartition(diskId string, rootPartDev string) error
|
||||
FormatPartition(fs, uuid string) error
|
||||
MakePartition(fs string) error
|
||||
|
||||
@@ -35,7 +35,7 @@ type IDeployer interface {
|
||||
DetectIsUEFISupport(rootfs fsdriver.IRootFsDriver) bool
|
||||
|
||||
DeployGuestfs(req *apis.DeployParams) (res *apis.DeployGuestFsResponse, err error)
|
||||
ResizeFs() (res *apis.Empty, err error)
|
||||
ResizeFs(req *apis.ResizeFsParams) (res *apis.Empty, err error)
|
||||
FormatFs(req *apis.FormatFsParams) (*apis.Empty, error)
|
||||
SaveToGlance(req *apis.SaveToGlanceParams) (*apis.SaveToGlanceResponse, error)
|
||||
ProbeImageInfo(req *apis.ProbeImageInfoPramas) (*apis.ImageInfo, error)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// 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 driver // import "yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils/driver"
|
||||
@@ -0,0 +1,87 @@
|
||||
// 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 driver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
type IFsutilExecDriver interface {
|
||||
Run(name string, args ...string) error
|
||||
Exec(name string, args ...string) ([]byte, error)
|
||||
ExecInputWait(name string, args []string, input []string) (int, string, string, error)
|
||||
}
|
||||
|
||||
type SProcDriver struct {
|
||||
}
|
||||
|
||||
func NewProcDriver() IFsutilExecDriver {
|
||||
return new(SProcDriver)
|
||||
}
|
||||
|
||||
func (*SProcDriver) Exec(name string, args ...string) ([]byte, error) {
|
||||
return procutils.NewCommand(name, args...).Output()
|
||||
}
|
||||
|
||||
func (*SProcDriver) Run(name string, args ...string) error {
|
||||
return procutils.NewCommand(name, args...).Run()
|
||||
}
|
||||
|
||||
func (*SProcDriver) ExecInputWait(name string, args []string, input []string) (int, string, string, error) {
|
||||
proc := procutils.NewCommand(name, args...)
|
||||
stdin, err := proc.StdinPipe()
|
||||
if err != nil {
|
||||
return -1, "", "", err
|
||||
}
|
||||
defer stdin.Close()
|
||||
|
||||
outb, err := proc.StdoutPipe()
|
||||
if err != nil {
|
||||
return -1, "", "", err
|
||||
}
|
||||
defer outb.Close()
|
||||
|
||||
errb, err := proc.StderrPipe()
|
||||
if err != nil {
|
||||
return -1, "", "", err
|
||||
}
|
||||
defer errb.Close()
|
||||
if err := proc.Start(); err != nil {
|
||||
return -1, "", "", err
|
||||
}
|
||||
for _, s := range input {
|
||||
io.WriteString(stdin, fmt.Sprintf("%s\n", s))
|
||||
}
|
||||
stdoutPut, err := ioutil.ReadAll(outb)
|
||||
if err != nil {
|
||||
return -1, "", "", err
|
||||
}
|
||||
stderrOutPut, err := ioutil.ReadAll(errb)
|
||||
if err != nil {
|
||||
return -1, "", "", err
|
||||
}
|
||||
if err = proc.Wait(); err != nil {
|
||||
if status, succ := proc.GetExitStatus(err); succ {
|
||||
return status, string(stdoutPut), string(stderrOutPut), err
|
||||
} else {
|
||||
return 0, string(stdoutPut), string(stderrOutPut), err
|
||||
}
|
||||
}
|
||||
return 0, string(stdoutPut), string(stderrOutPut), nil
|
||||
}
|
||||
@@ -16,8 +16,6 @@ package fsutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -27,6 +25,7 @@ import (
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/hostman/diskutils/deploy_iface"
|
||||
"yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils/driver"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestfs"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
|
||||
@@ -124,16 +123,27 @@ func ParseDiskPartition(dev string, lines []string) ([][]string, string) {
|
||||
return parts, label
|
||||
}
|
||||
|
||||
func GetDevSector512Count(dev string) int {
|
||||
sizeStr, _ := fileutils2.FileGetContents(fmt.Sprintf("/sys/block/%s/size", dev))
|
||||
sizeStr = strings.Trim(sizeStr, "\n")
|
||||
size, _ := strconv.Atoi(sizeStr)
|
||||
return size
|
||||
// use proc driver do resizefs
|
||||
func ResizeDiskFs(diskPath string, sizeMb int) error {
|
||||
fsutilDriver := NewFsutilDriver(driver.NewProcDriver())
|
||||
return fsutilDriver.ResizeDiskFs(diskPath, sizeMb)
|
||||
}
|
||||
|
||||
func ResizeDiskFs(diskPath string, sizeMb int) error {
|
||||
func (d *SFsutilDriver) ResizeDiskFs(diskPath string, sizeMb int) error {
|
||||
fPath, fs, err := d.ResizeDiskPartition(diskPath, sizeMb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err, _ = d.ResizePartitionFs(fPath, fs, false, false)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "resize fs %s", fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) ResizeDiskPartition(diskPath string, sizeMb int) (string, string, error) {
|
||||
var cmds = []string{"parted", "-a", "none", "-s", diskPath, "--", "unit", "s", "print"}
|
||||
lines, err := procutils.NewCommand(cmds[0], cmds[1:]...).Output()
|
||||
lines, err := d.Exec(cmds[0], cmds[1:]...)
|
||||
if err != nil {
|
||||
hasPartTable := func() bool {
|
||||
for _, line := range strings.Split(string(lines), "\n") {
|
||||
@@ -144,74 +154,108 @@ func ResizeDiskFs(diskPath string, sizeMb int) error {
|
||||
return false
|
||||
}
|
||||
if hasPartTable() {
|
||||
return nil
|
||||
return "", "", nil
|
||||
}
|
||||
log.Errorf("resize disk fs fail, output: %s , error: %s", lines, err)
|
||||
return err
|
||||
return "", "", err
|
||||
}
|
||||
parts, label := ParseDiskPartition(diskPath, strings.Split(string(lines), "\n"))
|
||||
log.Infof("Parts: %v label: %s", parts, label)
|
||||
if label == "gpt" {
|
||||
proc := procutils.NewCommand("gdisk", diskPath)
|
||||
stdin, err := proc.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
retCode, stdout, stderr, e := d.ExecInputWait("gdisk", []string{diskPath}, []string{"r", "e", "Y", "w", "Y", "Y"})
|
||||
if e != nil {
|
||||
return "", "", errors.Wrap(e, "gdisk exec failed")
|
||||
}
|
||||
defer stdin.Close()
|
||||
|
||||
outb, err := proc.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outb.Close()
|
||||
|
||||
errb, err := proc.StderrPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer errb.Close()
|
||||
|
||||
if err := proc.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range []string{"r", "e", "Y", "w", "Y", "Y"} {
|
||||
io.WriteString(stdin, fmt.Sprintf("%s\n", s))
|
||||
}
|
||||
stdoutPut, err := ioutil.ReadAll(outb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stderrOutPut, err := ioutil.ReadAll(errb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("gdisk: %s %s", stdoutPut, stderrOutPut)
|
||||
if err = proc.Wait(); err != nil {
|
||||
if status, succ := proc.GetExitStatus(err); succ {
|
||||
if status != 1 {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
log.Infof("gdisk: %s %s", stdout, stderr)
|
||||
if retCode != 1 && retCode != 0 {
|
||||
return "", "", errors.Errorf("Exit Code %d: %s\n%s", retCode, stdout, stderr)
|
||||
}
|
||||
}
|
||||
if len(parts) > 0 && (label == "gpt" ||
|
||||
(label == "msdos" && parts[len(parts)-1][5] == "primary")) {
|
||||
var part = parts[len(parts)-1]
|
||||
if IsSupportResizeFs(part[6]) {
|
||||
if part[5] == "lvm" || IsSupportResizeFs(part[6]) {
|
||||
// growpart script replace parted resizepart
|
||||
output, err := procutils.NewCommand("growpart", diskPath, part[0]).Output()
|
||||
output, err := d.Exec("growpart", diskPath, part[0])
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "growpart failed %s", output)
|
||||
}
|
||||
err, _ = ResizePartitionFs(part[7], part[6], false)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "resize fs %s", part[6])
|
||||
return "", "", errors.Wrapf(err, "growpart failed %s", output)
|
||||
}
|
||||
return part[7], part[6], nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) ResizeDiskWithDiskId(diskId string, rootPartDev string, onlineResize bool) error {
|
||||
// find partition need resize
|
||||
resizeDev, err := d.GetResizeDevBySerial(diskId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resizeDev == "" {
|
||||
log.Errorf("failed find disk serial %s", diskId)
|
||||
return nil
|
||||
}
|
||||
partDev, fsType, err := d.ResizeDiskPartition(resizeDev, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if partDev == "" || fsType == "" {
|
||||
if fsType == "" && partDev != "" {
|
||||
// fsType empty and partDev not empty is lvm device
|
||||
resizeDev = partDev
|
||||
}
|
||||
|
||||
if !d.IsLvmPvDevice(resizeDev) {
|
||||
fsType = d.GetFsFormat(resizeDev)
|
||||
err, _ := d.ResizePartitionFs(resizeDev, fsType, false, onlineResize)
|
||||
return err
|
||||
}
|
||||
if err := d.Pvresize(resizeDev); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vg := d.GetVgOfPvDevice(resizeDev)
|
||||
if vg == "" {
|
||||
return nil
|
||||
}
|
||||
lvs, err := d.GetVgLvs(vg)
|
||||
if err != nil {
|
||||
log.Errorf("failed get vg lvs %s: %s", vg, err)
|
||||
}
|
||||
if len(lvs) == 0 {
|
||||
log.Infof("disk %s has no lv, skip resize", diskId)
|
||||
return nil
|
||||
}
|
||||
|
||||
var resizeLv string
|
||||
if rootPartDev != "" {
|
||||
for i := range lvs {
|
||||
if lvs[i].LvPath == rootPartDev {
|
||||
resizeLv = rootPartDev
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if resizeLv == "" {
|
||||
if len(lvs) != 1 {
|
||||
log.Errorf("disk %s has multi lv and no rootfs, skip resize partition", diskId)
|
||||
return nil
|
||||
} else {
|
||||
resizeLv = lvs[0].LvPath
|
||||
}
|
||||
}
|
||||
err = d.ExtendLv(resizeLv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fsType = d.GetFsFormat(resizeLv)
|
||||
err, _ = d.ResizePartitionFs(resizeLv, fsType, false, onlineResize)
|
||||
return err
|
||||
} else {
|
||||
err, _ = d.ResizePartitionFs(partDev, fsType, false, onlineResize)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func IsSupportResizeFs(fs string) bool {
|
||||
@@ -225,13 +269,14 @@ func IsSupportResizeFs(fs string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
|
||||
func (d *SFsutilDriver) ResizePartitionFs(fpath, fs string, raiseError, onlineResize bool) (error, bool) {
|
||||
log.Errorf("ResizePartitionFs fstype %s", fs)
|
||||
if len(fs) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
var (
|
||||
cmds = [][]string{}
|
||||
uuids, _ = fileutils2.GetDevUuid(fpath)
|
||||
uuids, _ = d.GetDevUuid(fpath)
|
||||
)
|
||||
if strings.HasPrefix(fs, "linux-swap") {
|
||||
if v, ok := uuids["UUID"]; ok {
|
||||
@@ -240,37 +285,43 @@ func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
|
||||
cmds = [][]string{{"mkswap", fpath}}
|
||||
}
|
||||
} else if strings.HasPrefix(fs, "ext") {
|
||||
if !FsckExtFs(fpath) {
|
||||
if raiseError {
|
||||
return fmt.Errorf("Failed to fsck ext fs %s", fpath), false
|
||||
} else {
|
||||
return nil, false
|
||||
if !onlineResize {
|
||||
if !d.FsckExtFs(fpath) {
|
||||
if raiseError {
|
||||
return fmt.Errorf("Failed to fsck ext fs %s", fpath), false
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
cmds = [][]string{{"resize2fs", fpath}}
|
||||
} else if fs == "xfs" {
|
||||
var tmpPoint = fmt.Sprintf("/tmp/%s", strings.Replace(fpath, "/", "_", -1))
|
||||
if _, err := procutils.NewCommand("mountpoint", tmpPoint).Output(); err == nil {
|
||||
output, err := procutils.NewCommand("umount", "-f", tmpPoint).Output()
|
||||
if err != nil {
|
||||
log.Errorf("failed umount %s: %s, %s", tmpPoint, err, output)
|
||||
return err, false
|
||||
}
|
||||
}
|
||||
FsckXfsFs(fpath)
|
||||
uuid := uuids["UUID"]
|
||||
if len(uuid) > 0 {
|
||||
xfsutils.LockXfsPartition(uuid)
|
||||
defer xfsutils.UnlockXfsPartition(uuid)
|
||||
}
|
||||
cmds = [][]string{{"mkdir", "-p", tmpPoint},
|
||||
{"mount", fpath, tmpPoint},
|
||||
{"sleep", "2"},
|
||||
{"xfs_growfs", tmpPoint},
|
||||
{"sleep", "2"},
|
||||
{"umount", tmpPoint},
|
||||
{"sleep", "2"},
|
||||
{"rm", "-fr", tmpPoint}}
|
||||
if !onlineResize {
|
||||
var tmpPoint = fmt.Sprintf("/tmp/%s", strings.Replace(fpath, "/", "_", -1))
|
||||
if _, err := d.Exec("mountpoint", tmpPoint); err == nil {
|
||||
output, err := d.Exec("umount", "-f", tmpPoint)
|
||||
if err != nil {
|
||||
log.Errorf("failed umount %s: %s, %s", tmpPoint, err, output)
|
||||
return err, false
|
||||
}
|
||||
}
|
||||
d.FsckXfsFs(fpath)
|
||||
cmds = [][]string{{"mkdir", "-p", tmpPoint},
|
||||
{"mount", fpath, tmpPoint},
|
||||
{"sleep", "2"},
|
||||
{"xfs_growfs", tmpPoint},
|
||||
{"sleep", "2"},
|
||||
{"umount", tmpPoint},
|
||||
{"sleep", "2"},
|
||||
{"rm", "-fr", tmpPoint}}
|
||||
} else {
|
||||
cmds = [][]string{{"xfs_growfs", fpath}}
|
||||
}
|
||||
} else if fs == "ntfs" {
|
||||
// the following cmds may cause disk damage on Windows 10 with new version of NTFS
|
||||
// comment out the following codes only impact Windows 2003
|
||||
@@ -280,7 +331,7 @@ func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
|
||||
|
||||
if len(cmds) > 0 {
|
||||
for _, cmd := range cmds {
|
||||
output, err := procutils.NewCommand(cmd[0], cmd[1:]...).Output()
|
||||
output, err := d.Exec(cmd[0], cmd[1:]...)
|
||||
if err != nil {
|
||||
log.Errorf("resize partition: %s, %s", err, output)
|
||||
if raiseError {
|
||||
@@ -294,37 +345,29 @@ func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
|
||||
return nil, true
|
||||
}
|
||||
|
||||
func FsckExtFs(fpath string) bool {
|
||||
func (d *SFsutilDriver) FsckExtFs(fpath string) bool {
|
||||
log.Debugf("Exec command: %v", []string{"e2fsck", "-f", "-p", fpath})
|
||||
cmd := procutils.NewCommand("e2fsck", "-f", "-p", fpath)
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Errorf("e2fsck start failed: %s", err)
|
||||
retCode, stdout, stderr, err := d.ExecInputWait("e2fsck", []string{"-f", "-p", fpath}, nil)
|
||||
if err != nil {
|
||||
log.Errorf("exec e2fsck failed %s", err)
|
||||
return false
|
||||
} else {
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
if status, ok := cmd.GetExitStatus(err); ok {
|
||||
if status < 4 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
log.Errorln(err)
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if retCode < 4 {
|
||||
return true
|
||||
}
|
||||
log.Errorf("failed e2fsck retcode %d %s %s", retCode, stdout, stderr)
|
||||
return false
|
||||
}
|
||||
|
||||
// https://bugs.launchpad.net/ubuntu/+source/xfsprogs/+bug/1718244
|
||||
// use xfs_repair -n instead
|
||||
func FsckXfsFs(fpath string) bool {
|
||||
if output, err := procutils.NewCommand("xfs_check", fpath).Output(); err != nil {
|
||||
func (d *SFsutilDriver) FsckXfsFs(fpath string) bool {
|
||||
if output, err := d.Exec("xfs_check", fpath); err != nil {
|
||||
log.Errorf("xfs_check failed: %s, %s, try xfs_repair -n <dev> instead", err, output)
|
||||
if output, err := procutils.NewCommand("xfs_repair", "-n", fpath).Output(); err != nil {
|
||||
log.Errorf("xfs_repair -n dev failed: %s, %s", err, output)
|
||||
// repair the xfs
|
||||
procutils.NewCommand("xfs_repair", fpath).Output()
|
||||
d.Exec("xfs_repair", fpath)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -516,7 +559,7 @@ func DeployGuestfs(d deploy_iface.IDeployer, req *apis.DeployParams) (res *apis.
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func ResizeFs(d deploy_iface.IDeployer) (*apis.Empty, error) {
|
||||
func ResizeFs(d deploy_iface.IDeployer, diskId string) (*apis.Empty, error) {
|
||||
unmount := func(root fsdriver.IRootFsDriver) error {
|
||||
err := d.UmountRootfs(root)
|
||||
if err != nil {
|
||||
@@ -525,10 +568,12 @@ func ResizeFs(d deploy_iface.IDeployer) (*apis.Empty, error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var rootPartDev string
|
||||
root, err := d.MountRootfs(false)
|
||||
if err != nil && errors.Cause(err) != errors.ErrNotFound {
|
||||
return new(apis.Empty), errors.Wrapf(err, "disk.MountRootfs")
|
||||
} else if err == nil {
|
||||
rootPartDev = root.GetPartition().GetPartDev()
|
||||
if !root.IsResizeFsPartitionSupport() {
|
||||
err := unmount(root)
|
||||
if err != nil {
|
||||
@@ -543,8 +588,7 @@ func ResizeFs(d deploy_iface.IDeployer) (*apis.Empty, error) {
|
||||
return new(apis.Empty), err
|
||||
}
|
||||
}
|
||||
|
||||
err = d.ResizePartition()
|
||||
err = d.ResizePartition(diskId, rootPartDev)
|
||||
if err != nil {
|
||||
return new(apis.Empty), errors.Wrap(err, "resize disk partition")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,825 @@
|
||||
// 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 fsutils
|
||||
|
||||
var GrowPartScript = `
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2011 Canonical Ltd.
|
||||
# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Authors: Scott Moser <smoser@canonical.com>
|
||||
# Juerg Haefliger <juerg.haefliger@hp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# the fudge factor. if within this many bytes dont bother
|
||||
FUDGE=${GROWPART_FUDGE:-$((1024*1024))}
|
||||
TEMP_D=""
|
||||
RESTORE_FUNC=""
|
||||
RESTORE_HUMAN=""
|
||||
VERBOSITY=0
|
||||
DISK=""
|
||||
PART=""
|
||||
PT_UPDATE=false
|
||||
DRY_RUN=0
|
||||
|
||||
SFDISK_VERSION=""
|
||||
SFDISK_2_26="22600"
|
||||
SFDISK_V_WORKING_GPT="22603"
|
||||
MBR_BACKUP=""
|
||||
GPT_BACKUP=""
|
||||
_capture=""
|
||||
|
||||
error() {
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
fail() {
|
||||
[ $# -eq 0 ] || echo "FAILED:" "$@"
|
||||
exit 2
|
||||
}
|
||||
|
||||
nochange() {
|
||||
echo "NOCHANGE:" "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
changed() {
|
||||
echo "CHANGED:" "$@"
|
||||
exit 0
|
||||
}
|
||||
|
||||
change() {
|
||||
echo "CHANGE:" "$@"
|
||||
exit 0
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if [ -n "${RESTORE_FUNC}" ]; then
|
||||
error "***** WARNING: Resize failed, attempting to revert ******"
|
||||
if ${RESTORE_FUNC} ; then
|
||||
error "***** Restore appears to have gone OK ****"
|
||||
else
|
||||
error "***** Restore FAILED! ******"
|
||||
if [ -n "${RESTORE_HUMAN}" -a -f "${RESTORE_HUMAN}" ]; then
|
||||
error "**** original table looked like: ****"
|
||||
cat "${RESTORE_HUMAN}" 1>&2
|
||||
else
|
||||
error "We seem to have not saved the partition table!"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
[ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
|
||||
}
|
||||
|
||||
debug() {
|
||||
local level=${1}
|
||||
shift
|
||||
[ "${level}" -gt "${VERBOSITY}" ] && return
|
||||
if [ "${DEBUG_LOG}" ]; then
|
||||
echo "$@" >>"${DEBUG_LOG}"
|
||||
else
|
||||
error "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
debugcat() {
|
||||
local level="$1"
|
||||
shift;
|
||||
[ "${level}" -gt "$VERBOSITY" ] && return
|
||||
if [ "${DEBUG_LOG}" ]; then
|
||||
cat "$@" >>"${DEBUG_LOG}"
|
||||
else
|
||||
cat "$@" 1>&2
|
||||
fi
|
||||
}
|
||||
|
||||
mktemp_d() {
|
||||
# just a mktemp -d that doens't need mktemp if its not there.
|
||||
_RET=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX" 2>/dev/null) &&
|
||||
return
|
||||
_RET=$(umask 077 && t="${TMPDIR:-/tmp}/${0##*/}.$$" &&
|
||||
mkdir "${t}" && echo "${t}")
|
||||
return
|
||||
}
|
||||
|
||||
Usage() {
|
||||
cat <<EOF
|
||||
${0##*/} disk partition
|
||||
rewrite partition table so that partition takes up all the space it can
|
||||
options:
|
||||
-h | --help print Usage and exit
|
||||
--fudge F if part could be resized, but change would be
|
||||
less than 'F' bytes, do not resize (default: ${FUDGE})
|
||||
-N | --dry-run only report what would be done, show new 'sfdisk -d'
|
||||
-v | --verbose increase verbosity / debug
|
||||
-u | --update R update the the kernel partition table info after growing
|
||||
this requires kernel support and 'partx --update'
|
||||
R is one of:
|
||||
- 'auto' : [default] update partition if possible
|
||||
- 'force' : try despite sanity checks (fail on failure)
|
||||
- 'off' : do not attempt
|
||||
- 'on' : fail if sanity checks indicate no support
|
||||
|
||||
Example:
|
||||
- ${0##*/} /dev/sda 1
|
||||
Resize partition 1 on /dev/sda
|
||||
EOF
|
||||
}
|
||||
|
||||
bad_Usage() {
|
||||
Usage 1>&2
|
||||
error "$@"
|
||||
exit 2
|
||||
}
|
||||
|
||||
sfdisk_restore_legacy() {
|
||||
sfdisk --no-reread "${DISK}" -I "${MBR_BACKUP}"
|
||||
}
|
||||
|
||||
sfdisk_restore() {
|
||||
# files are named: sfdisk-<device>-<offset>.bak
|
||||
local f="" offset="" fails=0
|
||||
for f in "${MBR_BACKUP}"*.bak; do
|
||||
[ -f "$f" ] || continue
|
||||
offset=${f##*-}
|
||||
offset=${offset%.bak}
|
||||
[ "$offset" = "$f" ] && {
|
||||
error "WARN: confused by file $f";
|
||||
continue;
|
||||
}
|
||||
dd "if=$f" "of=${DISK}" seek=$(($offset)) bs=1 conv=notrunc ||
|
||||
{ error "WARN: failed restore from $f"; fails=$(($fails+1)); }
|
||||
done
|
||||
return $fails
|
||||
}
|
||||
|
||||
sfdisk_worked_but_blkrrpart_failed() {
|
||||
local ret="$1" output="$2"
|
||||
# exit code found was just 1, but dont insist on that
|
||||
#[ $ret -eq 1 ] || return 1
|
||||
# Successfully wrote the new partition table
|
||||
if grep -qi "Success.* wrote.* new.* partition" "$output"; then
|
||||
grep -qi "BLKRRPART: Device or resource busy" "$output"
|
||||
return
|
||||
# The partition table has been altered.
|
||||
elif grep -qi "The.* part.* table.* has.* been.* altered" "$output"; then
|
||||
# Re-reading the partition table failed
|
||||
grep -qi "Re-reading.* partition.* table.* failed" "$output"
|
||||
return
|
||||
fi
|
||||
return $ret
|
||||
}
|
||||
|
||||
get_sfdisk_version() {
|
||||
# set SFDISK_VERSION to MAJOR*10000+MINOR*100+MICRO
|
||||
local out oifs="$IFS" ver=""
|
||||
[ -n "$SFDISK_VERSION" ] && return 0
|
||||
# expected output: sfdisk from util-linux 2.25.2
|
||||
out=$(LANG=C sfdisk --version) ||
|
||||
{ error "failed to get sfdisk version"; return 1; }
|
||||
set -- $out
|
||||
ver=$4
|
||||
case "$ver" in
|
||||
[0-9]*.[0-9]*.[0-9]|[0-9].[0-9]*)
|
||||
IFS="."; set -- $ver; IFS="$oifs"
|
||||
SFDISK_VERSION=$(($1*10000+$2*100+${3:-0}))
|
||||
return 0;;
|
||||
*) error "unexpected output in sfdisk --version [$out]"
|
||||
return 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
resize_sfdisk() {
|
||||
local humanpt="${TEMP_D}/recovery"
|
||||
local mbr_backup="${TEMP_D}/orig.save"
|
||||
local restore_func=""
|
||||
local format="$1"
|
||||
|
||||
local change_out=${TEMP_D}/change.out
|
||||
local dump_out=${TEMP_D}/dump.out
|
||||
local new_out=${TEMP_D}/new.out
|
||||
local dump_mod=${TEMP_D}/dump.mod
|
||||
local tmp="${TEMP_D}/tmp.out"
|
||||
local err="${TEMP_D}/err.out"
|
||||
local mbr_max_512="4294967296"
|
||||
|
||||
local pt_start pt_size pt_end max_end new_size change_info dpart
|
||||
local sector_num sector_size disk_size tot out
|
||||
|
||||
LANG=C rqe sfd_list sfdisk --list --unit=S "$DISK" >"$tmp" ||
|
||||
fail "failed: sfdisk --list $DISK"
|
||||
if [ "${SFDISK_VERSION}" -lt ${SFDISK_2_26} ]; then
|
||||
# exected output contains: Units: sectors of 512 bytes, ...
|
||||
out=$(awk '$1 == "Units:" && $5 ~ /bytes/ { print $4 }' "$tmp") ||
|
||||
fail "failed to read sfdisk output"
|
||||
if [ -z "$out" ]; then
|
||||
error "WARN: sector size not found in sfdisk output, assuming 512"
|
||||
sector_size=512
|
||||
else
|
||||
sector_size="$out"
|
||||
fi
|
||||
local _w _cyl _w1 _heads _w2 sectors _w3 t s
|
||||
# show-size is in units of 1024 bytes (same as /proc/partitions)
|
||||
t=$(sfdisk --show-size "${DISK}") ||
|
||||
fail "failed: sfdisk --show-size $DISK"
|
||||
disk_size=$((t*1024))
|
||||
sector_num=$(($disk_size/$sector_size))
|
||||
msg="disk size '$disk_size' not evenly div by sector size '$sector_size'"
|
||||
[ "$((${disk_size}%${sector_size}))" -eq 0 ] ||
|
||||
error "WARN: $msg"
|
||||
restore_func=sfdisk_restore_legacy
|
||||
else
|
||||
# --list first line output:
|
||||
# Disk /dev/vda: 20 GiB, 21474836480 bytes, 41943040 sectors
|
||||
local _x
|
||||
read _x _x _x _x disk_size _x sector_num _x < "$tmp"
|
||||
sector_size=$((disk_size/$sector_num))
|
||||
restore_func=sfdisk_restore
|
||||
fi
|
||||
|
||||
debug 1 "$sector_num sectors of $sector_size. total size=${disk_size} bytes"
|
||||
|
||||
rqe sfd_dump sfdisk --unit=S --dump "${DISK}" >"${dump_out}" ||
|
||||
fail "failed to dump sfdisk info for ${DISK}"
|
||||
RESTORE_HUMAN="$dump_out"
|
||||
|
||||
{
|
||||
echo "## sfdisk --unit=S --dump ${DISK}"
|
||||
cat "${dump_out}"
|
||||
} >"$humanpt"
|
||||
|
||||
[ $? -eq 0 ] || fail "failed to save sfdisk -d output"
|
||||
RESTORE_HUMAN="$humanpt"
|
||||
|
||||
debugcat 1 "$humanpt"
|
||||
|
||||
sed -e 's/,//g; s/start=/start /; s/size=/size /' "${dump_out}" \
|
||||
>"${dump_mod}" ||
|
||||
fail "sed failed on dump output"
|
||||
|
||||
dpart="${DISK}${PART}" # disk and partition number
|
||||
if [ -b "${DISK}p${PART}" -a "${DISK%[0-9]}" != "${DISK}" ]; then
|
||||
# for block devices that end in a number (/dev/nbd0)
|
||||
# the partition is "<name>p<partition_number>" (/dev/nbd0p1)
|
||||
dpart="${DISK}p${PART}"
|
||||
elif [ "${DISK#/dev/loop[0-9]}" != "${DISK}" ]; then
|
||||
# for /dev/loop devices, sfdisk output will be <name>p<number>
|
||||
# format also, even though there is not a device there.
|
||||
dpart="${DISK}p${PART}"
|
||||
fi
|
||||
|
||||
pt_start=$(awk '$1 == pt { print $4 }' "pt=${dpart}" <"${dump_mod}") &&
|
||||
pt_size=$(awk '$1 == pt { print $6 }' "pt=${dpart}" <"${dump_mod}") &&
|
||||
[ -n "${pt_start}" -a -n "${pt_size}" ] &&
|
||||
pt_end=$((${pt_size}+${pt_start})) ||
|
||||
fail "failed to get start and end for ${dpart} in ${DISK}"
|
||||
|
||||
# find the minimal starting location that is >= pt_end
|
||||
max_end=$(awk '$3 == "start" { if($4 >= pt_end && $4 < min)
|
||||
{ min = $4 } } END { printf("%s\n",min); }' \
|
||||
min=${sector_num} pt_end=${pt_end} "${dump_mod}") &&
|
||||
[ -n "${max_end}" ] ||
|
||||
fail "failed to get max_end for partition ${PART}"
|
||||
|
||||
if [ "$format" = "gpt" ]; then
|
||||
# sfdisk respects 'last-lba' in input, and complains about
|
||||
# partitions that go past that. without it, it does the right thing.
|
||||
sed -i '/^last-lba:/d' "$dump_out" ||
|
||||
fail "failed to remove last-lba from output"
|
||||
fi
|
||||
if [ "$format" = "dos" ]; then
|
||||
mbr_max_sectors=$((mbr_max_512*$((sector_size/512))))
|
||||
if [ "$max_end" -gt "$mbr_max_sectors" ]; then
|
||||
max_end=$mbr_max_sectors
|
||||
fi
|
||||
[ $(($disk_size/512)) -gt $mbr_max_512 ] &&
|
||||
debug 0 "WARNING: MBR/dos partitioned disk is larger than 2TB." \
|
||||
"Additional space will go unused."
|
||||
fi
|
||||
|
||||
local gpt_second_size="33"
|
||||
if [ "${max_end}" -gt "$((${sector_num}-${gpt_second_size}))" ]; then
|
||||
# if mbr allow subsequent conversion to gpt without shrinking the
|
||||
# partition. safety net at cost of 33 sectors, seems reasonable.
|
||||
# if gpt, we can't write there anyway.
|
||||
debug 1 "padding ${gpt_second_size} sectors for gpt secondary header"
|
||||
max_end=$((${sector_num}-${gpt_second_size}))
|
||||
fi
|
||||
|
||||
debug 1 "max_end=${max_end} tot=${sector_num} pt_end=${pt_end}" \
|
||||
"pt_start=${pt_start} pt_size=${pt_size}"
|
||||
[ $((${pt_end})) -eq ${max_end} ] &&
|
||||
nochange "partition ${PART} is size ${pt_size}. it cannot be grown"
|
||||
[ $((${pt_end}+(${FUDGE}/$sector_size))) -gt ${max_end} ] &&
|
||||
nochange "partition ${PART} could only be grown by" \
|
||||
"$((${max_end}-${pt_end})) [fudge=$((${FUDGE}/$sector_size))]"
|
||||
|
||||
# now, change the size for this partition in ${dump_out} to be the
|
||||
# new size
|
||||
new_size=$((${max_end}-${pt_start}))
|
||||
sed "\|^\s*${dpart} |s/\(.*\)${pt_size},/\1${new_size},/" "${dump_out}" \
|
||||
>"${new_out}" ||
|
||||
fail "failed to change size in output"
|
||||
|
||||
change_info="partition=${PART} start=${pt_start}"
|
||||
change_info="${change_info} old: size=${pt_size} end=${pt_end}"
|
||||
change_info="${change_info} new: size=${new_size} end=${max_end}"
|
||||
if [ ${DRY_RUN} -ne 0 ]; then
|
||||
echo "CHANGE: ${change_info}"
|
||||
{
|
||||
echo "# === old sfdisk -d ==="
|
||||
cat "${dump_out}"
|
||||
echo "# === new sfdisk -d ==="
|
||||
cat "${new_out}"
|
||||
} 1>&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
MBR_BACKUP="${mbr_backup}"
|
||||
LANG=C sfdisk --no-reread "${DISK}" --force \
|
||||
-O "${mbr_backup}" <"${new_out}" >"${change_out}" 2>&1
|
||||
ret=$?
|
||||
[ $ret -eq 0 ] || RESTORE_FUNC="${restore_func}"
|
||||
|
||||
if [ $ret -eq 0 ]; then
|
||||
debug 1 "resize of ${DISK} returned 0."
|
||||
if [ $VERBOSITY -gt 2 ]; then
|
||||
sed 's,^,| ,' "${change_out}" 1>&2
|
||||
fi
|
||||
elif $PT_UPDATE &&
|
||||
sfdisk_worked_but_blkrrpart_failed "$ret" "${change_out}"; then
|
||||
# if the command failed, but it looks like only because
|
||||
# the device was busy and we have pt_update, then go on
|
||||
debug 1 "sfdisk failed, but likely only because of blkrrpart"
|
||||
else
|
||||
error "attempt to resize ${DISK} failed. sfdisk output below:"
|
||||
sed 's,^,| ,' "${change_out}" 1>&2
|
||||
fail "failed to resize"
|
||||
fi
|
||||
|
||||
rq pt_update pt_update "$DISK" "$PART" ||
|
||||
fail "pt_resize failed"
|
||||
|
||||
RESTORE_FUNC=""
|
||||
|
||||
changed "${change_info}"
|
||||
|
||||
# dump_out looks something like:
|
||||
## partition table of /tmp/out.img
|
||||
#unit: sectors
|
||||
#
|
||||
#/tmp/out.img1 : start= 1, size= 48194, Id=83
|
||||
#/tmp/out.img2 : start= 48195, size= 963900, Id=83
|
||||
#/tmp/out.img3 : start= 1012095, size= 305235, Id=82
|
||||
#/tmp/out.img4 : start= 1317330, size= 771120, Id= 5
|
||||
#/tmp/out.img5 : start= 1317331, size= 642599, Id=83
|
||||
#/tmp/out.img6 : start= 1959931, size= 48194, Id=83
|
||||
#/tmp/out.img7 : start= 2008126, size= 80324, Id=83
|
||||
}
|
||||
|
||||
gpt_restore() {
|
||||
sgdisk -l "${GPT_BACKUP}" "${DISK}"
|
||||
}
|
||||
|
||||
resize_sgdisk() {
|
||||
GPT_BACKUP="${TEMP_D}/pt.backup"
|
||||
|
||||
local pt_info="${TEMP_D}/pt.info"
|
||||
local pt_pretend="${TEMP_D}/pt.pretend"
|
||||
local pt_data="${TEMP_D}/pt.data"
|
||||
local out="${TEMP_D}/out"
|
||||
|
||||
local dev="disk=${DISK} partition=${PART}"
|
||||
|
||||
local pt_start pt_end pt_size last pt_max code guid name new_size
|
||||
local old new change_info sector_size
|
||||
|
||||
# Dump the original partition information and details to disk. This is
|
||||
# used in case something goes wrong and human interaction is required
|
||||
# to revert any changes.
|
||||
rqe sgd_info sgdisk "--info=${PART}" --print "${DISK}" >"${pt_info}" ||
|
||||
fail "${dev}: failed to dump original sgdisk info"
|
||||
RESTORE_HUMAN="${pt_info}"
|
||||
|
||||
sector_size=$(awk '$0 ~ /^Logical sector size:.*bytes/ { print $4 }' \
|
||||
"$pt_info") && [ -n "$sector_size" ] || {
|
||||
sector_size=512
|
||||
error "WARN: did not find sector size, assuming 512"
|
||||
}
|
||||
|
||||
debug 1 "$dev: original sgdisk info:"
|
||||
debugcat 1 "${pt_info}"
|
||||
|
||||
# Pretend to move the backup GPT header to the end of the disk and dump
|
||||
# the resulting partition information. We use this info to determine if
|
||||
# we have to resize the partition.
|
||||
rqe sgd_pretend sgdisk --pretend --move-second-header \
|
||||
--print "${DISK}" >"${pt_pretend}" ||
|
||||
fail "${dev}: failed to dump pretend sgdisk info"
|
||||
|
||||
debug 1 "$dev: pretend sgdisk info"
|
||||
debugcat 1 "${pt_pretend}"
|
||||
|
||||
# Extract the partition data from the pretend dump
|
||||
awk 'found { print } ; $1 == "Number" { found = 1 }' \
|
||||
"${pt_pretend}" >"${pt_data}" ||
|
||||
fail "${dev}: failed to parse pretend sgdisk info"
|
||||
|
||||
# Get the start and end sectors of the partition to be grown
|
||||
pt_start=$(awk '$1 == '"${PART}"' { print $2 }' "${pt_data}") &&
|
||||
[ -n "${pt_start}" ] ||
|
||||
fail "${dev}: failed to get start sector"
|
||||
pt_end=$(awk '$1 == '"${PART}"' { print $3 }' "${pt_data}") &&
|
||||
[ -n "${pt_end}" ] ||
|
||||
fail "${dev}: failed to get end sector"
|
||||
# sgdisk start and end are inclusive. start 2048 length 10 ends at 2057.
|
||||
pt_end=$((pt_end+1))
|
||||
pt_size="$((${pt_end} - ${pt_start}))"
|
||||
|
||||
# Get the last usable sector
|
||||
last=$(awk '/last usable sector is/ { print $NF }' \
|
||||
"${pt_pretend}") && [ -n "${last}" ] ||
|
||||
fail "${dev}: failed to get last usable sector"
|
||||
|
||||
# Find the minimal start sector that is >= pt_end
|
||||
pt_max=$(awk '{ if ($2 >= pt_end && $2 < min) { min = $2 } } END \
|
||||
{ print min }' min="${last}" pt_end="${pt_end}" \
|
||||
"${pt_data}") && [ -n "${pt_max}" ] ||
|
||||
fail "${dev}: failed to find max end sector"
|
||||
|
||||
debug 1 "${dev}: pt_start=${pt_start} pt_end=${pt_end}" \
|
||||
"pt_size=${pt_size} pt_max=${pt_max} last=${last}"
|
||||
|
||||
# Check if the partition can be grown
|
||||
[ "${pt_end}" -eq "${pt_max}" ] &&
|
||||
nochange "${dev}: size=${pt_size}, it cannot be grown"
|
||||
[ "$((${pt_end} + ${FUDGE}/${sector_size}))" -gt "${pt_max}" ] &&
|
||||
nochange "${dev}: could only be grown by" \
|
||||
"$((${pt_max} - ${pt_end})) [fudge=$((${FUDGE}/$sector_size))]"
|
||||
|
||||
# The partition can be grown if we made it here. Get some more info
|
||||
# about it so we can do it properly.
|
||||
# FIXME: Do we care about the attribute flags?
|
||||
code=$(awk '/^Partition GUID code:/ { print $4 }' "${pt_info}")
|
||||
guid=$(awk '/^Partition unique GUID:/ { print $4 }' "${pt_info}")
|
||||
name=$(awk '/^Partition name:/ { gsub(/'"'"'/, "") ; \
|
||||
if (NF >= 3) print substr($0, index($0, $3)) }' "${pt_info}")
|
||||
[ -n "${code}" -a -n "${guid}" ] ||
|
||||
fail "${dev}: failed to parse sgdisk details"
|
||||
|
||||
debug 1 "${dev}: code=${code} guid=${guid} name='${name}'"
|
||||
local wouldrun=""
|
||||
[ "$DRY_RUN" -ne 0 ] && wouldrun="would-run"
|
||||
|
||||
# Calculate the new size of the partition
|
||||
new_size=$((${pt_max} - ${pt_start}))
|
||||
change_info="partition=${PART} start=${pt_start}"
|
||||
change_info="${change_info} old: size=${pt_size} end=${pt_end}"
|
||||
change_info="${change_info} new: size=${new_size} end=${pt_max}"
|
||||
|
||||
# Backup the current partition table, we're about to modify it
|
||||
rq sgd_backup $wouldrun sgdisk "--backup=${GPT_BACKUP}" "${DISK}" ||
|
||||
fail "${dev}: failed to backup the partition table"
|
||||
|
||||
# Modify the partition table. We do it all in one go (the order is
|
||||
# important!):
|
||||
# - move the GPT backup header to the end of the disk
|
||||
# - delete the partition
|
||||
# - recreate the partition with the new size
|
||||
# - set the partition code
|
||||
# - set the partition GUID
|
||||
# - set the partition name
|
||||
rq sgdisk_mod $wouldrun sgdisk --move-second-header "--delete=${PART}" \
|
||||
"--new=${PART}:${pt_start}:$((pt_max-1))" \
|
||||
"--typecode=${PART}:${code}" \
|
||||
"--partition-guid=${PART}:${guid}" \
|
||||
"--change-name=${PART}:${name}" "${DISK}" &&
|
||||
rq pt_update $wouldrun pt_update "$DISK" "$PART" || {
|
||||
RESTORE_FUNC=gpt_restore
|
||||
fail "${dev}: failed to repartition"
|
||||
}
|
||||
|
||||
# Dry run
|
||||
[ "${DRY_RUN}" -ne 0 ] && change "${change_info}"
|
||||
|
||||
changed "${change_info}"
|
||||
}
|
||||
|
||||
kver_to_num() {
|
||||
local kver="$1" maj="" min="" mic="0"
|
||||
kver=${kver%%-*}
|
||||
maj=${kver%%.*}
|
||||
min=${kver#${maj}.}
|
||||
min=${min%%.*}
|
||||
mic=${kver#${maj}.${min}.}
|
||||
[ "$kver" = "$mic" ] && mic=0
|
||||
_RET=$(($maj*1000*1000+$min*1000+$mic))
|
||||
}
|
||||
|
||||
kver_cmp() {
|
||||
local op="$2" n1="" n2=""
|
||||
kver_to_num "$1"
|
||||
n1="$_RET"
|
||||
kver_to_num "$3"
|
||||
n2="$_RET"
|
||||
[ $n1 $op $n2 ]
|
||||
}
|
||||
|
||||
rq() {
|
||||
# runquieterror(label, command)
|
||||
# gobble stderr of a command unless it errors
|
||||
local label="$1" ret="" efile=""
|
||||
efile="$TEMP_D/$label.err"
|
||||
shift;
|
||||
|
||||
local rlabel="running"
|
||||
[ "$1" = "would-run" ] && rlabel="would-run" && shift
|
||||
|
||||
local cmd="" x=""
|
||||
for x in "$@"; do
|
||||
[ "${x#* }" != "$x" -o "${x#* \"}" != "$x" ] && x="'$x'"
|
||||
cmd="$cmd $x"
|
||||
done
|
||||
cmd=${cmd# }
|
||||
|
||||
debug 2 "$rlabel[$label][$_capture]" "$cmd"
|
||||
[ "$rlabel" = "would-run" ] && return 0
|
||||
|
||||
if [ "${_capture}" = "erronly" ]; then
|
||||
"$@" 2>"$TEMP_D/$label.err"
|
||||
ret=$?
|
||||
else
|
||||
"$@" >"$TEMP_D/$label.err" 2>&1
|
||||
ret=$?
|
||||
fi
|
||||
if [ $ret -ne 0 ]; then
|
||||
error "failed [$label:$ret]" "$@"
|
||||
cat "$efile" 1>&2
|
||||
fi
|
||||
return $ret
|
||||
}
|
||||
|
||||
rqe() {
|
||||
local _capture="erronly"
|
||||
rq "$@"
|
||||
}
|
||||
|
||||
verify_ptupdate() {
|
||||
local input="$1" found="" reason="" kver=""
|
||||
|
||||
# we can always satisfy 'off'
|
||||
if [ "$input" = "off" ]; then
|
||||
_RET="false";
|
||||
return 0;
|
||||
fi
|
||||
|
||||
if command -v partx >/dev/null 2>&1; then
|
||||
local out="" ret=0
|
||||
out=$(partx --help 2>&1)
|
||||
ret=$?
|
||||
if [ $ret -eq 0 ]; then
|
||||
echo "$out" | grep -q -- --update || {
|
||||
reason="partx has no '--update' flag in usage."
|
||||
found="off"
|
||||
}
|
||||
else
|
||||
reason="'partx --help' returned $ret. assuming it is old."
|
||||
found="off"
|
||||
fi
|
||||
else
|
||||
reason="no 'partx' command"
|
||||
found="off"
|
||||
fi
|
||||
|
||||
if [ -z "$found" ]; then
|
||||
if [ "$(uname)" != "Linux" ]; then
|
||||
reason="Kernel is not Linux per uname."
|
||||
found="off"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$found" ]; then
|
||||
kver=$(uname -r) || debug 1 "uname -r failed!"
|
||||
|
||||
if ! kver_cmp "${kver-0.0.0}" -ge 3.8.0; then
|
||||
reason="Kernel '$kver' < 3.8.0."
|
||||
found="off"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$found" ]; then
|
||||
_RET="true"
|
||||
return 0
|
||||
fi
|
||||
|
||||
case "$input" in
|
||||
on) error "$reason"; return 1;;
|
||||
auto)
|
||||
_RET="false";
|
||||
debug 1 "partition update disabled: $reason"
|
||||
return 0;;
|
||||
force)
|
||||
_RET="true"
|
||||
error "WARNING: ptupdate forced on even though: $reason"
|
||||
return 0;;
|
||||
esac
|
||||
error "unknown input '$input'";
|
||||
return 1;
|
||||
}
|
||||
|
||||
pt_update() {
|
||||
local dev="$1" part="$2" update="${3:-$PT_UPDATE}"
|
||||
if ! $update; then
|
||||
return 0
|
||||
fi
|
||||
# partx only works on block devices (do not run on file)
|
||||
[ -b "$dev" ] || return 0
|
||||
partx --update --nr "$part" "$dev"
|
||||
}
|
||||
|
||||
has_cmd() {
|
||||
command -v "${1}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
resize_sgdisk_gpt() {
|
||||
resize_sgdisk gpt
|
||||
}
|
||||
|
||||
resize_sgdisk_dos() {
|
||||
fail "unable to resize dos label with sgdisk"
|
||||
}
|
||||
|
||||
resize_sfdisk_gpt() {
|
||||
resize_sfdisk gpt
|
||||
}
|
||||
|
||||
resize_sfdisk_dos() {
|
||||
resize_sfdisk dos
|
||||
}
|
||||
|
||||
get_table_format() {
|
||||
local out="" disk="$1"
|
||||
if has_cmd blkid && out=$(blkid -o value -s PTTYPE "$disk") &&
|
||||
[ "$out" = "dos" -o "$out" = "gpt" ]; then
|
||||
_RET="$out"
|
||||
return
|
||||
fi
|
||||
_RET="dos"
|
||||
if [ ${SFDISK_VERSION} -lt ${SFDISK_2_26} ] &&
|
||||
out=$(sfdisk --id --force "$disk" 1 2>/dev/null); then
|
||||
if [ "$out" = "ee" ]; then
|
||||
_RET="gpt"
|
||||
else
|
||||
_RET="dos"
|
||||
fi
|
||||
return
|
||||
elif out=$(LANG=C sfdisk --list "$disk"); then
|
||||
out=$(echo "$out" | sed -e '/Disklabel type/!d' -e 's/.*: //')
|
||||
case "$out" in
|
||||
gpt|dos) _RET="$out";;
|
||||
*) error "WARN: unknown label $out";;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
get_resizer() {
|
||||
local format="$1" user=${2:-"auto"}
|
||||
|
||||
case "$user" in
|
||||
sgdisk) _RET="resize_sgdisk_$format"; return;;
|
||||
sfdisk) _RET="resize_sfdisk_$format"; return;;
|
||||
auto) :;;
|
||||
*) error "unexpected input: '$user'";;
|
||||
esac
|
||||
|
||||
if [ "$format" = "dos" ]; then
|
||||
_RET="resize_sfdisk_dos"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "${SFDISK_VERSION}" -ge ${SFDISK_V_WORKING_GPT} ]; then
|
||||
# sfdisk 2.26.2 works for resize but loses type (LP: #1474090)
|
||||
_RET="resize_sfdisk_gpt"
|
||||
elif has_cmd sgdisk; then
|
||||
_RET="resize_sgdisk_$format"
|
||||
else
|
||||
error "no tools available to resize disk with '$format'"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
pt_update="auto"
|
||||
resizer=${GROWPART_RESIZER:-"auto"}
|
||||
while [ $# -ne 0 ]; do
|
||||
cur=${1}
|
||||
next=${2}
|
||||
case "$cur" in
|
||||
-h|--help)
|
||||
Usage
|
||||
exit 0
|
||||
;;
|
||||
--fudge)
|
||||
FUDGE=${next}
|
||||
shift
|
||||
;;
|
||||
-N|--dry-run)
|
||||
DRY_RUN=1
|
||||
;;
|
||||
-u|--update|--update=*)
|
||||
if [ "${cur#--update=}" != "$cur" ]; then
|
||||
next="${cur#--update=}"
|
||||
else
|
||||
shift
|
||||
fi
|
||||
case "$next" in
|
||||
off|auto|force|on) pt_update=$next;;
|
||||
*) fail "unknown --update option: $next";;
|
||||
esac
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSITY=$(($VERBOSITY+1))
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
fail "unknown option ${cur}"
|
||||
;;
|
||||
*)
|
||||
if [ -z "${DISK}" ]; then
|
||||
DISK=${cur}
|
||||
else
|
||||
[ -z "${PART}" ] || fail "confused by arg ${cur}"
|
||||
PART=${cur}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[ -n "${DISK}" ] || bad_Usage "must supply disk and partition-number"
|
||||
[ -n "${PART}" ] || bad_Usage "must supply partition-number"
|
||||
|
||||
has_cmd "sfdisk" || fail "sfdisk not found"
|
||||
get_sfdisk_version || fail
|
||||
|
||||
[ -e "${DISK}" ] || fail "${DISK}: does not exist"
|
||||
|
||||
# If $DISK is a symlink, resolve it.
|
||||
# This avoids problems due to varying partition device name formats
|
||||
# (e.g. "1" for /dev/sda vs "-part1" for /dev/disk/by-id/name)
|
||||
if [ -L "${DISK}" ]; then
|
||||
has_cmd readlink ||
|
||||
fail "${DISK} is a symlink, but 'readlink' command not available."
|
||||
real_disk=$(readlink -f "${DISK}") || fail "unable to resolve ${DISK}"
|
||||
debug 1 "${DISK} resolved to ${real_disk}"
|
||||
DISK=${real_disk}
|
||||
fi
|
||||
|
||||
[ "${PART#*[!0-9]}" = "${PART}" ] || fail "partition-number must be a number"
|
||||
|
||||
verify_ptupdate "$pt_update" || fail
|
||||
PT_UPDATE=$_RET
|
||||
|
||||
debug 1 "update-partition set to $PT_UPDATE"
|
||||
|
||||
mktemp_d && TEMP_D="${_RET}" || fail "failed to make temp dir"
|
||||
trap cleanup 0 # EXIT - some shells may not like 'EXIT' but are ok with 0
|
||||
|
||||
# get the ID of the first partition to determine if it's MBR or GPT
|
||||
get_table_format "$DISK" || fail
|
||||
format=$_RET
|
||||
get_resizer "$format" "$resizer" ||
|
||||
fail "failed to get a resizer for id '$id'"
|
||||
resizer=$_RET
|
||||
|
||||
debug 1 "resizing $PART on $DISK using $resizer"
|
||||
"$resizer"
|
||||
|
||||
# vi: ts=4 noexpandtab
|
||||
`
|
||||
@@ -12,51 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package qemu_kvm
|
||||
package fsutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestfs/kvmpart"
|
||||
"yunion.io/x/onecloud/pkg/util/procutils"
|
||||
)
|
||||
|
||||
func (d *LocalDiskDriver) setupLVMS() {
|
||||
for _, part := range d.partitions {
|
||||
vg, err := d.findVg(part.GetPartDev())
|
||||
if err != nil {
|
||||
log.Infof("failed find vg %s", err)
|
||||
continue
|
||||
}
|
||||
if vg == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("found vg %s from %s", vg.VgName, part.GetPartDev())
|
||||
err = d.vgActive(vg.VgName)
|
||||
if err != nil {
|
||||
log.Infof("failed active vg %s: %s", vg.VgName, err)
|
||||
continue
|
||||
}
|
||||
lvs, err := d.getVgLvs(vg.VgName)
|
||||
if err != nil {
|
||||
log.Infof("failed get vg lvs %s: %s", vg.VgName, err)
|
||||
continue
|
||||
}
|
||||
log.Infof("found lvs %v from vg %s", lvs, vg.VgName)
|
||||
for _, lv := range lvs {
|
||||
lvmpart := kvmpart.NewKVMGuestDiskPartition(lv.LvPath, "", true)
|
||||
d.lvmPartitions = append(d.lvmPartitions, lvmpart)
|
||||
log.Infof("found lvm part dev %v", lvmpart.GetPartDev())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) vgActive(vgname string) error {
|
||||
func VgActive(vgname string) error {
|
||||
out, err := procutils.NewCommand("vgchange", "-ay", vgname).Output()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "vgchange -ay %s %s", vgname, out)
|
||||
@@ -64,6 +31,14 @@ func (d *LocalDiskDriver) vgActive(vgname string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) ExtendLv(lvPath string) error {
|
||||
out, err := d.Exec("lvextend", "-l", "+100%FREE", lvPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "extend lv %s failed %s", lvPath, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type LvProps struct {
|
||||
LvName string
|
||||
LvPath string
|
||||
@@ -78,9 +53,9 @@ type LvNames struct {
|
||||
} `json:"report"`
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) getVgLvs(vg string) ([]LvProps, error) {
|
||||
func (d *SFsutilDriver) GetVgLvs(vg string) ([]LvProps, error) {
|
||||
cmd := fmt.Sprintf("lvs --reportformat json -o lv_name,lv_path %s 2>/dev/null", vg)
|
||||
out, err := procutils.NewCommand("sh", "-c", cmd).Output()
|
||||
out, err := d.Exec("sh", "-c", cmd)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "find vg lvs")
|
||||
}
|
||||
@@ -116,7 +91,7 @@ type VgReports struct {
|
||||
} `json:"report"`
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) findVg(partDev string) (*VgProps, error) {
|
||||
func FindVg(partDev string) (*VgProps, error) {
|
||||
cmd := fmt.Sprintf("vgs --reportformat json -o vg_name,vg_uuid --devices %s 2>/dev/null", partDev)
|
||||
out, err := procutils.NewCommand("sh", "-c", cmd).Output()
|
||||
if err != nil {
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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 fsutils
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils/driver"
|
||||
|
||||
type SFsutilDriver struct {
|
||||
execDriver driver.IFsutilExecDriver
|
||||
}
|
||||
|
||||
func NewFsutilDriver(execDriver driver.IFsutilExecDriver) *SFsutilDriver {
|
||||
return &SFsutilDriver{execDriver}
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) Exec(name string, args ...string) ([]byte, error) {
|
||||
return d.execDriver.Exec(name, args...)
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) Run(name string, args ...string) error {
|
||||
return d.execDriver.Run(name, args...)
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) ExecInputWait(name string, args []string, input []string) (int, string, string, error) {
|
||||
return d.execDriver.ExecInputWait(name, args, input)
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// 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 fsutils
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils/driver"
|
||||
)
|
||||
|
||||
func (d *SFsutilDriver) GetResizeDevBySerial(diskId string) (string, error) {
|
||||
out, err := d.Exec("sh", "-c", "lsblk -d -o NAME,SERIAL | awk 'NR>1'")
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "ResizePartition lsblk %s", err)
|
||||
}
|
||||
lines := strings.Split(string(out), "\n")
|
||||
diskSerial := strings.ReplaceAll(diskId, "-", "")
|
||||
resizeDev := ""
|
||||
for i := range lines {
|
||||
segs := strings.Fields(lines[i])
|
||||
if len(segs) == 0 {
|
||||
continue
|
||||
}
|
||||
log.Errorf("segs %v", segs)
|
||||
if len(segs) == 1 {
|
||||
// fetch vpd 80 serial id
|
||||
ret, err := d.Exec("sg_inq", "-u", "-p", "0x80", path.Join("/dev/", segs[0]))
|
||||
if err != nil {
|
||||
log.Infof("failed exec sg_inq: %s %s", ret, err)
|
||||
continue
|
||||
}
|
||||
serialStr := strings.TrimSpace(string(ret))
|
||||
serialSegs := strings.Split(serialStr, "=")
|
||||
log.Errorf("serial segs %v", serialSegs)
|
||||
if len(serialSegs) == 2 && serialSegs[1] == diskSerial {
|
||||
resizeDev = path.Join("/dev/", segs[0])
|
||||
break
|
||||
}
|
||||
}
|
||||
devName, serial := segs[0], segs[1]
|
||||
log.Infof("lsblk segs: %s %s |", devName, serial)
|
||||
if strings.HasPrefix(diskSerial, serial) {
|
||||
resizeDev = path.Join("/dev/", devName)
|
||||
break
|
||||
}
|
||||
}
|
||||
return resizeDev, nil
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) IsLvmPvDevice(device string) bool {
|
||||
return d.Run("pvs", device) == nil
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) Pvresize(device string) error {
|
||||
out, err := d.Exec("partprobe")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed resize pv partprobe %s", out)
|
||||
}
|
||||
out, err = d.Exec("pvscan")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed resize pv pvscan %s", out)
|
||||
}
|
||||
out, err = d.Exec("pvresize", device)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed resize pv %s", out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) GetVgOfPvDevice(device string) string {
|
||||
out, err := d.Exec("pvs", "--noheadings", "-o", "vg_name", device)
|
||||
if err != nil {
|
||||
log.Errorf("get vg from pv %s device failed: %s %s", device, out, err)
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
func GetFsFormat(diskPath string) string {
|
||||
fsutilDriver := NewFsutilDriver(driver.NewProcDriver())
|
||||
return fsutilDriver.GetFsFormat(diskPath)
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) GetFsFormat(diskPath string) string {
|
||||
ret, err := d.Exec("blkid", "-o", "value", "-s", "TYPE", diskPath)
|
||||
if err != nil {
|
||||
log.Errorf("failed exec blkid of dev %s: %s, %s", diskPath, err, ret)
|
||||
return ""
|
||||
}
|
||||
var res string
|
||||
for _, line := range strings.Split(string(ret), "\n") {
|
||||
res += line
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (d *SFsutilDriver) GetDevUuid(dev string) (map[string]string, error) {
|
||||
lines, err := d.Exec("blkid", dev)
|
||||
if err != nil {
|
||||
log.Errorf("GetDevUuid %s error: %v", dev, err)
|
||||
return map[string]string{}, errors.Wrapf(err, "blkid")
|
||||
}
|
||||
for _, l := range strings.Split(string(lines), "\n") {
|
||||
if strings.HasPrefix(l, dev) {
|
||||
var ret = map[string]string{}
|
||||
for _, part := range strings.Split(l, " ") {
|
||||
data := strings.Split(part, "=")
|
||||
if len(data) == 2 && strings.HasSuffix(data[0], "UUID") {
|
||||
if data[1][0] == '"' || data[1][0] == '\'' {
|
||||
ret[data[0]] = data[1][1 : len(data[1])-1]
|
||||
} else {
|
||||
ret[data[0]] = data[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
return map[string]string{}, nil
|
||||
}
|
||||
@@ -23,13 +23,14 @@ import (
|
||||
|
||||
type IDisk interface {
|
||||
Connect(desc *apis.GuestDesc) error
|
||||
ConnectWithDiskId(desc *apis.GuestDesc, diskId string) error
|
||||
Disconnect() error
|
||||
MountRootfs() (fsdriver.IRootFsDriver, error)
|
||||
UmountRootfs(driver fsdriver.IRootFsDriver) error
|
||||
Cleanup()
|
||||
|
||||
DeployGuestfs(req *apis.DeployParams) (res *apis.DeployGuestFsResponse, err error)
|
||||
ResizeFs() (res *apis.Empty, err error)
|
||||
ResizeFs(req *apis.ResizeFsParams) (res *apis.Empty, err error)
|
||||
FormatFs(req *apis.FormatFsParams) (*apis.Empty, error)
|
||||
SaveToGlance(req *apis.SaveToGlanceParams) (*apis.SaveToGlanceResponse, error)
|
||||
ProbeImageInfo(req *apis.ProbeImageInfoPramas) (*apis.ImageInfo, error)
|
||||
|
||||
@@ -103,7 +103,11 @@ func (d *SKVMGuestDisk) IsLVMPartition() bool {
|
||||
}
|
||||
|
||||
func (d *SKVMGuestDisk) Connect(guestDesc *apis.GuestDesc) error {
|
||||
return d.deployer.Connect(guestDesc)
|
||||
return d.deployer.Connect(guestDesc, "")
|
||||
}
|
||||
|
||||
func (d *SKVMGuestDisk) ConnectWithDiskId(guestDesc *apis.GuestDesc, diskId string) error {
|
||||
return d.deployer.Connect(guestDesc, diskId)
|
||||
}
|
||||
|
||||
func (d *SKVMGuestDisk) Disconnect() error {
|
||||
@@ -144,8 +148,9 @@ func (d *SKVMGuestDisk) DeployGuestfs(req *apis.DeployParams) (res *apis.DeployG
|
||||
return d.deployer.DeployGuestfs(req)
|
||||
}
|
||||
|
||||
func (d *SKVMGuestDisk) ResizeFs() (*apis.Empty, error) {
|
||||
return d.deployer.ResizeFs()
|
||||
func (d *SKVMGuestDisk) ResizeFs(req *apis.ResizeFsParams) (*apis.Empty, error) {
|
||||
log.Errorf("start resizefs")
|
||||
return d.deployer.ResizeFs(req)
|
||||
}
|
||||
|
||||
func (d *SKVMGuestDisk) FormatFs(req *apis.FormatFsParams) (*apis.Empty, error) {
|
||||
|
||||
@@ -74,7 +74,7 @@ func NewLibguestfsDriver(imageInfo qemuimg.SImageInfo) *SLibguestfsDriver {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *SLibguestfsDriver) Connect(*apis.GuestDesc) error {
|
||||
func (d *SLibguestfsDriver) Connect(*apis.GuestDesc, string) error {
|
||||
fish, err := guestfsManager.AcquireFish()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -209,7 +209,7 @@ func (d *SLibguestfsDriver) Zerofree() {
|
||||
len(d.parts), time.Now().Sub(startTime).Seconds())
|
||||
}
|
||||
|
||||
func (d *SLibguestfsDriver) ResizePartition() error {
|
||||
func (d *SLibguestfsDriver) ResizePartition(string, string) error {
|
||||
if d.IsLVMPartition() {
|
||||
// do not try to resize LVM partition
|
||||
return nil
|
||||
@@ -271,8 +271,8 @@ func (d *SLibguestfsDriver) DeployGuestfs(req *apis.DeployParams) (res *apis.Dep
|
||||
return fsutils.DeployGuestfs(d, req)
|
||||
}
|
||||
|
||||
func (d *SLibguestfsDriver) ResizeFs() (*apis.Empty, error) {
|
||||
return fsutils.ResizeFs(d)
|
||||
func (d *SLibguestfsDriver) ResizeFs(*apis.ResizeFsParams) (*apis.Empty, error) {
|
||||
return fsutils.ResizeFs(d, "")
|
||||
}
|
||||
|
||||
func (d *SLibguestfsDriver) SaveToGlance(req *apis.SaveToGlanceParams) (*apis.SaveToGlanceResponse, error) {
|
||||
|
||||
@@ -59,7 +59,7 @@ func init() {
|
||||
lock = new(sync.Mutex)
|
||||
}
|
||||
|
||||
func (d *NBDDriver) Connect(*apis.GuestDesc) error {
|
||||
func (d *NBDDriver) Connect(*apis.GuestDesc, string) error {
|
||||
d.nbdDev = GetNBDManager().AcquireNbddev()
|
||||
if len(d.nbdDev) == 0 {
|
||||
return errors.Errorf("Cannot get nbd device")
|
||||
@@ -243,7 +243,7 @@ func (d *NBDDriver) FormatPartition(fs, uuid string) error {
|
||||
return fsutils.FormatPartition(fmt.Sprintf("%sp1", d.nbdDev), fs, uuid)
|
||||
}
|
||||
|
||||
func (d *NBDDriver) ResizePartition() error {
|
||||
func (d *NBDDriver) ResizePartition(string, string) error {
|
||||
if d.IsLVMPartition() {
|
||||
// do not resize LVM partition
|
||||
return nil
|
||||
@@ -282,8 +282,8 @@ func (d *NBDDriver) DeployGuestfs(req *apis.DeployParams) (res *apis.DeployGuest
|
||||
return fsutils.DeployGuestfs(d, req)
|
||||
}
|
||||
|
||||
func (d *NBDDriver) ResizeFs() (*apis.Empty, error) {
|
||||
return fsutils.ResizeFs(d)
|
||||
func (d *NBDDriver) ResizeFs(*apis.ResizeFsParams) (*apis.Empty, error) {
|
||||
return fsutils.ResizeFs(d, "")
|
||||
}
|
||||
|
||||
func (d *NBDDriver) SaveToGlance(req *apis.SaveToGlanceParams) (*apis.SaveToGlanceResponse, error) {
|
||||
|
||||
@@ -271,6 +271,7 @@ type QemuKvmDriver struct {
|
||||
|
||||
partitions []fsdriver.IDiskPartition
|
||||
lvmPartitions []fsdriver.IDiskPartition
|
||||
diskId string
|
||||
}
|
||||
|
||||
func NewQemuKvmDriver(imageInfo qemuimg.SImageInfo) *QemuKvmDriver {
|
||||
@@ -279,10 +280,10 @@ func NewQemuKvmDriver(imageInfo qemuimg.SImageInfo) *QemuKvmDriver {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *QemuKvmDriver) Connect(guestDesc *apis.GuestDesc) error {
|
||||
func (d *QemuKvmDriver) Connect(desc *apis.GuestDesc, diskId string) error {
|
||||
manager.Acquire()
|
||||
d.qemuArchDriver = NewCpuArchDriver(manager.cpuArch)
|
||||
err := d.connect(guestDesc)
|
||||
err := d.connect(desc, diskId)
|
||||
if err != nil {
|
||||
d.qemuArchDriver.CleanGuest()
|
||||
return err
|
||||
@@ -291,11 +292,12 @@ func (d *QemuKvmDriver) Connect(guestDesc *apis.GuestDesc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *QemuKvmDriver) connect(guestDesc *apis.GuestDesc) error {
|
||||
func (d *QemuKvmDriver) connect(guestDesc *apis.GuestDesc, diskId string) error {
|
||||
var (
|
||||
ncpu = 2
|
||||
memSizeMB = manager.getMemSizeMb()
|
||||
disks = make([]string, 0)
|
||||
diskIds = make([]string, 0)
|
||||
)
|
||||
|
||||
var sshport = manager.GetSshFreePort()
|
||||
@@ -304,16 +306,17 @@ func (d *QemuKvmDriver) connect(guestDesc *apis.GuestDesc) error {
|
||||
if guestDesc != nil && len(guestDesc.Disks) > 0 {
|
||||
for i := range guestDesc.Disks {
|
||||
disks = append(disks, guestDesc.Disks[i].Path)
|
||||
diskIds = append(diskIds, guestDesc.Disks[i].DiskId)
|
||||
}
|
||||
} else {
|
||||
if diskId == "" {
|
||||
diskId = "single-disk"
|
||||
}
|
||||
disks = append(disks, d.imageInfo.Path)
|
||||
diskIds = append(diskIds, diskId)
|
||||
}
|
||||
|
||||
err := d.qemuArchDriver.StartGuest(
|
||||
sshport, ncpu, memSizeMB,
|
||||
manager.hugepage, manager.hugepageSizeKB,
|
||||
d.imageInfo, disks,
|
||||
)
|
||||
err := d.qemuArchDriver.StartGuest(sshport, ncpu, memSizeMB, manager.hugepage, manager.hugepageSizeKB, d.imageInfo, disks, diskIds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -361,7 +364,7 @@ func (d *QemuKvmDriver) IsLVMPartition() bool {
|
||||
|
||||
func (d *QemuKvmDriver) Zerofree() {}
|
||||
|
||||
func (d *QemuKvmDriver) ResizePartition() error {
|
||||
func (d *QemuKvmDriver) ResizePartition(string, string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -447,13 +450,14 @@ func (d *QemuKvmDriver) DeployGuestfs(req *apis.DeployParams) (*apis.DeployGuest
|
||||
return res, retErr
|
||||
}
|
||||
|
||||
func (d *QemuKvmDriver) ResizeFs() (*apis.Empty, error) {
|
||||
func (d *QemuKvmDriver) ResizeFs(req *apis.ResizeFsParams) (*apis.Empty, error) {
|
||||
defer func() {
|
||||
logStr, _ := d.sshRun("test -f /log && cat /log")
|
||||
log.Infof("ResizeFs log: %v", strings.Join(logStr, "\n"))
|
||||
}()
|
||||
|
||||
cmd := fmt.Sprintf("%s --deploy-action resize_fs", DEPLOYER_BIN)
|
||||
params, _ := json.Marshal(req)
|
||||
cmd := fmt.Sprintf("%s --deploy-action resize_fs --deploy-params '%s'", DEPLOYER_BIN, params)
|
||||
out, err := d.sshRun(cmd)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "run resize_fs failed %s", out)
|
||||
@@ -613,7 +617,7 @@ func (d *QemuBaseDriver) CleanGuest() {
|
||||
}
|
||||
|
||||
func (d *QemuBaseDriver) startCmds(
|
||||
sshPort, ncpu, memSizeMB int, imageInfo qemuimg.SImageInfo, disksPath []string,
|
||||
sshPort, ncpu, memSizeMB int, imageInfo qemuimg.SImageInfo, disksPath, diskIds []string,
|
||||
machineOpts, cdromDeviceOpts, fwOpts, socketPath, initrdPath, kernelPath string,
|
||||
) string {
|
||||
cmd := manager.qemuCmd
|
||||
@@ -666,7 +670,7 @@ func (d *QemuBaseDriver) startCmds(
|
||||
}
|
||||
|
||||
cmd += diskDrive
|
||||
cmd += __("-device scsi-hd,drive=drive_%d,bus=scsi.0,id=drive_%d", i, i)
|
||||
cmd += __("-device scsi-hd,drive=drive_%d,bus=scsi.0,id=drive_%d,serial=%s", i, i, strings.ReplaceAll(diskIds[i], "-", ""))
|
||||
}
|
||||
cmd += __("-drive id=cd0,if=none,media=cdrom,file=%s", DEPLOY_ISO)
|
||||
cmd += cdromDeviceOpts
|
||||
@@ -678,7 +682,7 @@ type QemuX86Driver struct {
|
||||
QemuBaseDriver
|
||||
}
|
||||
|
||||
func (d *QemuX86Driver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath []string) error {
|
||||
func (d *QemuX86Driver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath, diskIds []string) error {
|
||||
uuid := stringutils.UUID4()
|
||||
socketPath := fmt.Sprintf("/opt/cloud/host-deployer/hmp_%s.socket", uuid)
|
||||
d.pidPath = fmt.Sprintf("/opt/cloud/host-deployer/%s.pid", uuid)
|
||||
@@ -691,6 +695,7 @@ func (d *QemuX86Driver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool,
|
||||
memSizeMB,
|
||||
imageInfo,
|
||||
disksPath,
|
||||
diskIds,
|
||||
machineOpts,
|
||||
cdromDeviceOpts,
|
||||
"",
|
||||
@@ -733,7 +738,7 @@ type QemuARMDriver struct {
|
||||
QemuBaseDriver
|
||||
}
|
||||
|
||||
func (d *QemuARMDriver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath []string) error {
|
||||
func (d *QemuARMDriver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath, diskIds []string) error {
|
||||
uuid := stringutils.UUID4()
|
||||
socketPath := fmt.Sprintf("/opt/cloud/host-deployer/hmp_%s.socket", uuid)
|
||||
d.pidPath = fmt.Sprintf("/opt/cloud/host-deployer/%s.pid", uuid)
|
||||
@@ -753,6 +758,7 @@ func (d *QemuARMDriver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool,
|
||||
memSizeMB,
|
||||
imageInfo,
|
||||
disksPath,
|
||||
diskIds,
|
||||
machineOpts,
|
||||
cdromDeviceOpts,
|
||||
fwOpts,
|
||||
@@ -792,7 +798,7 @@ func (d *QemuARMDriver) StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool,
|
||||
}
|
||||
|
||||
type IQemuArchDriver interface {
|
||||
StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath []string) error
|
||||
StartGuest(sshPort, ncpu, memSizeMB int, hugePage bool, pageSizeKB int, imageInfo qemuimg.SImageInfo, disksPath, diskIds []string) error
|
||||
CleanGuest()
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils"
|
||||
"yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils/driver"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestfs/kvmpart"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
|
||||
@@ -42,7 +43,7 @@ func NewLocalDiskDriver() *LocalDiskDriver {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) Connect(desc *apis.GuestDesc) error {
|
||||
func (d *LocalDiskDriver) Connect(desc *apis.GuestDesc, diskId string) error {
|
||||
out, err := procutils.NewCommand("sh", "-c", "cat /proc/partitions | grep -v name | awk '{print $4}'").Output()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cat proc partitions")
|
||||
@@ -88,12 +89,13 @@ func (d *LocalDiskDriver) Zerofree() {
|
||||
log.Infof("Zerofree %d partitions takes %f seconds", len(d.partitions), time.Now().Sub(startTime).Seconds())
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) ResizePartition() error {
|
||||
if d.IsLVMPartition() {
|
||||
// do not resize LVM partition
|
||||
return nil
|
||||
func (d *LocalDiskDriver) ResizePartition(diskId string, rootPartDev string) error {
|
||||
fsutilDriver := fsutils.NewFsutilDriver(driver.NewProcDriver())
|
||||
log.Infof("ResizePartition disk id %s", diskId)
|
||||
if len(diskId) > 0 {
|
||||
return fsutilDriver.ResizeDiskWithDiskId(diskId, rootPartDev, false)
|
||||
}
|
||||
return fsutils.ResizeDiskFs("/dev/sda", 0)
|
||||
return fsutilDriver.ResizeDiskFs("/dev/sda", 0)
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) FormatPartition(fs, uuid string) error {
|
||||
@@ -123,8 +125,12 @@ func (d *LocalDiskDriver) DeployGuestfs(req *apis.DeployParams) (res *apis.Deplo
|
||||
return fsutils.DeployGuestfs(d, req)
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) ResizeFs() (*apis.Empty, error) {
|
||||
return fsutils.ResizeFs(d)
|
||||
func (d *LocalDiskDriver) ResizeFs(req *apis.ResizeFsParams) (*apis.Empty, error) {
|
||||
var diskId string
|
||||
if req.DiskInfo != nil {
|
||||
diskId = req.DiskInfo.DiskId
|
||||
}
|
||||
return fsutils.ResizeFs(d, diskId)
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) SaveToGlance(req *apis.SaveToGlanceParams) (*apis.SaveToGlanceResponse, error) {
|
||||
@@ -138,3 +144,35 @@ func (d *LocalDiskDriver) FormatFs(req *apis.FormatFsParams) (*apis.Empty, error
|
||||
func (d *LocalDiskDriver) ProbeImageInfo(req *apis.ProbeImageInfoPramas) (*apis.ImageInfo, error) {
|
||||
return fsutils.ProbeImageInfo(d)
|
||||
}
|
||||
|
||||
func (d *LocalDiskDriver) setupLVMS() {
|
||||
fsutilDriver := fsutils.NewFsutilDriver(driver.NewProcDriver())
|
||||
for _, part := range d.partitions {
|
||||
vg, err := fsutils.FindVg(part.GetPartDev())
|
||||
if err != nil {
|
||||
log.Infof("failed find vg %s", err)
|
||||
continue
|
||||
}
|
||||
if vg == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("found vg %s from %s", vg.VgName, part.GetPartDev())
|
||||
err = fsutils.VgActive(vg.VgName)
|
||||
if err != nil {
|
||||
log.Infof("failed active vg %s: %s", vg.VgName, err)
|
||||
continue
|
||||
}
|
||||
lvs, err := fsutilDriver.GetVgLvs(vg.VgName)
|
||||
if err != nil {
|
||||
log.Infof("failed get vg lvs %s: %s", vg.VgName, err)
|
||||
continue
|
||||
}
|
||||
log.Infof("found lvs %v from vg %s", lvs, vg.VgName)
|
||||
for _, lv := range lvs {
|
||||
lvmpart := kvmpart.NewKVMGuestDiskPartition(lv.LvPath, "", true)
|
||||
d.lvmPartitions = append(d.lvmPartitions, lvmpart)
|
||||
log.Infof("found lvm part dev %v", lvmpart.GetPartDev())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,10 @@ func (vd *VDDKDisk) Connect(*apis.GuestDesc) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vd *VDDKDisk) ConnectWithDiskId(desc *apis.GuestDesc, diskId string) error {
|
||||
return vd.Connect(desc)
|
||||
}
|
||||
|
||||
func (vd *VDDKDisk) Disconnect() error {
|
||||
if vd.kvmDisk != nil {
|
||||
if err := vd.kvmDisk.Disconnect(); err != nil {
|
||||
@@ -451,8 +455,8 @@ func (vd *VDDKDisk) DeployGuestfs(req *apis.DeployParams) (res *apis.DeployGuest
|
||||
return vd.kvmDisk.DeployGuestfs(req)
|
||||
}
|
||||
|
||||
func (d *VDDKDisk) ResizeFs() (*apis.Empty, error) {
|
||||
return d.kvmDisk.ResizeFs()
|
||||
func (d *VDDKDisk) ResizeFs(req *apis.ResizeFsParams) (*apis.Empty, error) {
|
||||
return d.kvmDisk.ResizeFs(req)
|
||||
}
|
||||
|
||||
func (d *VDDKDisk) FormatFs(req *apis.FormatFsParams) (*apis.Empty, error) {
|
||||
|
||||
@@ -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 fsdriver
|
||||
|
||||
import (
|
||||
|
||||
@@ -95,7 +95,7 @@ func (p *SKVMGuestDiskPartition) IsReadonly() bool {
|
||||
}
|
||||
|
||||
func (p *SKVMGuestDiskPartition) getFsFormat() string {
|
||||
return fileutils2.GetFsFormat(p.partDev)
|
||||
return fsutils.GetFsFormat(p.partDev)
|
||||
}
|
||||
|
||||
func (p *SKVMGuestDiskPartition) MountPartReadOnly() bool {
|
||||
|
||||
@@ -2498,6 +2498,12 @@ func (task *SGuestOnlineResizeDiskTask) OnGetBlocksSucc(blocks []monitor.QemuBlo
|
||||
|
||||
func (task *SGuestOnlineResizeDiskTask) OnResizeSucc(err string) {
|
||||
if len(err) == 0 {
|
||||
if e := task.guestAgent.GuestPing(1); e == nil {
|
||||
if e := task.guestAgent.QgaResizeDisk(task.disk.GetId()); e != nil {
|
||||
log.Errorf("failed qga resize disk %s: %s", task.disk.GetId(), e)
|
||||
}
|
||||
}
|
||||
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewInt(task.sizeMB), "disk_size")
|
||||
hostutils.TaskComplete(task.ctx, params)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.21.5
|
||||
// protoc v3.21.2
|
||||
// source: deploy.proto
|
||||
|
||||
// protoc --version=libprotoc 3.11.3
|
||||
@@ -1119,6 +1119,7 @@ type DiskInfo struct {
|
||||
EncryptPassword string `protobuf:"bytes,2,opt,name=encrypt_password,json=encryptPassword,proto3" json:"encrypt_password,omitempty"`
|
||||
EncryptFormat string `protobuf:"bytes,3,opt,name=encrypt_format,json=encryptFormat,proto3" json:"encrypt_format,omitempty"`
|
||||
EncryptAlg string `protobuf:"bytes,4,opt,name=encrypt_alg,json=encryptAlg,proto3" json:"encrypt_alg,omitempty"`
|
||||
DiskId string `protobuf:"bytes,5,opt,name=disk_id,json=diskId,proto3" json:"disk_id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DiskInfo) Reset() {
|
||||
@@ -1181,6 +1182,13 @@ func (x *DiskInfo) GetEncryptAlg() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *DiskInfo) GetDiskId() string {
|
||||
if x != nil {
|
||||
return x.DiskId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DeployParams struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1260,6 +1268,7 @@ type ResizeFsParams struct {
|
||||
DiskInfo *DiskInfo `protobuf:"bytes,1,opt,name=disk_info,json=diskInfo,proto3" json:"disk_info,omitempty"`
|
||||
Hypervisor string `protobuf:"bytes,2,opt,name=hypervisor,proto3" json:"hypervisor,omitempty"`
|
||||
VddkInfo *VDDKConInfo `protobuf:"bytes,3,opt,name=vddk_info,json=vddkInfo,proto3" json:"vddk_info,omitempty"`
|
||||
GuestDesc *GuestDesc `protobuf:"bytes,4,opt,name=guest_desc,json=guestDesc,proto3" json:"guest_desc,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ResizeFsParams) Reset() {
|
||||
@@ -1315,6 +1324,13 @@ func (x *ResizeFsParams) GetVddkInfo() *VDDKConInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ResizeFsParams) GetGuestDesc() *GuestDesc {
|
||||
if x != nil {
|
||||
return x.GuestDesc
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FormatFsParams struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -2015,7 +2031,7 @@ var file_deploy_proto_rawDesc = []byte{
|
||||
0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x65, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x66, 0x5f,
|
||||
0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10,
|
||||
0x74, 0x65, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x66, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64,
|
||||
0x22, 0x91, 0x01, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a,
|
||||
0x22, 0xaa, 0x01, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
|
||||
0x68, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x5f, 0x70, 0x61, 0x73,
|
||||
0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6e, 0x63,
|
||||
@@ -2024,126 +2040,131 @@ var file_deploy_proto_rawDesc = []byte{
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x46, 0x6f, 0x72,
|
||||
0x6d, 0x61, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x5f, 0x61,
|
||||
0x6c, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
|
||||
0x74, 0x41, 0x6c, 0x67, 0x22, 0xce, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50,
|
||||
0x74, 0x41, 0x6c, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x64, 0x22, 0xce, 0x01,
|
||||
0x0a, 0x0c, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2b,
|
||||
0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x0a, 0x67,
|
||||
0x75, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x0f, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x47, 0x75, 0x65, 0x73, 0x74, 0x44, 0x65, 0x73, 0x63,
|
||||
0x52, 0x09, 0x67, 0x75, 0x65, 0x73, 0x74, 0x44, 0x65, 0x73, 0x63, 0x12, 0x31, 0x0a, 0x0b, 0x64,
|
||||
0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e,
|
||||
0x0a, 0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f, 0x6e,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64, 0x64, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xbd,
|
||||
0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x46, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d,
|
||||
0x73, 0x12, 0x2b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x68, 0x79, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x68, 0x79, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x12, 0x2e,
|
||||
0x0a, 0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f, 0x6e,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64, 0x64, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e,
|
||||
0x0a, 0x0a, 0x67, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x47, 0x75, 0x65, 0x73, 0x74, 0x44,
|
||||
0x65, 0x73, 0x63, 0x52, 0x09, 0x67, 0x75, 0x65, 0x73, 0x74, 0x44, 0x65, 0x73, 0x63, 0x22, 0x6e,
|
||||
0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
|
||||
0x12, 0x2b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a,
|
||||
0x09, 0x66, 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x08, 0x66, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75,
|
||||
0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x6f,
|
||||
0x0a, 0x0b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x64, 0x69, 0x73, 0x74, 0x72, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64,
|
||||
0x69, 0x73, 0x74, 0x72, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61,
|
||||
0x72, 0x63, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22,
|
||||
0x5d, 0x0a, 0x12, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x50,
|
||||
0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e,
|
||||
0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
|
||||
0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x0a, 0x67, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x47, 0x75,
|
||||
0x65, 0x73, 0x74, 0x44, 0x65, 0x73, 0x63, 0x52, 0x09, 0x67, 0x75, 0x65, 0x73, 0x74, 0x44, 0x65,
|
||||
0x73, 0x63, 0x12, 0x31, 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x5f, 0x69, 0x6e, 0x66,
|
||||
0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44,
|
||||
0x65, 0x70, 0x6c, 0x6f, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f,
|
||||
0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69, 0x6e,
|
||||
0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
|
||||
0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64, 0x64,
|
||||
0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x46, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b,
|
||||
0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x64, 0x69, 0x73,
|
||||
0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x79, 0x70, 0x65, 0x72, 0x76, 0x69,
|
||||
0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x68, 0x79, 0x70, 0x65, 0x72,
|
||||
0x76, 0x69, 0x73, 0x6f, 0x72, 0x12, 0x2e, 0x0a, 0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69, 0x6e,
|
||||
0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
|
||||
0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64, 0x64,
|
||||
0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x6e, 0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46,
|
||||
0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f,
|
||||
0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x61,
|
||||
0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x6f, 0x0a, 0x0b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x73, 0x74, 0x72, 0x6f, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x73, 0x74, 0x72, 0x6f, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x63, 0x68, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61,
|
||||
0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61,
|
||||
0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, 0x5d, 0x0a, 0x12, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f,
|
||||
0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x09,
|
||||
0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52,
|
||||
0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d,
|
||||
0x70, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d,
|
||||
0x70, 0x72, 0x65, 0x73, 0x73, 0x22, 0x65, 0x0a, 0x14, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47,
|
||||
0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a,
|
||||
0x07, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x6f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x34, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
|
||||
0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x73, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52,
|
||||
0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x43, 0x0a, 0x14,
|
||||
0x50, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x50, 0x72,
|
||||
0x61, 0x6d, 0x61, 0x73, 0x12, 0x2b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e, 0x66,
|
||||
0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44,
|
||||
0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x22, 0xb2, 0x02, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12,
|
||||
0x2a, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x6f,
|
||||
0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x73,
|
||||
0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x75, 0x65, 0x66, 0x69, 0x5f,
|
||||
0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69,
|
||||
0x73, 0x55, 0x65, 0x66, 0x69, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10,
|
||||
0x69, 0x73, 0x5f, 0x6c, 0x76, 0x6d, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x4c, 0x76, 0x6d, 0x50, 0x61, 0x72,
|
||||
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61,
|
||||
0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52,
|
||||
0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x68, 0x79, 0x73, 0x69,
|
||||
0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63,
|
||||
0x61, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12,
|
||||
0x35, 0x0a, 0x17, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f,
|
||||
0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x14, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x43, 0x6c, 0x6f,
|
||||
0x75, 0x64, 0x49, 0x6e, 0x69, 0x74, 0x22, 0x2b, 0x0a, 0x0c, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69,
|
||||
0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x70,
|
||||
0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x50,
|
||||
0x61, 0x74, 0x68, 0x22, 0x7d, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73,
|
||||
0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2e, 0x0a,
|
||||
0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f, 0x6e, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64, 0x64, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a,
|
||||
0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69,
|
||||
0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x22, 0x43, 0x0a, 0x17, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43,
|
||||
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a,
|
||||
0x05, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x52, 0x05, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x32, 0xc6, 0x03, 0x0a, 0x0b, 0x44, 0x65, 0x70, 0x6c,
|
||||
0x6f, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6c, 0x6f,
|
||||
0x79, 0x47, 0x75, 0x65, 0x73, 0x74, 0x46, 0x73, 0x12, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
|
||||
0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1b, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x73, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x47, 0x75, 0x65, 0x73, 0x74, 0x46,
|
||||
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x52, 0x65, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x46, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x52, 0x65, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x46, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x08, 0x46, 0x6f, 0x72, 0x6d,
|
||||
0x61, 0x74, 0x46, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x46, 0x6f, 0x72, 0x6d,
|
||||
0x61, 0x74, 0x46, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0c, 0x53, 0x61, 0x76, 0x65, 0x54,
|
||||
0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x53,
|
||||
0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d,
|
||||
0x73, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47,
|
||||
0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a,
|
||||
0x0e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12,
|
||||
0x1a, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6d, 0x61, 0x67,
|
||||
0x65, 0x49, 0x6e, 0x66, 0x6f, 0x50, 0x72, 0x61, 0x6d, 0x61, 0x73, 0x1a, 0x0f, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4f, 0x0a, 0x10,
|
||||
0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x22, 0x65,
|
||||
0x0a, 0x14, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x66,
|
||||
0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12,
|
||||
0x34, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x52, 0x65, 0x6c,
|
||||
0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
|
||||
0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x43, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6d,
|
||||
0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x50, 0x72, 0x61, 0x6d, 0x61, 0x73, 0x12, 0x2b, 0x0a,
|
||||
0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xb2, 0x02, 0x0a, 0x09, 0x49,
|
||||
0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2a, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x69,
|
||||
0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73,
|
||||
0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x73,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a,
|
||||
0x0f, 0x69, 0x73, 0x5f, 0x75, 0x65, 0x66, 0x69, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x55, 0x65, 0x66, 0x69, 0x53, 0x75,
|
||||
0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x73, 0x5f, 0x6c, 0x76, 0x6d, 0x5f,
|
||||
0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x0e, 0x69, 0x73, 0x4c, 0x76, 0x6d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79,
|
||||
0x12, 0x36, 0x0a, 0x17, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x72,
|
||||
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x15, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x35, 0x0a, 0x17, 0x69, 0x73, 0x5f, 0x69,
|
||||
0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x69,
|
||||
0x6e, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x69, 0x73, 0x49, 0x6e, 0x73,
|
||||
0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x49, 0x6e, 0x69, 0x74, 0x22,
|
||||
0x2b, 0x0a, 0x0c, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12,
|
||||
0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x22, 0x7d, 0x0a, 0x16,
|
||||
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73,
|
||||
0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45,
|
||||
0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1d,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43,
|
||||
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a,
|
||||
0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44,
|
||||
0x69, 0x73, 0x6b, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69,
|
||||
0x44, 0x69, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x42, 0x34, 0x5a, 0x32, 0x79, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f,
|
||||
0x6f, 0x6e, 0x65, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x68, 0x6f, 0x73,
|
||||
0x74, 0x6d, 0x61, 0x6e, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65,
|
||||
0x72, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x76, 0x64, 0x64, 0x6b, 0x5f, 0x69,
|
||||
0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x73,
|
||||
0x2e, 0x56, 0x44, 0x44, 0x4b, 0x43, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x64,
|
||||
0x64, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52,
|
||||
0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x43, 0x0a, 0x17, 0x45,
|
||||
0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, 0x05, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78,
|
||||
0x69, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x64, 0x69, 0x73, 0x6b, 0x73,
|
||||
0x32, 0xc6, 0x03, 0x0a, 0x0b, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74,
|
||||
0x12, 0x40, 0x0a, 0x0d, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x47, 0x75, 0x65, 0x73, 0x74, 0x46,
|
||||
0x73, 0x12, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x50,
|
||||
0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x44, 0x65, 0x70,
|
||||
0x6c, 0x6f, 0x79, 0x47, 0x75, 0x65, 0x73, 0x74, 0x46, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x46, 0x73, 0x12, 0x14,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x46, 0x73, 0x50, 0x61,
|
||||
0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x12, 0x2d, 0x0a, 0x08, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46, 0x73, 0x12, 0x14, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x73, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x46, 0x73, 0x50, 0x61, 0x72,
|
||||
0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x12, 0x44, 0x0a, 0x0c, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c,
|
||||
0x61, 0x6e, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x73, 0x2e, 0x53, 0x61, 0x76, 0x65, 0x54, 0x6f, 0x47, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x49,
|
||||
0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e,
|
||||
0x50, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x50, 0x72,
|
||||
0x61, 0x6d, 0x61, 0x73, 0x1a, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x49, 0x6d, 0x61, 0x67,
|
||||
0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4f, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
|
||||
0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x73,
|
||||
0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b,
|
||||
0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x45,
|
||||
0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e,
|
||||
0x6e, 0x65, 0x63, 0x74, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x12, 0x1d, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x73, 0x2e, 0x45, 0x73, 0x78, 0x69, 0x44, 0x69, 0x73, 0x6b, 0x73, 0x43, 0x6f,
|
||||
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0b, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x34, 0x5a, 0x32, 0x79, 0x75, 0x6e,
|
||||
0x69, 0x6f, 0x6e, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f, 0x6f, 0x6e, 0x65, 0x63, 0x6c, 0x6f, 0x75,
|
||||
0x64, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x2f, 0x68, 0x6f,
|
||||
0x73, 0x74, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -2196,33 +2217,34 @@ var file_deploy_proto_depIdxs = []int32{
|
||||
3, // 9: apis.DeployParams.vddk_info:type_name -> apis.VDDKConInfo
|
||||
10, // 10: apis.ResizeFsParams.disk_info:type_name -> apis.DiskInfo
|
||||
3, // 11: apis.ResizeFsParams.vddk_info:type_name -> apis.VDDKConInfo
|
||||
10, // 12: apis.FormatFsParams.disk_info:type_name -> apis.DiskInfo
|
||||
10, // 13: apis.SaveToGlanceParams.disk_info:type_name -> apis.DiskInfo
|
||||
14, // 14: apis.SaveToGlanceResponse.release_info:type_name -> apis.ReleaseInfo
|
||||
10, // 15: apis.ProbeImageInfoPramas.disk_info:type_name -> apis.DiskInfo
|
||||
14, // 16: apis.ImageInfo.os_info:type_name -> apis.ReleaseInfo
|
||||
3, // 17: apis.ConnectEsxiDisksParams.vddk_info:type_name -> apis.VDDKConInfo
|
||||
19, // 18: apis.ConnectEsxiDisksParams.access_info:type_name -> apis.EsxiDiskInfo
|
||||
19, // 19: apis.EsxiDisksConnectionInfo.disks:type_name -> apis.EsxiDiskInfo
|
||||
11, // 20: apis.DeployAgent.DeployGuestFs:input_type -> apis.DeployParams
|
||||
12, // 21: apis.DeployAgent.ResizeFs:input_type -> apis.ResizeFsParams
|
||||
13, // 22: apis.DeployAgent.FormatFs:input_type -> apis.FormatFsParams
|
||||
15, // 23: apis.DeployAgent.SaveToGlance:input_type -> apis.SaveToGlanceParams
|
||||
17, // 24: apis.DeployAgent.ProbeImageInfo:input_type -> apis.ProbeImageInfoPramas
|
||||
20, // 25: apis.DeployAgent.ConnectEsxiDisks:input_type -> apis.ConnectEsxiDisksParams
|
||||
21, // 26: apis.DeployAgent.DisconnectEsxiDisks:input_type -> apis.EsxiDisksConnectionInfo
|
||||
9, // 27: apis.DeployAgent.DeployGuestFs:output_type -> apis.DeployGuestFsResponse
|
||||
8, // 28: apis.DeployAgent.ResizeFs:output_type -> apis.Empty
|
||||
8, // 29: apis.DeployAgent.FormatFs:output_type -> apis.Empty
|
||||
16, // 30: apis.DeployAgent.SaveToGlance:output_type -> apis.SaveToGlanceResponse
|
||||
18, // 31: apis.DeployAgent.ProbeImageInfo:output_type -> apis.ImageInfo
|
||||
21, // 32: apis.DeployAgent.ConnectEsxiDisks:output_type -> apis.EsxiDisksConnectionInfo
|
||||
8, // 33: apis.DeployAgent.DisconnectEsxiDisks:output_type -> apis.Empty
|
||||
27, // [27:34] is the sub-list for method output_type
|
||||
20, // [20:27] is the sub-list for method input_type
|
||||
20, // [20:20] is the sub-list for extension type_name
|
||||
20, // [20:20] is the sub-list for extension extendee
|
||||
0, // [0:20] is the sub-list for field type_name
|
||||
0, // 12: apis.ResizeFsParams.guest_desc:type_name -> apis.GuestDesc
|
||||
10, // 13: apis.FormatFsParams.disk_info:type_name -> apis.DiskInfo
|
||||
10, // 14: apis.SaveToGlanceParams.disk_info:type_name -> apis.DiskInfo
|
||||
14, // 15: apis.SaveToGlanceResponse.release_info:type_name -> apis.ReleaseInfo
|
||||
10, // 16: apis.ProbeImageInfoPramas.disk_info:type_name -> apis.DiskInfo
|
||||
14, // 17: apis.ImageInfo.os_info:type_name -> apis.ReleaseInfo
|
||||
3, // 18: apis.ConnectEsxiDisksParams.vddk_info:type_name -> apis.VDDKConInfo
|
||||
19, // 19: apis.ConnectEsxiDisksParams.access_info:type_name -> apis.EsxiDiskInfo
|
||||
19, // 20: apis.EsxiDisksConnectionInfo.disks:type_name -> apis.EsxiDiskInfo
|
||||
11, // 21: apis.DeployAgent.DeployGuestFs:input_type -> apis.DeployParams
|
||||
12, // 22: apis.DeployAgent.ResizeFs:input_type -> apis.ResizeFsParams
|
||||
13, // 23: apis.DeployAgent.FormatFs:input_type -> apis.FormatFsParams
|
||||
15, // 24: apis.DeployAgent.SaveToGlance:input_type -> apis.SaveToGlanceParams
|
||||
17, // 25: apis.DeployAgent.ProbeImageInfo:input_type -> apis.ProbeImageInfoPramas
|
||||
20, // 26: apis.DeployAgent.ConnectEsxiDisks:input_type -> apis.ConnectEsxiDisksParams
|
||||
21, // 27: apis.DeployAgent.DisconnectEsxiDisks:input_type -> apis.EsxiDisksConnectionInfo
|
||||
9, // 28: apis.DeployAgent.DeployGuestFs:output_type -> apis.DeployGuestFsResponse
|
||||
8, // 29: apis.DeployAgent.ResizeFs:output_type -> apis.Empty
|
||||
8, // 30: apis.DeployAgent.FormatFs:output_type -> apis.Empty
|
||||
16, // 31: apis.DeployAgent.SaveToGlance:output_type -> apis.SaveToGlanceResponse
|
||||
18, // 32: apis.DeployAgent.ProbeImageInfo:output_type -> apis.ImageInfo
|
||||
21, // 33: apis.DeployAgent.ConnectEsxiDisks:output_type -> apis.EsxiDisksConnectionInfo
|
||||
8, // 34: apis.DeployAgent.DisconnectEsxiDisks:output_type -> apis.Empty
|
||||
28, // [28:35] is the sub-list for method output_type
|
||||
21, // [21:28] is the sub-list for method input_type
|
||||
21, // [21:21] is the sub-list for extension type_name
|
||||
21, // [21:21] is the sub-list for extension extendee
|
||||
0, // [0:21] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_deploy_proto_init() }
|
||||
|
||||
@@ -131,6 +131,7 @@ message DiskInfo {
|
||||
string encrypt_password = 2;
|
||||
string encrypt_format = 3;
|
||||
string encrypt_alg = 4;
|
||||
string disk_id = 5;
|
||||
}
|
||||
|
||||
message DeployParams {
|
||||
@@ -144,6 +145,7 @@ message ResizeFsParams {
|
||||
DiskInfo disk_info = 1;
|
||||
string hypervisor = 2;
|
||||
VDDKConInfo vddk_info = 3;
|
||||
GuestDesc guest_desc = 4;
|
||||
}
|
||||
|
||||
message FormatFsParams {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.21.5
|
||||
// - protoc v3.21.2
|
||||
// source: deploy.proto
|
||||
|
||||
package apis
|
||||
|
||||
@@ -128,7 +128,7 @@ func (*DeployerServer) ResizeFs(ctx context.Context, req *deployapi.ResizeFsPara
|
||||
res, err = nil, errors.Error(msg)
|
||||
}
|
||||
}()
|
||||
log.Infof("********* Resize fs on %#v", apiDiskInfo(req.DiskInfo))
|
||||
log.Infof("********* Resize fs on %#v", req.DiskInfo)
|
||||
disk, err := diskutils.GetIDisk(diskutils.DiskParams{
|
||||
Hypervisor: req.Hypervisor,
|
||||
DiskInfo: apiDiskInfo(req.GetDiskInfo()),
|
||||
@@ -139,12 +139,16 @@ func (*DeployerServer) ResizeFs(ctx context.Context, req *deployapi.ResizeFsPara
|
||||
}
|
||||
defer disk.Cleanup()
|
||||
|
||||
if err := disk.Connect(nil); err != nil {
|
||||
var diskId string
|
||||
if req.DiskInfo != nil {
|
||||
diskId = req.DiskInfo.DiskId
|
||||
}
|
||||
if err := disk.ConnectWithDiskId(req.GuestDesc, diskId); err != nil {
|
||||
return new(deployapi.Empty), errors.Wrap(err, "disk connect failed")
|
||||
}
|
||||
defer disk.Disconnect()
|
||||
|
||||
return disk.ResizeFs()
|
||||
return disk.ResizeFs(req)
|
||||
}
|
||||
|
||||
func (*DeployerServer) FormatFs(ctx context.Context, req *deployapi.FormatFsParams) (*deployapi.Empty, error) {
|
||||
|
||||
@@ -50,11 +50,11 @@ func (d *LocalDeploy) ResizeFs(req *deployapi.ResizeFsParams) (res *deployapi.Em
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "new local disk")
|
||||
}
|
||||
if err := localDisk.Connect(nil); err != nil {
|
||||
if err := localDisk.Connect(req.GuestDesc); err != nil {
|
||||
return nil, errors.Wrapf(err, "local disk connect")
|
||||
}
|
||||
defer localDisk.Disconnect()
|
||||
return localDisk.ResizeFs()
|
||||
return localDisk.ResizeFs(req)
|
||||
}
|
||||
|
||||
func (d *LocalDeploy) FormatFs(req *deployapi.FormatFsParams) (*deployapi.Empty, error) {
|
||||
@@ -143,7 +143,11 @@ func StartLocalDeploy(deployAction string) (interface{}, error) {
|
||||
}
|
||||
return localDeployer.DeployGuestFs(params)
|
||||
case "resize_fs":
|
||||
return localDeployer.ResizeFs(nil)
|
||||
params := new(deployapi.ResizeFsParams)
|
||||
if err := unmarshalDeployParams(params); err != nil {
|
||||
return nil, errors.Wrap(err, "unmarshal params")
|
||||
}
|
||||
return localDeployer.ResizeFs(params)
|
||||
case "format_fs":
|
||||
params := new(deployapi.FormatFsParams)
|
||||
if err := unmarshalDeployParams(params); err != nil {
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// 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 qga
|
||||
|
||||
import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils/driver"
|
||||
)
|
||||
|
||||
type SQgaDriver struct {
|
||||
agent *QemuGuestAgent
|
||||
}
|
||||
|
||||
func NewQgaFsutilDriver(agent *QemuGuestAgent) driver.IFsutilExecDriver {
|
||||
ret := new(SQgaDriver)
|
||||
ret.agent = agent
|
||||
return ret
|
||||
}
|
||||
|
||||
func (q *SQgaDriver) ExecInputWait(name string, args []string, input []string) (int, string, string, error) {
|
||||
return q.agent.CommandWithTimeout(name, args, nil, "", true, -1)
|
||||
}
|
||||
|
||||
func (q *SQgaDriver) Exec(name string, args ...string) ([]byte, error) {
|
||||
retCode, stdout, stderr, err := q.agent.CommandWithTimeout(name, args, nil, "", true, -1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if retCode != 0 {
|
||||
return []byte(stdout + "\n" + stderr), errors.Errorf("Exit code %d", retCode)
|
||||
}
|
||||
var retStr = []byte(stdout)
|
||||
if len(stderr) > 0 {
|
||||
retStr = []byte(stdout + "\n" + stderr)
|
||||
}
|
||||
return retStr, nil
|
||||
}
|
||||
|
||||
func (q *SQgaDriver) Run(name string, args ...string) error {
|
||||
retCode, stdout, stderr, err := q.agent.CommandWithTimeout(name, args, nil, "", true, -1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if retCode != 0 {
|
||||
return errors.Errorf("Exit code %d\n%s\n%s", retCode, stdout, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -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 qga
|
||||
|
||||
import (
|
||||
|
||||
@@ -31,13 +31,14 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/types"
|
||||
"yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestfs"
|
||||
"yunion.io/x/onecloud/pkg/hostman/monitor"
|
||||
)
|
||||
|
||||
const (
|
||||
QGA_DEFAULT_READ_TIMEOUT_SECOND int = 5
|
||||
QGA_EXEC_DEFAULT_WAIT_TIMEOUT int = 5
|
||||
QGA_EXEC_DEFAULT_WAIT_TIMEOUT int = 300
|
||||
)
|
||||
|
||||
type QGACallback func([]byte)
|
||||
@@ -377,6 +378,46 @@ func (qga *QemuGuestAgent) QgaGetNetwork() ([]byte, error) {
|
||||
return *res, nil
|
||||
}
|
||||
|
||||
type GuestDiskPciController struct {
|
||||
Domain int `json:"domain"`
|
||||
Bus int `json:"bus"`
|
||||
Slot int `json:"slot"`
|
||||
Func int `json:"func"`
|
||||
}
|
||||
|
||||
type GuestFsDisk struct {
|
||||
PciController GuestDiskPciController `json:"pci-controller"`
|
||||
BusType string `json:"bus-type"`
|
||||
Bus int `json:"bus"`
|
||||
Target int `json:"target"`
|
||||
Unit int `json:"unit"`
|
||||
Serial string `json:"serial"`
|
||||
Dev string `json:"dev"`
|
||||
}
|
||||
|
||||
type GuestFsInfo struct {
|
||||
Name string `json:"name"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
Type string `json:"type"`
|
||||
UsedBytes int64 `json:"used-bytes"`
|
||||
TotalBytes int64 `json:"total-bytes"`
|
||||
Disk []GuestFsDisk `json:"disk"`
|
||||
}
|
||||
|
||||
func (qga *QemuGuestAgent) QgaGuestGetFsInfo() ([]GuestFsInfo, error) {
|
||||
//run guest-get-fsinfo
|
||||
cmdFsInfo := &monitor.Command{
|
||||
Execute: "guest-get-fsinfo",
|
||||
}
|
||||
rawResFsInfo, err := qga.execCmd(cmdFsInfo, true, -1)
|
||||
resFsInfo := make([]GuestFsInfo, 0)
|
||||
err = json.Unmarshal(*rawResFsInfo, &resFsInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unmarshal raw response")
|
||||
}
|
||||
return resFsInfo, nil
|
||||
}
|
||||
|
||||
type GuestOsInfo struct {
|
||||
Id string `json:"id"`
|
||||
KernelRelease string `json:"kernel-release"`
|
||||
@@ -690,6 +731,82 @@ func (qga *QemuGuestAgent) QgaDeployNics(guestNics []*types.SServerNic) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qga *QemuGuestAgent) QgaResizeDisk(diskId string) error {
|
||||
//Getting information about the operating system
|
||||
resOsInfo, err := qga.QgaGuestGetOsInfo()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get os info")
|
||||
}
|
||||
|
||||
//Judgement based on id, currently only windows and other systems are judged
|
||||
switch resOsInfo.Id {
|
||||
case "mswindows":
|
||||
return qga.QgaResizeWindowsDisk(diskId)
|
||||
default:
|
||||
return qga.QgaResizeLinuxDisk(diskId)
|
||||
}
|
||||
}
|
||||
|
||||
func (qga *QemuGuestAgent) QgaResizeWindowsDisk(diskId string) error {
|
||||
fsInfos, err := qga.QgaGuestGetFsInfo()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "QgaGuestGetFsInfo")
|
||||
}
|
||||
diskSerial := strings.ReplaceAll(diskId, "-", "")
|
||||
|
||||
for i := range fsInfos {
|
||||
fsInfo := fsInfos[i]
|
||||
for j := range fsInfo.Disk {
|
||||
if len(fsInfo.Disk[j].Serial) > 15 && strings.HasPrefix(diskSerial, fsInfo.Disk[j].Serial) {
|
||||
mountPoint := fsInfo.Mountpoint
|
||||
if strings.HasSuffix(mountPoint, ":\\") {
|
||||
driverLetter := mountPoint[0:1]
|
||||
log.Infof("disk %s found driver letter %s", mountPoint, driverLetter)
|
||||
retCode, stdout, stderr, err := qga.CommandWithTimeout("powershell.exe",
|
||||
[]string{"-Command", "Resize-Partition", "-DriveLetter", driverLetter, "-Size", fmt.Sprintf("(Get-PartitionSupportedSize -DriveLetter %s).SizeMax", driverLetter)},
|
||||
nil, "", true, -1,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "qga exec resize")
|
||||
}
|
||||
if retCode != 0 {
|
||||
return errors.Errorf("qga exec resize failed: %s %s, retcode %d", stdout, stderr, retCode)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qga *QemuGuestAgent) QgaResizeLinuxDisk(diskId string) error {
|
||||
qgaDriver := NewQgaFsutilDriver(qga)
|
||||
fsutilDriver := fsutils.NewFsutilDriver(qgaDriver)
|
||||
|
||||
err := qga.FilePutContents("/usr/bin/growpart", fsutils.GrowPartScript, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "file put content growpart")
|
||||
}
|
||||
retCode, stdout, stderr, err := qga.CommandWithTimeout("chmod", []string{"+x", "/usr/bin/growpart"}, nil, "", true, -1)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "chmod +x /usr/bin/growpart failed")
|
||||
}
|
||||
if retCode != 0 {
|
||||
return errors.Errorf("chmod +x /usr/bin/growpart failed: %s %s", stdout, stderr)
|
||||
}
|
||||
retCode, stdout, stderr, err = qga.CommandWithTimeout("sh", []string{"-c", "df / | awk 'NR==2{print $1}'"}, nil, "", true, -1)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "df / | awk 'NR==2{print $1}' failed")
|
||||
}
|
||||
if retCode != 0 {
|
||||
return errors.Errorf("df / | awk 'NR==2{print $1}' failed: %s %s", stdout, stderr)
|
||||
}
|
||||
rootPartDev := strings.TrimSpace(stdout)
|
||||
log.Infof("disk %s resize root part dev %s", diskId, rootPartDev)
|
||||
return fsutilDriver.ResizeDiskWithDiskId(diskId, rootPartDev, true)
|
||||
}
|
||||
|
||||
/*
|
||||
# @username: the user account whose password to change
|
||||
# @password: the new password entry string, base64 encoded
|
||||
|
||||
@@ -52,12 +52,8 @@ func (sd *SAgentDisk) PrepareSaveToGlance(ctx context.Context, params interface{
|
||||
return storage.PrepareSaveToGlance(ctx, p.TaskId, p.DiskInfo)
|
||||
}
|
||||
|
||||
func (sd *SAgentDisk) Resize(ctx context.Context, diskInfo interface{}) (jsonutils.JSONObject, error) {
|
||||
body, ok := diskInfo.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(hostutils.ParamsError, "PrepareSaveToGlance params format error")
|
||||
}
|
||||
|
||||
func (sd *SAgentDisk) Resize(ctx context.Context, params *SDiskResizeInput) (jsonutils.JSONObject, error) {
|
||||
body := params.DiskInfo
|
||||
type sResize struct {
|
||||
SizeMb int64 `json:"size_mb"`
|
||||
HostInfo vcenter.SVCenterAccessInfo
|
||||
|
||||
@@ -57,7 +57,7 @@ type IDisk interface {
|
||||
DiskSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
|
||||
DiskDeleteSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
|
||||
Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
|
||||
Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
|
||||
Resize(ctx context.Context, params *SDiskResizeInput) (jsonutils.JSONObject, error)
|
||||
PreResize(ctx context.Context, sizeMb int64) error
|
||||
PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
|
||||
ResetFromSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error)
|
||||
@@ -133,7 +133,7 @@ func (d *SBaseDisk) CreateFromRemoteHostImage(ctx context.Context, url string, s
|
||||
return errors.Errorf("unsupported operation")
|
||||
}
|
||||
|
||||
func (d *SBaseDisk) Resize(context.Context, interface{}) (jsonutils.JSONObject, error) {
|
||||
func (d *SBaseDisk) Resize(context.Context, *SDiskResizeInput) (jsonutils.JSONObject, error) {
|
||||
return nil, errors.Errorf("unsupported operation")
|
||||
}
|
||||
|
||||
@@ -201,9 +201,12 @@ func (d *SBaseDisk) DeployGuestFs(diskInfo *deployapi.DiskInfo, guestDesc *desc.
|
||||
return jsonutils.Marshal(ret), nil
|
||||
}
|
||||
|
||||
func (d *SBaseDisk) ResizeFs(diskInfo *deployapi.DiskInfo) error {
|
||||
func (d *SBaseDisk) ResizeFs(resizeDiskInput *deployapi.DiskInfo, guestDesc *deployapi.GuestDesc) error {
|
||||
_, err := deployclient.GetDeployClient().ResizeFs(
|
||||
context.Background(), &deployapi.ResizeFsParams{DiskInfo: diskInfo})
|
||||
context.Background(), &deployapi.ResizeFsParams{
|
||||
DiskInfo: resizeDiskInput,
|
||||
GuestDesc: guestDesc,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -153,12 +153,8 @@ func (d *SLocalDisk) OnRebuildRoot(ctx context.Context, params api.DiskAllocateI
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *SLocalDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
diskInfo, ok := params.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
|
||||
func (d *SLocalDisk) Resize(ctx context.Context, params *SDiskResizeInput) (jsonutils.JSONObject, error) {
|
||||
diskInfo := params.DiskInfo
|
||||
sizeMb, _ := diskInfo.Int("size")
|
||||
disk, err := qemuimg.NewQemuImage(d.GetPath())
|
||||
if err != nil {
|
||||
@@ -166,7 +162,8 @@ func (d *SLocalDisk) Resize(ctx context.Context, params interface{}) (jsonutils.
|
||||
return nil, err
|
||||
}
|
||||
resizeFsInfo := &deployapi.DiskInfo{
|
||||
Path: d.GetPath(),
|
||||
Path: d.GetPath(),
|
||||
DiskId: d.GetId(),
|
||||
}
|
||||
if diskInfo.Contains("encrypt_info") {
|
||||
var encryptInfo apis.SEncryptInfo
|
||||
@@ -192,7 +189,7 @@ func (d *SLocalDisk) Resize(ctx context.Context, params interface{}) (jsonutils.
|
||||
}
|
||||
}
|
||||
|
||||
if err := d.ResizeFs(resizeFsInfo); err != nil {
|
||||
if err := d.ResizeFs(resizeFsInfo, params.GuestDesc); err != nil {
|
||||
log.Errorf("Resize fs %s fail %s", d.GetPath(), err)
|
||||
// return nil, errors.Wrapf(err, "resize fs %s", d.GetPath())
|
||||
}
|
||||
@@ -249,11 +246,13 @@ func (d *SLocalDisk) createFromTemplateAndResize(
|
||||
retSize, _ := ret.Int("disk_size")
|
||||
log.Infof("REQSIZE: %d, RETSIZE: %d", size, retSize)
|
||||
if size > retSize {
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("size", jsonutils.NewInt(size))
|
||||
params := new(SDiskResizeInput)
|
||||
diskInfo := jsonutils.NewDict()
|
||||
diskInfo.Set("size", jsonutils.NewInt(size))
|
||||
if encryptInfo != nil {
|
||||
params.Set("encrypt_info", jsonutils.Marshal(encryptInfo))
|
||||
diskInfo.Set("encrypt_info", jsonutils.Marshal(encryptInfo))
|
||||
}
|
||||
params.DiskInfo = diskInfo
|
||||
return d.Resize(ctx, params)
|
||||
}
|
||||
return ret, nil
|
||||
|
||||
@@ -252,13 +252,9 @@ func (d *SLVMDisk) PreResize(ctx context.Context, sizeMb int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SLVMDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
diskInfo, ok := params.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
func (d *SLVMDisk) Resize(ctx context.Context, params *SDiskResizeInput) (jsonutils.JSONObject, error) {
|
||||
diskInfo := params.DiskInfo
|
||||
sizeMb, _ := diskInfo.Int("size")
|
||||
|
||||
qemuImg, err := qemuimg.NewQemuImage(d.GetPath())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "lvm qemuimg.NewQemuImage")
|
||||
@@ -275,7 +271,8 @@ func (d *SLVMDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JS
|
||||
}
|
||||
|
||||
resizeFsInfo := &deployapi.DiskInfo{
|
||||
Path: d.GetPath(),
|
||||
Path: d.GetPath(),
|
||||
DiskId: d.GetId(),
|
||||
}
|
||||
if diskInfo.Contains("encrypt_info") {
|
||||
var encryptInfo apis.SEncryptInfo
|
||||
@@ -295,7 +292,7 @@ func (d *SLVMDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JS
|
||||
return nil, errors.Wrap(err, "qemuImg resize")
|
||||
}
|
||||
|
||||
if err := d.ResizeFs(resizeFsInfo); err != nil {
|
||||
if err := d.ResizeFs(resizeFsInfo, params.GuestDesc); err != nil {
|
||||
log.Errorf("Resize fs %s fail %s", d.GetPath(), err)
|
||||
}
|
||||
return d.GetDiskDesc(), nil
|
||||
@@ -318,11 +315,13 @@ func (d *SLVMDisk) CreateFromTemplate(
|
||||
retSize, _ := ret.Int("disk_size")
|
||||
log.Infof("REQSIZE: %d, RETSIZE: %d", sizeMb, retSize)
|
||||
if sizeMb > retSize {
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("size", jsonutils.NewInt(sizeMb))
|
||||
params := new(SDiskResizeInput)
|
||||
diskInfo := jsonutils.NewDict()
|
||||
diskInfo.Set("size", jsonutils.NewInt(sizeMb))
|
||||
if encryptInfo != nil {
|
||||
params.Set("encrypt_info", jsonutils.Marshal(encryptInfo))
|
||||
diskInfo.Set("encrypt_info", jsonutils.Marshal(encryptInfo))
|
||||
}
|
||||
params.DiskInfo = diskInfo
|
||||
return d.Resize(ctx, params)
|
||||
}
|
||||
return ret, nil
|
||||
|
||||
@@ -73,13 +73,14 @@ func (d *SNasDisk) CreateFromSnapshotLocation(ctx context.Context, snapshotLocat
|
||||
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))
|
||||
params := new(SDiskResizeInput)
|
||||
diskInfo := jsonutils.NewDict()
|
||||
diskInfo.Set("size", jsonutils.NewInt(size))
|
||||
if encryptInfo != nil {
|
||||
params.Set("encrypt_info", jsonutils.Marshal(encryptInfo))
|
||||
diskInfo.Set("encrypt_info", jsonutils.Marshal(encryptInfo))
|
||||
}
|
||||
_, err = d.Resize(ctx, params)
|
||||
return nil, err
|
||||
params.DiskInfo = diskInfo
|
||||
return d.Resize(ctx, params)
|
||||
}
|
||||
return d.GetDiskDesc(), nil
|
||||
}
|
||||
|
||||
@@ -118,11 +118,8 @@ func (d *SRBDDisk) OnRebuildRoot(ctx context.Context, params api.DiskAllocateInp
|
||||
return storage.renameImage(pool, d.Id, params.BackingDiskId)
|
||||
}
|
||||
|
||||
func (d *SRBDDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
diskInfo, ok := params.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
func (d *SRBDDisk) Resize(ctx context.Context, params *SDiskResizeInput) (jsonutils.JSONObject, error) {
|
||||
diskInfo := params.DiskInfo
|
||||
storage := d.Storage.(*SRbdStorage)
|
||||
sizeMb, _ := diskInfo.Int("size")
|
||||
if err := storage.resizeImage(d.Id, uint64(sizeMb)); err != nil {
|
||||
@@ -130,9 +127,10 @@ func (d *SRBDDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JS
|
||||
}
|
||||
|
||||
resizeFsInfo := &deployapi.DiskInfo{
|
||||
Path: d.GetPath(),
|
||||
Path: d.GetPath(),
|
||||
DiskId: d.GetId(),
|
||||
}
|
||||
if err := d.ResizeFs(resizeFsInfo); err != nil {
|
||||
if err := d.ResizeFs(resizeFsInfo, params.GuestDesc); err != nil {
|
||||
log.Errorf("Resize fs %s fail %s", d.GetPath(), err)
|
||||
// return nil, errors.Wrapf(err, "resize fs %s", d.GetPath())
|
||||
}
|
||||
@@ -176,8 +174,10 @@ func (d *SRBDDisk) CreateFromTemplate(ctx context.Context, imageId string, forma
|
||||
retSize, _ := ret.Int("disk_size")
|
||||
log.Infof("REQSIZE: %d, RETSIZE: %d", size, retSize)
|
||||
if size > retSize {
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("size", jsonutils.NewInt(size))
|
||||
params := new(SDiskResizeInput)
|
||||
diskInfo := jsonutils.NewDict()
|
||||
diskInfo.Set("size", jsonutils.NewInt(size))
|
||||
params.DiskInfo = diskInfo
|
||||
return d.Resize(ctx, params)
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ func (d *SSLVMDisk) PreResize(ctx context.Context, sizeMb int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SSLVMDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
func (d *SSLVMDisk) Resize(ctx context.Context, params *SDiskResizeInput) (jsonutils.JSONObject, error) {
|
||||
if ok, err := lvmutils.LvIsActivated(d.GetPath()); err != nil {
|
||||
return nil, err
|
||||
} else if ok && d.Storage.Lvmlockd() {
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/workmanager"
|
||||
"yunion.io/x/onecloud/pkg/hostman/guestman"
|
||||
deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostutils"
|
||||
"yunion.io/x/onecloud/pkg/hostman/storageman"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
@@ -314,12 +315,31 @@ func diskResize(ctx context.Context, userCred mcclient.TokenCredential, storage
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("disk")
|
||||
}
|
||||
resizeDiskInfo := &storageman.SDiskResizeInput{
|
||||
DiskInfo: diskInfo,
|
||||
}
|
||||
serverId, _ := diskInfo.GetString("server_id")
|
||||
if len(serverId) > 0 {
|
||||
guest, ok := guestman.GetGuestManager().GetServer(serverId)
|
||||
if !ok {
|
||||
return nil, httperrors.NewBadRequestError("server %s not found", serverId)
|
||||
}
|
||||
deployDesc := deployapi.GuestStructDescToDeployDesc(guest.Desc)
|
||||
resizeDiskInfo.GuestDesc = deployDesc
|
||||
}
|
||||
|
||||
if len(serverId) > 0 && guestman.GetGuestManager().Status(serverId) == "running" {
|
||||
sizeMb, _ := diskInfo.Int("size")
|
||||
return guestman.GetGuestManager().OnlineResizeDisk(ctx, serverId, disk, sizeMb)
|
||||
} else {
|
||||
hostutils.DelayTask(ctx, disk.Resize, diskInfo)
|
||||
resizeFunc := func(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
input, ok := params.(*storageman.SDiskResizeInput)
|
||||
if !ok {
|
||||
return nil, hostutils.ParamsError
|
||||
}
|
||||
return disk.Resize(ctx, input)
|
||||
}
|
||||
hostutils.DelayTask(ctx, resizeFunc, diskInfo)
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
@@ -120,3 +121,8 @@ type SStorageSaveToGlanceInfo struct {
|
||||
UserCred mcclient.TokenCredential
|
||||
DiskInfo *jsonutils.JSONDict
|
||||
}
|
||||
|
||||
type SDiskResizeInput struct {
|
||||
DiskInfo jsonutils.JSONObject
|
||||
GuestDesc *deployapi.GuestDesc
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user