@@ -9,12 +9,16 @@ import (
99 "fmt"
1010 "io/fs"
1111 "os"
12+ "path/filepath"
1213 "text/tabwriter"
1314
15+ contfs "github.com/containerd/continuity/fs"
1416 "github.com/docker/go-units"
17+ "github.com/lima-vm/go-qcow2reader"
1518 "github.com/lima-vm/lima/pkg/nativeimgutil"
1619 "github.com/lima-vm/lima/pkg/qemu"
1720 "github.com/lima-vm/lima/pkg/store"
21+ "github.com/lima-vm/lima/pkg/store/filenames"
1822 "github.com/sirupsen/logrus"
1923 "github.com/spf13/cobra"
2024)
@@ -44,6 +48,7 @@ func newDiskCommand() *cobra.Command {
4448 newDiskDeleteCommand (),
4549 newDiskUnlockCommand (),
4650 newDiskResizeCommand (),
51+ newDiskImportCommand (),
4752 )
4853 return diskCommand
4954}
@@ -418,3 +423,64 @@ func diskResizeAction(cmd *cobra.Command, args []string) error {
418423func diskBashComplete (cmd * cobra.Command , _ []string , _ string ) ([]string , cobra.ShellCompDirective ) {
419424 return bashCompleteDiskNames (cmd )
420425}
426+
427+ func newDiskImportCommand () * cobra.Command {
428+ diskImportCommand := & cobra.Command {
429+ Use : "import DISK FILE" ,
430+ Example : `
431+ Import a disk:
432+ $ limactl disk import DISK DISKPATH
433+ ` ,
434+ Short : "Import an existing disk to Lima" ,
435+ Args : WrapArgsError (cobra .ExactArgs (2 )),
436+ RunE : diskImportAction ,
437+ ValidArgsFunction : diskBashComplete ,
438+ }
439+ return diskImportCommand
440+ }
441+
442+ func diskImportAction (_ * cobra.Command , args []string ) error {
443+ diskName := args [0 ]
444+ fName := args [1 ]
445+
446+ diskDir , err := store .DiskDir (diskName )
447+ if err != nil {
448+ return err
449+ }
450+
451+ if _ , err := os .Stat (diskDir ); ! errors .Is (err , fs .ErrNotExist ) {
452+ return fmt .Errorf ("disk %q already exists (%q)" , diskName , diskDir )
453+ }
454+
455+ f , err := os .Open (fName )
456+ if err != nil {
457+ return err
458+ }
459+ defer f .Close ()
460+
461+ img , err := qcow2reader .Open (f )
462+ if err != nil {
463+ return err
464+ }
465+
466+ diskSize := img .Size ()
467+ format := img .Type ()
468+
469+ switch format {
470+ case "qcow2" , "raw" :
471+ default :
472+ return fmt .Errorf (`disk format %q not supported, use "qcow2" or "raw" instead` , format )
473+ }
474+
475+ if err := os .MkdirAll (diskDir , 0o755 ); err != nil {
476+ return err
477+ }
478+
479+ if err := contfs .CopyFile (filepath .Join (diskDir , filenames .DataDisk ), fName ); err != nil {
480+ return nil
481+ }
482+
483+ logrus .Infof ("Imported %s with size %s" , diskName , units .BytesSize (float64 (diskSize )))
484+
485+ return nil
486+ }
0 commit comments