...
1
2 package image
3
4 import (
5 "context"
6 "errors"
7 "os/exec"
8 "path/filepath"
9
10 devfile "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
11 "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
12
13 envcontext "github.com/redhat-developer/odo/pkg/config/context"
14 "github.com/redhat-developer/odo/pkg/libdevfile"
15 "github.com/redhat-developer/odo/pkg/log"
16 odocontext "github.com/redhat-developer/odo/pkg/odo/context"
17 "github.com/redhat-developer/odo/pkg/testingutil/filesystem"
18 )
19
20
21 type Backend interface {
22
23
24 Build(fs filesystem.Filesystem, image *devfile.ImageComponent, devfilePath string) error
25
26 Push(image string) error
27
28 String() string
29 }
30
31 var lookPathCmd = exec.LookPath
32
33
34
35 func BuildPushImages(ctx context.Context, backend Backend, fs filesystem.Filesystem, push bool) error {
36 var (
37 devfileObj = odocontext.GetEffectiveDevfileObj(ctx)
38 devfilePath = odocontext.GetDevfilePath(ctx)
39 path = filepath.Dir(devfilePath)
40 )
41
42 if backend == nil {
43
44 return errors.New("odo requires either Podman or Docker to be installed in your environment. Please install one of them and try again.")
45
46 }
47
48 components, err := devfileObj.Data.GetComponents(common.DevfileOptions{
49 ComponentOptions: common.ComponentOptions{ComponentType: devfile.ImageComponentType},
50 })
51 if err != nil {
52 return err
53 }
54 if len(components) == 0 {
55 return libdevfile.NewComponentTypeNotFoundError(devfile.ImageComponentType)
56 }
57
58 for _, component := range components {
59 err = buildPushImage(backend, fs, component.Image, path, push)
60 if err != nil {
61 return err
62 }
63 }
64 return nil
65 }
66
67
68
69 func BuildPushSpecificImage(ctx context.Context, backend Backend, fs filesystem.Filesystem, component devfile.Component, push bool) error {
70 var (
71 devfilePath = odocontext.GetDevfilePath(ctx)
72 path = filepath.Dir(devfilePath)
73 )
74
75 if backend == nil {
76
77 return errors.New("odo requires either Podman or Docker to be installed in your environment. Please install one of them and try again.")
78
79 }
80
81 return buildPushImage(backend, fs, component.Image, path, push)
82 }
83
84
85
86 func buildPushImage(backend Backend, fs filesystem.Filesystem, image *devfile.ImageComponent, devfilePath string, push bool) error {
87 if image == nil {
88 return errors.New("image should not be nil")
89 }
90 var msg string
91 if push {
92 msg = "Building & Pushing Image: %s"
93 } else {
94 msg = "Building Image: %s"
95 }
96 log.Sectionf(msg, image.ImageName)
97 err := backend.Build(fs, image, devfilePath)
98 if err != nil {
99 return err
100 }
101 if push {
102 err = backend.Push(image.ImageName)
103 if err != nil {
104 return err
105 }
106 }
107 return nil
108 }
109
110
111
112
113 func SelectBackend(ctx context.Context) Backend {
114
115 podmanCmd := envcontext.GetEnvConfig(ctx).PodmanCmd
116 globalExtraArgs := envcontext.GetEnvConfig(ctx).OdoContainerBackendGlobalArgs
117 buildExtraArgs := envcontext.GetEnvConfig(ctx).OdoImageBuildArgs
118 if _, err := lookPathCmd(podmanCmd); err == nil {
119
120
121
122
123
124
125
126
127
128
129
130 if log.IsAppleSilicon() {
131 log.Warning("WARNING: Building images on Apple Silicon / M1 is not (yet) supported natively on Podman")
132 log.Warning("There is however a temporary workaround: https://github.com/containers/podman/discussions/12899")
133 }
134 return NewDockerCompatibleBackend(podmanCmd, globalExtraArgs, buildExtraArgs)
135 }
136
137 dockerCmd := envcontext.GetEnvConfig(ctx).DockerCmd
138 if _, err := lookPathCmd(dockerCmd); err == nil {
139 return NewDockerCompatibleBackend(dockerCmd, globalExtraArgs, buildExtraArgs)
140 }
141 return nil
142 }
143
View as plain text