-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
201 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package virtualbox | ||
|
||
import ( | ||
"fmt" | ||
"github.com/mhewedy/vermin/db" | ||
"github.com/mhewedy/vermin/hypervisor/base" | ||
"github.com/mhewedy/vermin/log" | ||
"github.com/mhewedy/vermin/progress" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
func (*virtualbox) ShrinkDisk(vmName string) error { | ||
|
||
stop := progress.Show("Shrinking disk", false) | ||
defer stop() | ||
|
||
box, err := getBoxInfo(vmName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
origDiskPath := filepath.Join(db.GetVMPath(vmName), box.Disk.Location) | ||
|
||
if isVMDK(box.Disk) { | ||
|
||
tmpDir, err := ioutil.TempDir("", "vermin_disk_shrink_"+vmName) | ||
if err != nil { | ||
return err | ||
} | ||
defer os.RemoveAll(tmpDir) | ||
|
||
vdiPath := filepath.Join(tmpDir, box.Disk.Location+".vdi") | ||
newVMDKPath := filepath.Join(tmpDir, box.Disk.Location) | ||
|
||
log.Debug("clone vmdk disk into vdi") | ||
if err := vboxManage("clonehd", origDiskPath, vdiPath, "--format", "vdi").Run(); err != nil { | ||
return err | ||
} | ||
log.Debug("shrink the vdi") | ||
if err := vboxManage("modifyhd", vdiPath, "--compact").Run(); err != nil { | ||
return err | ||
} | ||
log.Debug("clone the vdi back into a new vmdk") | ||
if err := vboxManage("clonehd", vdiPath, newVMDKPath, "--format", "vmdk").Run(); err != nil { | ||
return err | ||
} | ||
log.Debug("set the uuid of the new vmdk with the same uuid of the old vmdk") | ||
if err := vboxManage("internalcommands", "sethduuid", newVMDKPath, box.Disk.UUID).Run(); err != nil { | ||
return err | ||
} | ||
log.Debug("copy the new vmdk into the same location of the old vmdk") | ||
return copyFile(newVMDKPath, origDiskPath) | ||
|
||
} else if isVDI(box.Disk) { | ||
return vboxManage("modifyhd", origDiskPath, "--compact").Run() | ||
} else { | ||
return fmt.Errorf("unsupported disk format %s", box.Disk.Location) | ||
} | ||
} | ||
|
||
func isVMDK(disk *base.Disk) bool { | ||
return strings.HasSuffix(strings.ToLower(disk.Location), ".vmdk") | ||
} | ||
|
||
func isVDI(disk *base.Disk) bool { | ||
return strings.HasSuffix(strings.ToLower(disk.Location), ".vdi") | ||
} | ||
|
||
// Copy the src file to dst. Any existing file will be overwritten and will not | ||
// copy file attributes. | ||
func copyFile(src, dst string) error { | ||
in, err := os.Open(src) | ||
if err != nil { | ||
return err | ||
} | ||
defer in.Close() | ||
|
||
out, err := os.Create(dst) | ||
if err != nil { | ||
return err | ||
} | ||
defer out.Close() | ||
|
||
_, err = io.Copy(out, in) | ||
if err != nil { | ||
return err | ||
} | ||
return out.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package vms | ||
|
||
import ( | ||
"fmt" | ||
"github.com/mhewedy/vermin/cmd/ssh" | ||
"github.com/mhewedy/vermin/hypervisor" | ||
"github.com/mhewedy/vermin/progress" | ||
) | ||
|
||
func Shrink(vmName string) error { | ||
|
||
fmt.Println("The VM will restarted as part of the disk shrinking process.\n" + | ||
"Please note that, this is a time-consuming process and requires a free disk space on your disk.") | ||
|
||
if err := ssh.EstablishConn(vmName); err != nil { | ||
return err | ||
} | ||
|
||
if err := zerofyDisk(vmName); err != nil { | ||
return err | ||
} | ||
|
||
if err := Stop(vmName); err != nil { | ||
return err | ||
} | ||
|
||
if err := hypervisor.ShrinkDisk(vmName); err != nil { | ||
return err | ||
} | ||
|
||
return Start(vmName) | ||
} | ||
|
||
func zerofyDisk(vmName string) error { | ||
stop := progress.Show("Filling free disk space with zeros", false) | ||
defer stop() | ||
// sometimes the an error returned, however the command succeed | ||
_, _ = ssh.Execute(vmName, "sh -c 'cat /dev/zero > zero.fill; sync; sleep 1; sync; rm -f zero.fill'") | ||
return nil | ||
} |