Skip to content

Commit 7320451

Browse files
committed
separate noop into OS specific code
noop contains funcs that are specific to different OS. This commit creates OS specific noop file that implements their logic. This cleans the noop file of all switches/if. This is a simple refactor, no logic is changed Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
1 parent fe965ad commit 7320451

File tree

4 files changed

+139
-112
lines changed

4 files changed

+139
-112
lines changed

pkg/imagepullers/noop.go

Lines changed: 3 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,13 @@ package imagepullers
22

33
import (
44
"bufio"
5-
"errors"
65
"fmt"
76
"io"
87
"os"
9-
"os/exec"
10-
"path/filepath"
11-
12-
"github.com/sirupsen/logrus"
138

149
"github.com/containers/podman/v5/pkg/machine/define"
1510

1611
"github.com/containers/podman/v5/pkg/machine/env"
17-
18-
"github.com/lima-vm/go-qcow2reader"
19-
"github.com/lima-vm/go-qcow2reader/convert"
20-
"github.com/lima-vm/go-qcow2reader/image"
21-
"github.com/lima-vm/go-qcow2reader/image/qcow2"
22-
"github.com/lima-vm/go-qcow2reader/image/raw"
2312
)
2413

2514
type NoopImagePuller struct {
@@ -40,21 +29,6 @@ func (puller *NoopImagePuller) SetSourceURI(sourcePath string) {
4029
puller.sourceURI = sourcePath
4130
}
4231

43-
func imageExtension(vmType define.VMType, sourceURI string) string {
44-
switch vmType {
45-
case define.WSLVirt:
46-
ext := filepath.Ext(sourceURI)
47-
if ext == ".wsl" {
48-
return ".wsl"
49-
}
50-
return ".tar.gz"
51-
case define.QemuVirt, define.HyperVVirt:
52-
return filepath.Ext(sourceURI)
53-
default:
54-
return "." + vmType.ImageFormat().Kind()
55-
}
56-
}
57-
5832
func (puller *NoopImagePuller) LocalPath() (*define.VMFile, error) {
5933
// if localPath has already been calculated returns it
6034
if puller.localPath != nil {
@@ -85,97 +59,14 @@ func (puller *NoopImagePuller) Download() error {
8559
if err != nil {
8660
return err
8761
}
88-
return doCopyFile(puller.sourceURI, localPath.Path, puller.vmType)
89-
}
90-
91-
func doCopyFile(src, dest string, vmType define.VMType) error {
92-
srcF, err := os.Open(src)
93-
if err != nil {
94-
return err
95-
}
96-
defer srcF.Close()
97-
98-
switch vmType {
99-
case define.AppleHvVirt, define.LibKrun:
100-
return copyFileMac(srcF, dest)
101-
case define.WSLVirt, define.HyperVVirt:
102-
return copyFileWin(srcF, dest)
103-
default:
104-
return copyFile(srcF, dest)
105-
}
106-
}
107-
108-
func copyFileMac(src *os.File, dest string) error {
109-
srcImg, err := qcow2reader.Open(src)
110-
if err != nil {
111-
return err
112-
}
113-
defer srcImg.Close()
114-
115-
switch srcImg.Type() {
116-
case raw.Type:
117-
// if the image is raw it performs a simple copy
118-
return copyFile(src, dest)
119-
case qcow2.Type:
120-
// if the image is qcow2 it performs a conversion to raw
121-
return convertToRaw(srcImg, dest)
122-
default:
123-
return fmt.Errorf("%s format not supported for conversion to raw", srcImg.Type())
124-
}
125-
}
126-
127-
func copyFileWin(srcF *os.File, dest string) error {
128-
binary, err := exec.LookPath("robocopy")
129-
if err != nil {
130-
logrus.Debugf("warning: failed to get robocopy binary: %v. Falling back to default file copy between %s and %s\n", err, srcF.Name(), dest)
131-
return copyFile(srcF, dest)
132-
}
133-
134-
srcDir, srcFile := filepath.Split(srcF.Name())
135-
destDir := filepath.Dir(dest)
136-
137-
cmd := exec.Command(binary, "/J", "/MT", "/R:0", srcDir, destDir, srcFile)
138-
if logrus.IsLevelEnabled(logrus.DebugLevel) {
139-
cmd.Stdout = os.Stdout
140-
cmd.Stderr = os.Stderr
141-
}
142-
143-
err = cmd.Run()
144-
if err != nil {
145-
// robocopy does not use classic exit codes like linux commands, so we need to check for specific errors
146-
// Only exit code 8 is considered an error, all other exit codes are considered successful with exceptions
147-
// see https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy
148-
var exitErr *exec.ExitError
149-
if errors.As(err, &exitErr) {
150-
exitCode := exitErr.ExitCode()
151-
if exitCode >= 8 {
152-
return fmt.Errorf("failed to run robocopy: %w", err)
153-
}
154-
} else {
155-
return fmt.Errorf("failed to run robocopy: %w", err)
156-
}
157-
}
15862

159-
err = os.Rename(filepath.Join(destDir, srcFile), dest)
160-
if err != nil {
161-
return fmt.Errorf("failed to rename file: %w", err)
162-
}
163-
164-
return nil
165-
}
166-
167-
func convertToRaw(srcImg image.Image, dest string) error {
168-
destF, err := os.Create(dest)
63+
src, err := os.Open(puller.sourceURI)
16964
if err != nil {
17065
return err
17166
}
172-
defer destF.Close()
173-
174-
if err := srcImg.Readable(); err != nil {
175-
return fmt.Errorf("source image is not readable: %w", err)
176-
}
67+
defer src.Close()
17768

178-
return convert.Convert(destF, srcImg, convert.Options{})
69+
return doCopyFile(src, localPath.Path)
17970
}
18071

18172
func copyFile(src *os.File, dest string) error {

pkg/imagepullers/noop_darwin.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//go:build darwin
2+
3+
package imagepullers
4+
5+
import (
6+
"fmt"
7+
"os"
8+
9+
"github.com/containers/podman/v5/pkg/machine/define"
10+
11+
"github.com/lima-vm/go-qcow2reader"
12+
"github.com/lima-vm/go-qcow2reader/convert"
13+
"github.com/lima-vm/go-qcow2reader/image"
14+
"github.com/lima-vm/go-qcow2reader/image/qcow2"
15+
"github.com/lima-vm/go-qcow2reader/image/raw"
16+
)
17+
18+
func imageExtension(vmType define.VMType, _ string) string {
19+
return "." + vmType.ImageFormat().Kind()
20+
}
21+
22+
func doCopyFile(src *os.File, dest string) error {
23+
srcImg, err := qcow2reader.Open(src)
24+
if err != nil {
25+
return err
26+
}
27+
defer srcImg.Close()
28+
29+
switch srcImg.Type() {
30+
case raw.Type:
31+
return copyFile(src, dest)
32+
case qcow2.Type:
33+
return convertToRaw(srcImg, dest)
34+
default:
35+
return fmt.Errorf("%s format not supported for conversion to raw", srcImg.Type())
36+
}
37+
}
38+
39+
func convertToRaw(srcImg image.Image, dest string) error {
40+
destF, err := os.Create(dest)
41+
if err != nil {
42+
return err
43+
}
44+
defer destF.Close()
45+
46+
if err := srcImg.Readable(); err != nil {
47+
return fmt.Errorf("source image is not readable: %w", err)
48+
}
49+
50+
return convert.Convert(destF, srcImg, convert.Options{})
51+
}

pkg/imagepullers/noop_unix.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//go:build !windows && !darwin
2+
3+
package imagepullers
4+
5+
import (
6+
"os"
7+
"path/filepath"
8+
9+
"github.com/containers/podman/v5/pkg/machine/define"
10+
)
11+
12+
func imageExtension(_ define.VMType, sourceURI string) string {
13+
return filepath.Ext(sourceURI)
14+
}
15+
16+
func doCopyFile(src *os.File, dest string) error {
17+
return copyFile(src, dest)
18+
}

pkg/imagepullers/noop_windows.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//go:build windows
2+
3+
package imagepullers
4+
5+
import (
6+
"errors"
7+
"fmt"
8+
"os"
9+
"os/exec"
10+
"path/filepath"
11+
12+
"github.com/containers/podman/v5/pkg/machine/define"
13+
"github.com/sirupsen/logrus"
14+
)
15+
16+
func imageExtension(vmType define.VMType, sourceURI string) string {
17+
switch vmType {
18+
case define.WSLVirt:
19+
ext := filepath.Ext(sourceURI)
20+
if ext == ".wsl" {
21+
return ".wsl"
22+
}
23+
return ".tar.gz"
24+
default:
25+
return filepath.Ext(sourceURI)
26+
}
27+
}
28+
29+
func doCopyFile(src *os.File, dest string) error {
30+
binary, err := exec.LookPath("robocopy")
31+
if err != nil {
32+
logrus.Debugf("warning: failed to get robocopy binary: %v. Falling back to default file copy between %s and %s\n", err, src.Name(), dest)
33+
return copyFile(src, dest)
34+
}
35+
36+
srcDir, srcFile := filepath.Split(src.Name())
37+
destDir := filepath.Dir(dest)
38+
39+
cmd := exec.Command(binary, "/J", "/MT", "/R:0", srcDir, destDir, srcFile)
40+
if logrus.IsLevelEnabled(logrus.DebugLevel) {
41+
cmd.Stdout = os.Stdout
42+
cmd.Stderr = os.Stderr
43+
}
44+
45+
err = cmd.Run()
46+
if err != nil {
47+
// robocopy does not use classic exit codes like linux commands, so we need to check for specific errors
48+
// Only exit code 8 is considered an error, all other exit codes are considered successful with exceptions
49+
// see https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy
50+
var exitErr *exec.ExitError
51+
if errors.As(err, &exitErr) {
52+
exitCode := exitErr.ExitCode()
53+
if exitCode >= 8 {
54+
return fmt.Errorf("failed to run robocopy: %w", err)
55+
}
56+
} else {
57+
return fmt.Errorf("failed to run robocopy: %w", err)
58+
}
59+
}
60+
61+
err = os.Rename(filepath.Join(destDir, srcFile), dest)
62+
if err != nil {
63+
return fmt.Errorf("failed to rename file: %w", err)
64+
}
65+
66+
return nil
67+
}

0 commit comments

Comments
 (0)