Skip to content

Commit 8dbd13c

Browse files
committed
simplify code, refactor for better future
1 parent 778352e commit 8dbd13c

12 files changed

Lines changed: 277 additions & 382 deletions

File tree

cmd/core/helpers.go

Lines changed: 46 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,9 @@ func InitBackends(ctx context.Context, conf *config.Config) ([]imagebackend.Imag
8080

8181
// InitImageBackends initializes only image backends (no hypervisor needed).
8282
func InitImageBackends(ctx context.Context, conf *config.Config) ([]imagebackend.Images, error) {
83-
ociStore, err := oci.New(ctx, conf)
84-
if err != nil {
85-
return nil, fmt.Errorf("init oci backend: %w", err)
86-
}
87-
cloudimgStore, err := cloudimg.New(ctx, conf)
83+
ociStore, cloudimgStore, err := InitImageBackendsForPull(ctx, conf)
8884
if err != nil {
89-
return nil, fmt.Errorf("init cloudimg backend: %w", err)
85+
return nil, err
9086
}
9187
return []imagebackend.Images{ociStore, cloudimgStore}, nil
9288
}
@@ -195,48 +191,14 @@ func VMConfigFromFlags(cmd *cobra.Command, image string) (*types.VMConfig, error
195191
// against the snapshot minimums (clone resources must be >= snapshot's).
196192
func CloneVMConfigFromFlags(cmd *cobra.Command, snapCfg *types.SnapshotConfig) (*types.VMConfig, error) {
197193
vmName, _ := cmd.Flags().GetString("name")
198-
cpu, _ := cmd.Flags().GetInt("cpu")
199-
memStr, _ := cmd.Flags().GetString("memory")
200-
storStr, _ := cmd.Flags().GetString("storage")
201194
network, _ := cmd.Flags().GetString("network")
202195
if network == "" {
203196
network = snapCfg.Network
204197
}
205198

206-
if cpu == 0 {
207-
cpu = snapCfg.CPU
208-
}
209-
210-
var memBytes int64
211-
if memStr == "" {
212-
memBytes = snapCfg.Memory
213-
} else {
214-
var err error
215-
memBytes, err = units.RAMInBytes(memStr)
216-
if err != nil {
217-
return nil, fmt.Errorf("invalid --memory %q: %w", memStr, err)
218-
}
219-
}
220-
221-
var storBytes int64
222-
if storStr == "" {
223-
storBytes = snapCfg.Storage
224-
} else {
225-
var err error
226-
storBytes, err = units.RAMInBytes(storStr)
227-
if err != nil {
228-
return nil, fmt.Errorf("invalid --storage %q: %w", storStr, err)
229-
}
230-
}
231-
232-
if cpu < snapCfg.CPU {
233-
return nil, fmt.Errorf("--cpu %d below snapshot minimum %d", cpu, snapCfg.CPU)
234-
}
235-
if memBytes < snapCfg.Memory {
236-
return nil, fmt.Errorf("--memory %s below snapshot minimum %s", FormatSize(memBytes), FormatSize(snapCfg.Memory))
237-
}
238-
if storBytes < snapCfg.Storage {
239-
return nil, fmt.Errorf("--storage %s below snapshot minimum %s", FormatSize(storBytes), FormatSize(snapCfg.Storage))
199+
cpu, memBytes, storBytes, err := mergeResourceFlags(cmd, snapCfg.CPU, snapCfg.Memory, snapCfg.Storage, snapCfg)
200+
if err != nil {
201+
return nil, err
240202
}
241203

242204
cfg := &types.VMConfig{
@@ -258,39 +220,15 @@ func CloneVMConfigFromFlags(cmd *cobra.Command, snapCfg *types.SnapshotConfig) (
258220
// Keeps VM's current values by default; CLI flags override.
259221
// Validates that final values are >= snapshot minimums.
260222
func RestoreVMConfigFromFlags(cmd *cobra.Command, vm *types.VM, snapCfg *types.SnapshotConfig) (*types.VMConfig, error) {
261-
cpu, _ := cmd.Flags().GetInt("cpu")
262-
memStr, _ := cmd.Flags().GetString("memory")
263-
storStr, _ := cmd.Flags().GetString("storage")
264-
265223
result := vm.Config // value copy — keep current VM values
266224

267-
if cpu > 0 {
268-
result.CPU = cpu
269-
}
270-
if memStr != "" {
271-
memBytes, err := units.RAMInBytes(memStr)
272-
if err != nil {
273-
return nil, fmt.Errorf("invalid --memory %q: %w", memStr, err)
274-
}
275-
result.Memory = memBytes
276-
}
277-
if storStr != "" {
278-
storBytes, err := units.RAMInBytes(storStr)
279-
if err != nil {
280-
return nil, fmt.Errorf("invalid --storage %q: %w", storStr, err)
281-
}
282-
result.Storage = storBytes
283-
}
284-
285-
if result.CPU < snapCfg.CPU {
286-
return nil, fmt.Errorf("--cpu %d below snapshot minimum %d", result.CPU, snapCfg.CPU)
287-
}
288-
if result.Memory < snapCfg.Memory {
289-
return nil, fmt.Errorf("--memory %s below snapshot minimum %s", FormatSize(result.Memory), FormatSize(snapCfg.Memory))
290-
}
291-
if result.Storage < snapCfg.Storage {
292-
return nil, fmt.Errorf("--storage %s below snapshot minimum %s", FormatSize(result.Storage), FormatSize(snapCfg.Storage))
225+
cpu, memBytes, storBytes, err := mergeResourceFlags(cmd, result.CPU, result.Memory, result.Storage, snapCfg)
226+
if err != nil {
227+
return nil, err
293228
}
229+
result.CPU = cpu
230+
result.Memory = memBytes
231+
result.Storage = storBytes
294232

295233
return &result, nil
296234
}
@@ -378,3 +316,38 @@ func sanitizeVMName(image string) string {
378316
}
379317
return n
380318
}
319+
320+
func mergeResourceFlags(cmd *cobra.Command, cpu int, memory, storage int64, snapCfg *types.SnapshotConfig) (int, int64, int64, error) {
321+
cpuFlag, _ := cmd.Flags().GetInt("cpu")
322+
memStr, _ := cmd.Flags().GetString("memory")
323+
storStr, _ := cmd.Flags().GetString("storage")
324+
325+
if cpuFlag > 0 {
326+
cpu = cpuFlag
327+
}
328+
if memStr != "" {
329+
v, err := units.RAMInBytes(memStr)
330+
if err != nil {
331+
return 0, 0, 0, fmt.Errorf("invalid --memory %q: %w", memStr, err)
332+
}
333+
memory = v
334+
}
335+
if storStr != "" {
336+
v, err := units.RAMInBytes(storStr)
337+
if err != nil {
338+
return 0, 0, 0, fmt.Errorf("invalid --storage %q: %w", storStr, err)
339+
}
340+
storage = v
341+
}
342+
343+
if cpu < snapCfg.CPU {
344+
return 0, 0, 0, fmt.Errorf("--cpu %d below snapshot minimum %d", cpu, snapCfg.CPU)
345+
}
346+
if memory < snapCfg.Memory {
347+
return 0, 0, 0, fmt.Errorf("--memory %s below snapshot minimum %s", FormatSize(memory), FormatSize(snapCfg.Memory))
348+
}
349+
if storage < snapCfg.Storage {
350+
return 0, 0, 0, fmt.Errorf("--storage %s below snapshot minimum %s", FormatSize(storage), FormatSize(snapCfg.Storage))
351+
}
352+
return cpu, memory, storage, nil
353+
}

cmd/vm/handler.go

Lines changed: 64 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -213,26 +213,6 @@ func (h Handler) Start(cmd *cobra.Command, args []string) error {
213213
return batchVMCmd(ctx, "start", "started", hyper.Start, args)
214214
}
215215

216-
// recoverNetwork recreates the network namespace and TC redirect for VMs
217-
// whose netns was lost (e.g. after host reboot). Best-effort: failures are
218-
// logged but do not block start — hyper.Start will report the real error.
219-
func (h Handler) recoverNetwork(ctx context.Context, hyper hypervisor.Hypervisor, net network.Network, refs []string) {
220-
logger := log.WithFunc("cmd.recoverNetwork")
221-
for _, ref := range refs {
222-
vm, err := hyper.Inspect(ctx, ref)
223-
if err != nil || vm == nil || len(vm.NetworkConfigs) == 0 {
224-
continue
225-
}
226-
if net.Verify(ctx, vm.ID) == nil {
227-
continue // netns exists, no recovery needed
228-
}
229-
logger.Warnf(ctx, "netns missing for VM %s, recovering network", vm.ID)
230-
if _, recoverErr := net.Config(ctx, vm.ID, len(vm.NetworkConfigs), &vm.Config, vm.NetworkConfigs...); recoverErr != nil {
231-
logger.Warnf(ctx, "recover network for VM %s: %v (start will fail)", vm.ID, recoverErr)
232-
}
233-
}
234-
}
235-
236216
func (h Handler) Stop(cmd *cobra.Command, args []string) error {
237217
ctx, conf, err := h.Init(cmd)
238218
if err != nil {
@@ -498,14 +478,30 @@ func (h Handler) Debug(cmd *cobra.Command, args []string) error {
498478
balloon = memoryMB / 2 //nolint:mnd
499479
}
500480

501-
if boot.KernelPath != "" {
502-
printRunOCI(storageConfigs, boot, vmCfg.Name, vmCfg.Image, cowPath, chBin, vmCfg.CPU, maxCPU, memoryMB, balloon, cowSizeGB, vmCfg.Windows)
503-
} else {
504-
printRunCloudimg(storageConfigs, boot, vmCfg.Name, vmCfg.Image, cowPath, chBin, vmCfg.CPU, maxCPU, memoryMB, balloon, cowSizeGB, vmCfg.Windows)
505-
}
481+
printDebugRun(storageConfigs, boot, vmCfg.Name, vmCfg.Image, cowPath, chBin, vmCfg.CPU, maxCPU, memoryMB, balloon, cowSizeGB, vmCfg.Windows, boot.KernelPath != "")
506482
return nil
507483
}
508484

485+
// recoverNetwork recreates the network namespace and TC redirect for VMs
486+
// whose netns was lost (e.g. after host reboot). Best-effort: failures are
487+
// logged but do not block start — hyper.Start will report the real error.
488+
func (h Handler) recoverNetwork(ctx context.Context, hyper hypervisor.Hypervisor, net network.Network, refs []string) {
489+
logger := log.WithFunc("cmd.recoverNetwork")
490+
for _, ref := range refs {
491+
vm, err := hyper.Inspect(ctx, ref)
492+
if err != nil || vm == nil || len(vm.NetworkConfigs) == 0 {
493+
continue
494+
}
495+
if net.Verify(ctx, vm.ID) == nil {
496+
continue // netns exists, no recovery needed
497+
}
498+
logger.Warnf(ctx, "netns missing for VM %s, recovering network", vm.ID)
499+
if _, recoverErr := net.Config(ctx, vm.ID, len(vm.NetworkConfigs), &vm.Config, vm.NetworkConfigs...); recoverErr != nil {
500+
logger.Warnf(ctx, "recover network for VM %s: %v (start will fail)", vm.ID, recoverErr)
501+
}
502+
}
503+
}
504+
509505
// initHyper is the shared init for methods that only need the hypervisor.
510506
func (h Handler) initHyper(cmd *cobra.Command) (context.Context, hypervisor.Hypervisor, error) {
511507
ctx, conf, err := h.Init(cmd)
@@ -733,59 +729,57 @@ func printBashArray(name string, nics []nicHint, field func(nicHint) string) {
733729
fmt.Println(")")
734730
}
735731

736-
func printRunOCI(configs []*types.StorageConfig, boot *types.BootConfig, vmName, image, cowPath, chBin string, cpu, maxCPU, memory, balloon, cowSize int, windows bool) {
737-
if cowPath == "" {
738-
cowPath = fmt.Sprintf("cow-%s.raw", vmName)
739-
}
740-
741-
debugConfigs := append(append([]*types.StorageConfig(nil), configs...),
742-
&types.StorageConfig{Path: cowPath, RO: false, Serial: cloudhypervisor.CowSerial})
743-
diskArgs := cloudhypervisor.DebugDiskCLIArgs(debugConfigs, cpu)
732+
func printDebugRun(configs []*types.StorageConfig, boot *types.BootConfig, vmName, image, cowPath, chBin string, cpu, maxCPU, memory, balloon, cowSize int, windows, directBoot bool) {
733+
if directBoot {
734+
if cowPath == "" {
735+
cowPath = fmt.Sprintf("cow-%s.raw", vmName)
736+
}
744737

745-
cocoonLayers := strings.Join(cloudhypervisor.ReverseLayerSerials(configs), ",")
738+
debugConfigs := append(append([]*types.StorageConfig(nil), configs...),
739+
&types.StorageConfig{Path: cowPath, RO: false, Serial: cloudhypervisor.CowSerial})
740+
diskArgs := cloudhypervisor.DebugDiskCLIArgs(debugConfigs, cpu)
746741

747-
cmdline := fmt.Sprintf(
748-
"console=hvc0 loglevel=3 boot=cocoon-overlay cocoon.layers=%s cocoon.cow=%s clocksource=kvm-clock rw",
749-
cocoonLayers, cloudhypervisor.CowSerial)
742+
cocoonLayers := strings.Join(cloudhypervisor.ReverseLayerSerials(configs), ",")
743+
cmdline := fmt.Sprintf(
744+
"console=hvc0 loglevel=3 boot=cocoon-overlay cocoon.layers=%s cocoon.cow=%s clocksource=kvm-clock rw",
745+
cocoonLayers, cloudhypervisor.CowSerial)
750746

751-
fmt.Println("# Prepare COW disk")
752-
fmt.Printf("truncate -s %dG %s\n", cowSize, cowPath)
753-
fmt.Printf("mkfs.ext4 -F -m 0 -q -E lazy_itable_init=1,lazy_journal_init=1,discard %s\n", cowPath)
754-
fmt.Println()
747+
fmt.Println("# Prepare COW disk")
748+
fmt.Printf("truncate -s %dG %s\n", cowSize, cowPath)
749+
fmt.Printf("mkfs.ext4 -F -m 0 -q -E lazy_itable_init=1,lazy_journal_init=1,discard %s\n", cowPath)
750+
fmt.Println()
755751

756-
fmt.Printf("# Launch VM: %s (image: %s, boot: direct kernel)\n", vmName, image)
757-
fmt.Printf("%s \\\n", chBin)
758-
fmt.Printf(" --kernel %s \\\n", boot.KernelPath)
759-
fmt.Printf(" --initramfs %s \\\n", boot.InitrdPath)
760-
fmt.Printf(" --disk")
761-
for _, d := range diskArgs {
762-
fmt.Printf(" \\\n \"%s\"", d)
763-
}
764-
fmt.Printf(" \\\n")
765-
fmt.Printf(" --cmdline \"%s\" \\\n", cmdline)
766-
printCommonCHArgs(cpu, maxCPU, memory, balloon, windows)
767-
}
752+
fmt.Printf("# Launch VM: %s (image: %s, boot: direct kernel)\n", vmName, image)
753+
fmt.Printf("%s \\\n", chBin)
754+
fmt.Printf(" --kernel %s \\\n", boot.KernelPath)
755+
fmt.Printf(" --initramfs %s \\\n", boot.InitrdPath)
756+
fmt.Printf(" --disk")
757+
for _, d := range diskArgs {
758+
fmt.Printf(" \\\n \"%s\"", d)
759+
}
760+
fmt.Printf(" \\\n")
761+
fmt.Printf(" --cmdline \"%s\" \\\n", cmdline)
762+
} else {
763+
if cowPath == "" {
764+
cowPath = fmt.Sprintf("cow-%s.qcow2", vmName)
765+
}
768766

769-
func printRunCloudimg(configs []*types.StorageConfig, boot *types.BootConfig, vmName, image, cowPath, chBin string, cpu, maxCPU, memory, balloon, cowSize int, windows bool) {
770-
if cowPath == "" {
771-
cowPath = fmt.Sprintf("cow-%s.qcow2", vmName)
772-
}
767+
basePath := configs[0].Path
773768

774-
basePath := configs[0].Path
769+
fmt.Println("# Prepare COW overlay")
770+
fmt.Printf("qemu-img create -f qcow2 -F qcow2 -b %s %s\n", basePath, cowPath)
771+
if cowSize > 0 {
772+
fmt.Printf("qemu-img resize %s %dG\n", cowPath, cowSize)
773+
}
774+
fmt.Println()
775775

776-
fmt.Println("# Prepare COW overlay")
777-
fmt.Printf("qemu-img create -f qcow2 -F qcow2 -b %s %s\n", basePath, cowPath)
778-
if cowSize > 0 {
779-
fmt.Printf("qemu-img resize %s %dG\n", cowPath, cowSize)
776+
fmt.Printf("# Launch VM: %s (image: %s, boot: UEFI firmware)\n", vmName, image)
777+
fmt.Printf("%s \\\n", chBin)
778+
fmt.Printf(" --firmware %s \\\n", boot.FirmwarePath)
779+
fmt.Printf(" --disk \\\n")
780+
diskArgs := cloudhypervisor.DebugDiskCLIArgs([]*types.StorageConfig{{Path: cowPath, RO: false}}, cpu)
781+
fmt.Printf(" \"%s\" \\\n", diskArgs[0])
780782
}
781-
fmt.Println()
782-
783-
fmt.Printf("# Launch VM: %s (image: %s, boot: UEFI firmware)\n", vmName, image)
784-
fmt.Printf("%s \\\n", chBin)
785-
fmt.Printf(" --firmware %s \\\n", boot.FirmwarePath)
786-
fmt.Printf(" --disk \\\n")
787-
diskArgs := cloudhypervisor.DebugDiskCLIArgs([]*types.StorageConfig{{Path: cowPath, RO: false}}, cpu)
788-
fmt.Printf(" \"%s\" \\\n", diskArgs[0])
789783
printCommonCHArgs(cpu, maxCPU, memory, balloon, windows)
790784
}
791785

0 commit comments

Comments
 (0)