kvm.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package diskutils
  15. import (
  16. "io/ioutil"
  17. "os"
  18. "path/filepath"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. cloudconsts "yunion.io/x/onecloud/pkg/cloudcommon/consts"
  22. "yunion.io/x/onecloud/pkg/hostman/diskutils/deploy_iface"
  23. "yunion.io/x/onecloud/pkg/hostman/diskutils/libguestfs"
  24. "yunion.io/x/onecloud/pkg/hostman/diskutils/nbd"
  25. "yunion.io/x/onecloud/pkg/hostman/diskutils/qemu_kvm"
  26. "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver"
  27. "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
  28. "yunion.io/x/onecloud/pkg/hostman/hostdeployer/consts"
  29. "yunion.io/x/onecloud/pkg/util/qemuimg"
  30. )
  31. type SKVMGuestDisk struct {
  32. readOnly bool
  33. kvmImagePath string
  34. topImagePath string
  35. deployer deploy_iface.IDeployer
  36. }
  37. func NewKVMGuestDisk(imageInfo qemuimg.SImageInfo, driver string, readOnly bool) (*SKVMGuestDisk, error) {
  38. originImage := imageInfo.Path
  39. imagePath := imageInfo.Path
  40. if readOnly {
  41. // if readonly, create a top image over the original image, open device as RW
  42. tmpFileDir, err := ioutil.TempDir(cloudconsts.DeployTempDir(), "kvm_disks")
  43. if err != nil {
  44. log.Errorf("fail to obtain tempFile for readonly kvm disk: %s", err)
  45. return nil, errors.Wrap(err, "ioutil.TempDir")
  46. }
  47. tmpFileName := filepath.Join(tmpFileDir, "disk")
  48. img, err := qemuimg.NewQemuImage(tmpFileName)
  49. if err != nil {
  50. log.Errorf("fail to init qemu image %s", tmpFileName)
  51. return nil, errors.Wrap(err, "NewQemuImage")
  52. }
  53. err = img.CreateQcow2(0, false, imageInfo.Path, imageInfo.Password, imageInfo.EncryptFormat, imageInfo.EncryptAlg)
  54. if err != nil {
  55. log.Errorf("fail to create overlay qcow2 for kvm disk readonly access: %s", err)
  56. return nil, errors.Wrap(err, "CreateQcow2")
  57. }
  58. originImage = imagePath
  59. imagePath = tmpFileName
  60. imageInfo.Path = tmpFileName
  61. }
  62. return &SKVMGuestDisk{
  63. readOnly: readOnly,
  64. kvmImagePath: originImage,
  65. topImagePath: imagePath,
  66. deployer: newDeployer(imageInfo, driver),
  67. }, nil
  68. }
  69. func (d *SKVMGuestDisk) Cleanup() {
  70. if d.readOnly {
  71. // if readonly, discard the top image when cleanup
  72. os.RemoveAll(filepath.Dir(d.topImagePath))
  73. }
  74. }
  75. var _ deploy_iface.IDeployer = (*qemu_kvm.QemuKvmDriver)(nil)
  76. var _ deploy_iface.IDeployer = (*qemu_kvm.LocalDiskDriver)(nil)
  77. func newDeployer(imageInfo qemuimg.SImageInfo, driver string) deploy_iface.IDeployer {
  78. switch driver {
  79. case consts.DEPLOY_DRIVER_NBD:
  80. return nbd.NewNBDDriver(imageInfo)
  81. case consts.DEPLOY_DRIVER_LIBGUESTFS:
  82. return libguestfs.NewLibguestfsDriver(imageInfo)
  83. case consts.DEPLOY_DRIVER_QEMU_KVM:
  84. return qemu_kvm.NewQemuKvmDriver(imageInfo)
  85. case consts.DEPLOY_DRIVER_LOCAL_DISK:
  86. return qemu_kvm.NewLocalDiskDriver()
  87. default:
  88. return nbd.NewNBDDriver(imageInfo)
  89. }
  90. }
  91. func (d *SKVMGuestDisk) IsLVMPartition() bool {
  92. return d.deployer.IsLVMPartition()
  93. }
  94. func (d *SKVMGuestDisk) Connect(guestDesc *apis.GuestDesc) error {
  95. return d.deployer.Connect(guestDesc, "")
  96. }
  97. func (d *SKVMGuestDisk) ConnectWithDiskId(guestDesc *apis.GuestDesc, diskId string) error {
  98. return d.deployer.Connect(guestDesc, diskId)
  99. }
  100. func (d *SKVMGuestDisk) Disconnect() error {
  101. return d.deployer.Disconnect()
  102. }
  103. func (d *SKVMGuestDisk) MountRootfs() (fsdriver.IRootFsDriver, error) {
  104. return d.MountKvmRootfs()
  105. }
  106. func (d *SKVMGuestDisk) MountKvmRootfs() (fsdriver.IRootFsDriver, error) {
  107. return d.mountKvmRootfs(false)
  108. }
  109. func (d *SKVMGuestDisk) mountKvmRootfs(readonly bool) (fsdriver.IRootFsDriver, error) {
  110. return d.deployer.MountRootfs(readonly)
  111. }
  112. func (d *SKVMGuestDisk) MountKvmRootfsReadOnly() (fsdriver.IRootFsDriver, error) {
  113. return d.mountKvmRootfs(true)
  114. }
  115. func (d *SKVMGuestDisk) UmountKvmRootfs(fd fsdriver.IRootFsDriver) error {
  116. if part := fd.GetPartition(); part != nil {
  117. return part.Umount()
  118. }
  119. return nil
  120. }
  121. func (d *SKVMGuestDisk) UmountRootfs(fd fsdriver.IRootFsDriver) error {
  122. if fd == nil {
  123. return nil
  124. }
  125. return d.UmountKvmRootfs(fd)
  126. }
  127. func (d *SKVMGuestDisk) DeployGuestfs(req *apis.DeployParams) (res *apis.DeployGuestFsResponse, err error) {
  128. return d.deployer.DeployGuestfs(req)
  129. }
  130. func (d *SKVMGuestDisk) ResizeFs(req *apis.ResizeFsParams) (*apis.Empty, error) {
  131. log.Errorf("start resizefs")
  132. return d.deployer.ResizeFs(req)
  133. }
  134. func (d *SKVMGuestDisk) FormatFs(req *apis.FormatFsParams) (*apis.Empty, error) {
  135. return d.deployer.FormatFs(req)
  136. }
  137. func (d *SKVMGuestDisk) SaveToGlance(req *apis.SaveToGlanceParams) (*apis.SaveToGlanceResponse, error) {
  138. return d.deployer.SaveToGlance(req)
  139. }
  140. func (d *SKVMGuestDisk) ProbeImageInfo(req *apis.ProbeImageInfoPramas) (*apis.ImageInfo, error) {
  141. return d.deployer.ProbeImageInfo(req)
  142. }