Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions cmd/list.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package cmd

import (
"fmt"
"os"

"github.com/containers/podman-bootc/pkg/config"
"github.com/containers/podman-bootc/pkg/define"
"github.com/containers/podman-bootc/pkg/user"
"github.com/containers/podman-bootc/pkg/utils"
"github.com/containers/podman-bootc/pkg/vm"

"github.com/containers/common/pkg/report"
Expand Down Expand Up @@ -60,46 +61,49 @@ func doList(_ *cobra.Command, _ []string) error {
}

func CollectVmList(user user.User, libvirtUri string) (vmList []vm.BootcVMConfig, err error) {
files, err := os.ReadDir(user.CacheDir())
ids, err := user.Storage().List()
if err != nil {
return nil, err
}

for _, f := range files {
if f.IsDir() {
cfg, err := getVMInfo(user, libvirtUri, f.Name())
if err != nil {
logrus.Warningf("skipping vm %s reason: %v", f.Name(), err)
continue
}

vmList = append(vmList, *cfg)
for _, id := range ids {
cfg, err := getVMInfo(user, libvirtUri, id)
if err != nil {
logrus.Warningf("skipping vm %s reason: %v", id, err)
continue
}

vmList = append(vmList, *cfg)
}
return vmList, nil
}

func getVMInfo(user user.User, libvirtUri string, imageId string) (*vm.BootcVMConfig, error) {
func getVMInfo(user user.User, libvirtUri string, imageId define.FullImageId) (*vm.BootcVMConfig, error) {
guard, unlock, err := user.Storage().Get(imageId)
if err != nil {
return nil, fmt.Errorf("unable to lock the VM cache: %w", err)
}
defer func() {
if err := unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", imageId, err)
}
}()

bootcVM, err := vm.NewVM(vm.NewVMParameters{
ImageID: imageId,
ImageID: string(imageId),
User: user,
LibvirtUri: libvirtUri,
Locking: utils.Shared,
})

if err != nil {
return nil, err
}

// Let's be explicit instead of relying on the defer exec order
defer func() {
bootcVM.CloseConnection()
if err := bootcVM.Unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", imageId, err)
}
}()

cfg, err := bootcVM.GetConfig()
cfg, err := bootcVM.GetConfig(guard)
if err != nil {
return nil, err
}
Expand Down
61 changes: 33 additions & 28 deletions cmd/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package cmd

import (
"fmt"
"os"

"github.com/containers/podman-bootc/pkg/config"
"github.com/containers/podman-bootc/pkg/define"
"github.com/containers/podman-bootc/pkg/user"
"github.com/containers/podman-bootc/pkg/utils"
"github.com/containers/podman-bootc/pkg/vm"

"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -44,35 +43,49 @@ func oneOrAll() cobra.PositionalArgs {
}

func doRemove(_ *cobra.Command, args []string) error {
usr, err := user.NewUser()
if err != nil {
return err
}

if removeAll {
return pruneAll()
return pruneAll(usr)
}

return prune(args[0])
id := args[0]
fullImageId, err := usr.Storage().SearchByPrefix(id)
if err != nil {
return fmt.Errorf("searching for ID %s: %w", id, err)
}
if fullImageId == nil {
return fmt.Errorf("local installation '%s' does not exists", id)
}

return prune(usr, *fullImageId)
}

func prune(id string) error {
user, err := user.NewUser()
func prune(usr user.User, id define.FullImageId) error {
_, unlock, err := usr.Storage().GetExclusiveOrAdd(id)
if err != nil {
return err
return fmt.Errorf("unable to lock the VM cache: %w", err)
}
defer func() {
if err := unlock(); err != nil {
logrus.Errorf("unable to unlock VM %s: %v", id, err)
}
}()

bootcVM, err := vm.NewVM(vm.NewVMParameters{
ImageID: id,
ImageID: string(id),
LibvirtUri: config.LibvirtUri,
User: user,
Locking: utils.Exclusive,
User: usr,
})
if err != nil {
return fmt.Errorf("unable to get VM %s: %v", id, err)
}

// Let's be explicit instead of relying on the defer exec order
defer func() {
bootcVM.CloseConnection()
if err := bootcVM.Unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", id, err)
}
}()

if force {
Expand All @@ -90,24 +103,16 @@ func prune(id string) error {
return nil
}

func pruneAll() error {
user, err := user.NewUser()
func pruneAll(usr user.User) error {
ids, err := usr.Storage().List()
if err != nil {
return err
}

files, err := os.ReadDir(user.CacheDir())
if err != nil {
return err
}

for _, f := range files {
if f.IsDir() {
vmID := f.Name()
err := prune(vmID)
if err != nil {
logrus.Errorf("unable to remove %s: %v", vmID, err)
}
for _, id := range ids {
err := prune(usr, id)
if err != nil {
logrus.Errorf("unable to remove %s: %v", id, err)
}
}

Expand Down
18 changes: 13 additions & 5 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/containers/podman-bootc/pkg/bootc"
"github.com/containers/podman-bootc/pkg/config"
"github.com/containers/podman-bootc/pkg/define"
"github.com/containers/podman-bootc/pkg/user"
"github.com/containers/podman-bootc/pkg/utils"
"github.com/containers/podman-bootc/pkg/vm"
Expand Down Expand Up @@ -116,11 +117,20 @@ func doRun(flags *cobra.Command, args []string) error {
return fmt.Errorf("unable to get free port for SSH: %w", err)
}

guard, unlock, err := user.Storage().Get(define.FullImageId(bootcDisk.GetImageId()))
if err != nil {
return fmt.Errorf("unable to lock the VM cache: %w", err)
}
defer func() {
if err := unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", bootcDisk.GetImageId(), err)
}
}()

bootcVM, err := vm.NewVM(vm.NewVMParameters{
ImageID: bootcDisk.GetImageId(),
User: user,
LibvirtUri: config.LibvirtUri,
Locking: utils.Shared,
})

if err != nil {
Expand All @@ -130,9 +140,6 @@ func doRun(flags *cobra.Command, args []string) error {
// Let's be explicit instead of relying on the defer exec order
defer func() {
bootcVM.CloseConnection()
if err := bootcVM.Unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", bootcDisk.GetImageId(), err)
}
}()

cmd := args[1:]
Expand All @@ -153,6 +160,7 @@ func doRun(flags *cobra.Command, args []string) error {
}

// write down the config file
// FIXME: we are writing the config using a shared guard
if err = bootcVM.WriteConfig(*bootcDisk); err != nil {
return err
}
Expand Down Expand Up @@ -191,7 +199,7 @@ func doRun(flags *cobra.Command, args []string) error {
}

// ssh into the VM
ExitCode, err = utils.WithExitCode(bootcVM.RunSSH(cmd))
ExitCode, err = utils.WithExitCode(bootcVM.RunSSH(guard, cmd))
if err != nil {
return fmt.Errorf("ssh: %w", err)
}
Expand Down
33 changes: 23 additions & 10 deletions cmd/ssh.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"fmt"

"github.com/containers/podman-bootc/pkg/config"
"github.com/containers/podman-bootc/pkg/user"
"github.com/containers/podman-bootc/pkg/utils"
Expand All @@ -25,30 +27,41 @@ func init() {
}

func doSsh(_ *cobra.Command, args []string) error {
user, err := user.NewUser()
usr, err := user.NewUser()
if err != nil {
return err
}

id := args[0]
fullImageId, err := usr.Storage().SearchByPrefix(id)
if err != nil {
return fmt.Errorf("searching for ID %s: %w", id, err)
}
if fullImageId == nil {
return fmt.Errorf("local installation '%s' does not exists", id)
}

guard, unlock, err := usr.Storage().Get(*fullImageId)
if err != nil {
return fmt.Errorf("unable to lock the VM cache: %w", err)
}
defer func() {
if err := unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", id, err)
}
}()

vm, err := vm.NewVM(vm.NewVMParameters{
ImageID: id,
User: user,
ImageID: string(*fullImageId),
User: usr,
LibvirtUri: config.LibvirtUri,
Locking: utils.Shared,
})

if err != nil {
return err
}

// Let's be explicit instead of relying on the defer exec order
defer func() {
vm.CloseConnection()
if err := vm.Unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", id, err)
}
}()

err = vm.SetUser(sshUser)
Expand All @@ -61,6 +74,6 @@ func doSsh(_ *cobra.Command, args []string) error {
cmd = args[1:]
}

ExitCode, err = utils.WithExitCode(vm.RunSSH(cmd))
ExitCode, err = utils.WithExitCode(vm.RunSSH(guard, cmd))
return err
}
32 changes: 23 additions & 9 deletions cmd/stop.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package cmd

import (
"fmt"

"github.com/containers/podman-bootc/pkg/config"
"github.com/containers/podman-bootc/pkg/user"
"github.com/containers/podman-bootc/pkg/utils"
"github.com/containers/podman-bootc/pkg/vm"

"github.com/sirupsen/logrus"
Expand All @@ -23,28 +24,41 @@ func init() {
}

func doStop(_ *cobra.Command, args []string) (err error) {
user, err := user.NewUser()
usr, err := user.NewUser()
if err != nil {
return err
}

id := args[0]
fullImageId, err := usr.Storage().SearchByPrefix(id)
if err != nil {
return fmt.Errorf("searching for ID %s: %w", id, err)
}
if fullImageId == nil {
return fmt.Errorf("local installation '%s' does not exists", id)
}

_, unlock, err := usr.Storage().GetExclusiveOrAdd(*fullImageId)
if err != nil {
return fmt.Errorf("unable to lock the VM cache: %w", err)
}
defer func() {
if err := unlock(); err != nil {
logrus.Errorf("unable to unlock VM %s: %v", id, err)
}
}()

bootcVM, err := vm.NewVM(vm.NewVMParameters{
ImageID: id,
ImageID: string(*fullImageId),
LibvirtUri: config.LibvirtUri,
User: user,
Locking: utils.Exclusive,
User: usr,
})
if err != nil {
return err
}

// Let's be explicit instead of relying on the defer exec order
defer func() {
bootcVM.CloseConnection()
if err := bootcVM.Unlock(); err != nil {
logrus.Warningf("unable to unlock VM %s: %v", id, err)
}
}()

return bootcVM.Delete()
Expand Down
Loading