Skip to content

Commit 4ccf515

Browse files
committed
disk: Recreate the bootc disk image when passed certain parameters
Sometimes the disk image needs to be recreated even if reusing the same container image, for example when passing --disk-size to create a bootc disk with a larger disk size. Signed-off-by: Chris Kyrouac <[email protected]>
1 parent ff78afc commit 4ccf515

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

cmd/run.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,16 @@ func doRun(flags *cobra.Command, args []string) error {
136136
return fmt.Errorf("VM already running, use the ssh command to connect to it")
137137
}
138138

139+
// if any of these parameters are set, we need to rebuild the disk image if one exists
140+
bustCache := false
141+
if diskImageConfigInstance.DiskSize != "" ||
142+
diskImageConfigInstance.RootSizeMax != "" ||
143+
diskImageConfigInstance.Filesystem != "" {
144+
bustCache = true
145+
}
146+
139147
// create the disk image
140-
bootcDisk := bootc.NewBootcDisk(containerImage, ctx, user, cache)
148+
bootcDisk := bootc.NewBootcDisk(containerImage, ctx, user, cache, bustCache)
141149
err = bootcDisk.Install(vmConfig.Quiet, diskImageConfigInstance)
142150

143151
if err != nil {

pkg/bootc/bootc_disk.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type BootcDisk struct {
6868
CreatedAt time.Time
6969
file *os.File
7070
bootcInstallContainerId string
71+
bustCache bool
7172
}
7273

7374
// create singleton for easy cleanup
@@ -82,13 +83,16 @@ var (
8283
// - imageNameOrId: the name or id of the container image
8384
// - ctx: context for the podman machine connection
8485
// - user: the user who is running the command, determines where the disk image is stored
85-
func NewBootcDisk(containerImage container.ContainerImage, ctx context.Context, user user.User, cache cache.Cache) *BootcDisk {
86+
// - cache: the cache to use for storing the disk image
87+
// - bustCache: whether to force a new disk image to be created
88+
func NewBootcDisk(containerImage container.ContainerImage, ctx context.Context, user user.User, cache cache.Cache, bustCache bool) *BootcDisk {
8689
instanceOnce.Do(func() {
8790
instance = &BootcDisk{
8891
ContainerImage: containerImage,
8992
Ctx: ctx,
9093
User: user,
9194
Cache: cache,
95+
bustCache: bustCache,
9296
}
9397
})
9498
return instance
@@ -146,13 +150,25 @@ func (p *BootcDisk) getOrInstallImageToDisk(quiet bool, diskConfig DiskImageConf
146150
logrus.Debugf("No existing disk image found")
147151
return p.bootcInstallImageToDisk(quiet, diskConfig)
148152
}
153+
if p.bustCache {
154+
logrus.Debug("Found existing disk image but cache busting is enabled, removing and recreating")
155+
err = os.Remove(diskPath)
156+
if err != nil {
157+
return err
158+
}
159+
return p.bootcInstallImageToDisk(quiet, diskConfig)
160+
}
161+
149162
logrus.Debug("Found existing disk image, comparing digest")
150163
defer f.Close()
151164
buf := make([]byte, 4096)
152165
len, err := unix.Fgetxattr(int(f.Fd()), imageMetaXattr, buf)
153166
if err != nil {
154167
// If there's no xattr, just remove it
155-
os.Remove(diskPath)
168+
err = os.Remove(diskPath)
169+
if err != nil {
170+
return err
171+
}
156172
logrus.Debugf("No %s xattr found", imageMetaXattr)
157173
return p.bootcInstallImageToDisk(quiet, diskConfig)
158174
}

podman-bootc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func cleanup() {
5959
}
6060

6161
//delete the disk image
62-
err = bootc.NewBootcDisk(container.ContainerImage{}, ctx, user, cache.Cache{}).Cleanup()
62+
err = bootc.NewBootcDisk(container.ContainerImage{}, ctx, user, cache.Cache{}, false).Cleanup()
6363
if err != nil {
6464
logrus.Errorf("unable to get podman machine info: %s", err)
6565
os.Exit(0)

test/e2e/e2e_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,62 @@ var _ = Describe("E2E", func() {
315315
}
316316
})
317317
})
318+
319+
320+
Context("Modifying disk size", Ordered, func() {
321+
var vm *e2e.TestVM
322+
323+
BeforeAll(func() {
324+
var err error
325+
vm, err = e2e.BootVM(e2e.BaseImage, "--disk-size", "25G")
326+
Expect(err).To(Not(HaveOccurred()))
327+
})
328+
329+
It("Should create a new VM with a specific disk size", func() {
330+
vmDirs, err := e2e.ListCacheDirs()
331+
Expect(err).To(Not(HaveOccurred()))
332+
Expect(vmDirs).To(HaveLen(1))
333+
334+
fileInfo, err := os.Stat(filepath.Join(vmDirs[0], config.DiskImage))
335+
Expect(err).To(Not(HaveOccurred()))
336+
337+
Expect(fileInfo.Size()).To(Equal(int64(25000001536)))
338+
})
339+
340+
It("Should fail to resize a VM's disk size while the VM is running", func() {
341+
_, _, err := e2e.RunPodmanBootc("run", e2e.BaseImage, "--disk-size", "26G")
342+
Expect(err).To(HaveOccurred())
343+
})
344+
345+
It("Should resize an existing VM's disk size", func() {
346+
//stop the VM first
347+
err := vm.StdIn.Close()
348+
Expect(err).To(Not(HaveOccurred()))
349+
_, _, err = e2e.RunPodmanBootc("stop", vm.Id)
350+
Expect(err).To(Not(HaveOccurred()))
351+
352+
Eventually(func() bool {
353+
vmExists, err := e2e.VMExists(vm.Id)
354+
Expect(err).To(Not(HaveOccurred()))
355+
return vmExists
356+
}).Should(BeFalse())
357+
358+
//resize the disk
359+
vm, err = e2e.BootVM(e2e.BaseImage, "--disk-size", "27G")
360+
Expect(err).To(Not(HaveOccurred()))
361+
362+
//verify the disk size
363+
vmDirs, err := e2e.ListCacheDirs()
364+
Expect(err).To(Not(HaveOccurred()))
365+
Expect(vmDirs).To(HaveLen(1))
366+
fileInfo, err := os.Stat(filepath.Join(vmDirs[0], config.DiskImage))
367+
Expect(err).To(Not(HaveOccurred()))
368+
Expect(fileInfo.Size()).To(Equal(int64(27000000512)))
369+
})
370+
371+
AfterAll(func() {
372+
vm.StdIn.Close()
373+
e2e.Cleanup()
374+
})
375+
})
318376
})

test/e2e/e2e_utils.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ func GetVMIdFromContainerImage(image string) (vmId string, err error) {
105105
return
106106
}
107107

108-
func BootVM(image string) (vm *TestVM, err error) {
109-
runActiveCmd := exec.Command(PodmanBootcBinary(), "run", image)
108+
func BootVM(image string, args ...string) (vm *TestVM, err error) {
109+
cmd := []string{"run", image}
110+
cmd = append(cmd, args...)
111+
runActiveCmd := exec.Command(PodmanBootcBinary(), cmd...)
110112
stdIn, err := runActiveCmd.StdinPipe()
111113

112114
if err != nil {

0 commit comments

Comments
 (0)