@@ -13,6 +13,7 @@ import (
13
13
"strings"
14
14
15
15
"github.com/containers/podman/v5/pkg/bindings"
16
+ "github.com/containers/podman/v5/pkg/domain/entities"
16
17
"github.com/containers/podman/v5/pkg/machine/define"
17
18
"github.com/containers/podman/v5/pkg/machine/env"
18
19
"github.com/containers/podman/v5/pkg/machine/provider"
@@ -25,44 +26,46 @@ import (
25
26
// FindMachineByPort finds a running machine that matches the given connection port.
26
27
// It returns the machine configuration and provider, or an error if not found.
27
28
func FindMachineByPort (connectionURI string , parsedConnection * url.URL ) (* vmconfigs.MachineConfig , vmconfigs.VMProvider , error ) {
28
- machineProvider , err := provider .Get ()
29
- if err != nil {
30
- return nil , nil , fmt .Errorf ("getting machine provider: %w" , err )
31
- }
32
-
33
- dirs , err := env .GetMachineDirs (machineProvider .VMType ())
34
- if err != nil {
35
- return nil , nil , err
36
- }
37
-
38
- machineList , err := vmconfigs .LoadMachinesInDir (dirs )
39
- if err != nil {
40
- return nil , nil , fmt .Errorf ("listing machines: %w" , err )
41
- }
42
-
43
- // Now we know that the connection points to a machine and we
44
- // can find the machine by looking for the one with the
45
- // matching port.
46
- connectionPort , err := strconv .Atoi (parsedConnection .Port ())
47
- if err != nil {
48
- return nil , nil , fmt .Errorf ("parsing connection port: %w" , err )
49
- }
50
-
51
- for _ , mc := range machineList {
52
- if connectionPort != mc .SSH .Port {
29
+ for _ , machineProvider := range provider .GetAll () {
30
+ logrus .Debugf ("Checking provider: %s" , machineProvider .VMType ())
31
+ dirs , err := env .GetMachineDirs (machineProvider .VMType ())
32
+ if err != nil {
33
+ logrus .Debugf ("Failed to get machine dirs for provider %s: %v" , machineProvider .VMType (), err )
53
34
continue
54
35
}
55
36
56
- state , err := machineProvider . State ( mc , false )
37
+ machineList , err := vmconfigs . LoadMachinesInDir ( dirs )
57
38
if err != nil {
58
- return nil , nil , err
39
+ logrus .Debugf ("Failed to list machines: %v" , err )
40
+ continue
59
41
}
60
42
61
- if state != define .Running {
62
- return nil , nil , fmt .Errorf ("machine %s is not running but in state %s" , mc .Name , state )
43
+ // Now we know that the connection points to a machine and we
44
+ // can find the machine by looking for the one with the
45
+ // matching port.
46
+ connectionPort , err := strconv .Atoi (parsedConnection .Port ())
47
+ if err != nil {
48
+ logrus .Debugf ("Failed to parse connection port: %v" , err )
49
+ continue
63
50
}
64
51
65
- return mc , machineProvider , nil
52
+ for _ , mc := range machineList {
53
+ if connectionPort != mc .SSH .Port {
54
+ continue
55
+ }
56
+
57
+ state , err := machineProvider .State (mc , false )
58
+ if err != nil {
59
+ logrus .Debugf ("Failed to get machine state for %s: %v" , mc .Name , err )
60
+ continue
61
+ }
62
+
63
+ if state != define .Running {
64
+ return nil , nil , fmt .Errorf ("machine %s is not running but in state %s" , mc .Name , state )
65
+ }
66
+
67
+ return mc , machineProvider , nil
68
+ }
66
69
}
67
70
68
71
return nil , nil , fmt .Errorf ("could not find a matching machine for connection %q" , connectionURI )
@@ -154,3 +157,113 @@ func CheckPathOnRunningMachine(ctx context.Context, path string) (*LocalAPIMap,
154
157
155
158
return isPathAvailableOnMachine (mounts , vmType , path )
156
159
}
160
+
161
+ // CheckIfImageBuildPathsOnRunningMachine checks if the build context directory and all specified
162
+ // Containerfiles are available on the running machine. If they are, it translates their paths
163
+ // to the corresponding remote paths and returns them along with a flag indicating success.
164
+ func CheckIfImageBuildPathsOnRunningMachine (ctx context.Context , containerFiles []string , options entities.BuildOptions ) ([]string , entities.BuildOptions , bool ) {
165
+ if machineMode := bindings .GetMachineMode (ctx ); ! machineMode {
166
+ logrus .Debug ("Machine mode is not enabled, skipping machine check" )
167
+ return nil , options , false
168
+ }
169
+
170
+ conn , err := bindings .GetClient (ctx )
171
+ if err != nil {
172
+ logrus .Debugf ("Failed to get client connection: %v" , err )
173
+ return nil , options , false
174
+ }
175
+
176
+ mounts , vmType , err := getMachineMountsAndVMType (conn .URI .String (), conn .URI )
177
+ if err != nil {
178
+ logrus .Debugf ("Failed to get machine mounts: %v" , err )
179
+ return nil , options , false
180
+ }
181
+
182
+ // Context directory
183
+ if err := fileutils .Lexists (options .ContextDirectory ); errors .Is (err , fs .ErrNotExist ) {
184
+ logrus .Debugf ("Path %s does not exist locally, skipping machine check" , options .ContextDirectory )
185
+ return nil , options , false
186
+ }
187
+ mapping , found := isPathAvailableOnMachine (mounts , vmType , options .ContextDirectory )
188
+ if ! found {
189
+ logrus .Debugf ("Path %s is not available on the running machine" , options .ContextDirectory )
190
+ return nil , options , false
191
+ }
192
+ options .ContextDirectory = mapping .RemotePath
193
+
194
+ // Containerfiles
195
+ translatedContainerFiles := []string {}
196
+ for _ , containerFile := range containerFiles {
197
+ if strings .HasPrefix (containerFile , "http://" ) || strings .HasPrefix (containerFile , "https://" ) {
198
+ translatedContainerFiles = append (translatedContainerFiles , containerFile )
199
+ continue
200
+ }
201
+
202
+ // If Containerfile does not exist, assume it is in context directory
203
+ if err := fileutils .Lexists (containerFile ); err != nil {
204
+ if ! errors .Is (err , fs .ErrNotExist ) {
205
+ logrus .Fatalf ("Failed to check if containerfile %s exists: %v" , containerFile , err )
206
+ return nil , options , false
207
+ }
208
+ continue
209
+ }
210
+
211
+ mapping , found := isPathAvailableOnMachine (mounts , vmType , containerFile )
212
+ if ! found {
213
+ logrus .Debugf ("Path %s is not available on the running machine" , containerFile )
214
+ return nil , options , false
215
+ }
216
+ translatedContainerFiles = append (translatedContainerFiles , mapping .RemotePath )
217
+ }
218
+
219
+ // Additional build contexts
220
+ for _ , context := range options .AdditionalBuildContexts {
221
+ switch {
222
+ case context .IsImage , context .IsURL :
223
+ continue
224
+ default :
225
+ if err := fileutils .Lexists (context .Value ); errors .Is (err , fs .ErrNotExist ) {
226
+ logrus .Debugf ("Path %s does not exist locally, skipping machine check" , context .Value )
227
+ return nil , options , false
228
+ }
229
+ mapping , found := isPathAvailableOnMachine (mounts , vmType , context .Value )
230
+ if ! found {
231
+ logrus .Debugf ("Path %s is not available on the running machine" , context .Value )
232
+ return nil , options , false
233
+ }
234
+ context .Value = mapping .RemotePath
235
+ }
236
+ }
237
+ return translatedContainerFiles , options , true
238
+ }
239
+
240
+ // IsHyperVProvider checks if the current machine provider is Hyper-V.
241
+ // It returns true if the provider is Hyper-V, false otherwise, or an error if the check fails.
242
+ func IsHyperVProvider (ctx context.Context ) (bool , error ) {
243
+ conn , err := bindings .GetClient (ctx )
244
+ if err != nil {
245
+ logrus .Debugf ("Failed to get client connection: %v" , err )
246
+ return false , err
247
+ }
248
+
249
+ _ , vmProvider , err := FindMachineByPort (conn .URI .String (), conn .URI )
250
+ if err != nil {
251
+ logrus .Debugf ("Failed to get machine hypervisor type: %v" , err )
252
+ return false , err
253
+ }
254
+
255
+ return vmProvider .VMType () == define .HyperVVirt , nil
256
+ }
257
+
258
+ // ValidatePathForLocalAPI checks if the provided path satisfies requirements for local API usage.
259
+ // It returns an error if the path is not absolute or does not exist on the filesystem.
260
+ func ValidatePathForLocalAPI (path string ) error {
261
+ if ! filepath .IsAbs (path ) {
262
+ return fmt .Errorf ("path %q is not absolute" , path )
263
+ }
264
+
265
+ if err := fileutils .Exists (path ); err != nil {
266
+ return err
267
+ }
268
+ return nil
269
+ }
0 commit comments