podman

Форк
0
747 строк · 25.9 Кб
1
package buildah
2

3
import (
4
	"context"
5
	"encoding/json"
6
	"fmt"
7
	"os"
8
	"runtime"
9
	"strings"
10
	"time"
11

12
	"github.com/containers/buildah/define"
13
	"github.com/containers/buildah/docker"
14
	internalUtil "github.com/containers/buildah/internal/util"
15
	"github.com/containers/image/v5/manifest"
16
	"github.com/containers/image/v5/pkg/compression"
17
	"github.com/containers/image/v5/transports"
18
	"github.com/containers/image/v5/types"
19
	"github.com/containers/storage/pkg/stringid"
20
	ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
21
	"github.com/sirupsen/logrus"
22
	"golang.org/x/exp/slices"
23
)
24

25
// unmarshalConvertedConfig obtains the config blob of img valid for the wantedManifestMIMEType format
26
// (either as it exists, or converting the image if necessary), and unmarshals it into dest.
27
// NOTE: The MIME type is of the _manifest_, not of the _config_ that is returned.
28
func unmarshalConvertedConfig(ctx context.Context, dest interface{}, img types.Image, wantedManifestMIMEType string) error {
29
	_, actualManifestMIMEType, err := img.Manifest(ctx)
30
	if err != nil {
31
		return fmt.Errorf("getting manifest MIME type for %q: %w", transports.ImageName(img.Reference()), err)
32
	}
33
	if wantedManifestMIMEType != actualManifestMIMEType {
34
		layerInfos := img.LayerInfos()
35
		for i := range layerInfos { // force the "compression" to gzip, which is supported by all of the formats we care about
36
			layerInfos[i].CompressionOperation = types.Compress
37
			layerInfos[i].CompressionAlgorithm = &compression.Gzip
38
		}
39
		updatedImg, err := img.UpdatedImage(ctx, types.ManifestUpdateOptions{
40
			LayerInfos: layerInfos,
41
		})
42
		if err != nil {
43
			return fmt.Errorf("resetting recorded compression for %q: %w", transports.ImageName(img.Reference()), err)
44
		}
45
		secondUpdatedImg, err := updatedImg.UpdatedImage(ctx, types.ManifestUpdateOptions{
46
			ManifestMIMEType: wantedManifestMIMEType,
47
		})
48
		if err != nil {
49
			return fmt.Errorf("converting image %q from %q to %q: %w", transports.ImageName(img.Reference()), actualManifestMIMEType, wantedManifestMIMEType, err)
50
		}
51
		img = secondUpdatedImg
52
	}
53
	config, err := img.ConfigBlob(ctx)
54
	if err != nil {
55
		return fmt.Errorf("reading %s config from %q: %w", wantedManifestMIMEType, transports.ImageName(img.Reference()), err)
56
	}
57
	if err := json.Unmarshal(config, dest); err != nil {
58
		return fmt.Errorf("parsing %s configuration %q from %q: %w", wantedManifestMIMEType, string(config), transports.ImageName(img.Reference()), err)
59
	}
60
	return nil
61
}
62

63
func (b *Builder) initConfig(ctx context.Context, img types.Image, sys *types.SystemContext) error {
64
	if img != nil { // A pre-existing image, as opposed to a "FROM scratch" new one.
65
		rawManifest, manifestMIMEType, err := img.Manifest(ctx)
66
		if err != nil {
67
			return fmt.Errorf("reading image manifest for %q: %w", transports.ImageName(img.Reference()), err)
68
		}
69
		rawConfig, err := img.ConfigBlob(ctx)
70
		if err != nil {
71
			return fmt.Errorf("reading image configuration for %q: %w", transports.ImageName(img.Reference()), err)
72
		}
73
		b.Manifest = rawManifest
74
		b.Config = rawConfig
75

76
		dimage := docker.V2Image{}
77
		if err := unmarshalConvertedConfig(ctx, &dimage, img, manifest.DockerV2Schema2MediaType); err != nil {
78
			return err
79
		}
80
		b.Docker = dimage
81

82
		oimage := ociv1.Image{}
83
		if err := unmarshalConvertedConfig(ctx, &oimage, img, ociv1.MediaTypeImageManifest); err != nil {
84
			return err
85
		}
86
		b.OCIv1 = oimage
87

88
		if manifestMIMEType == ociv1.MediaTypeImageManifest {
89
			// Attempt to recover format-specific data from the manifest.
90
			v1Manifest := ociv1.Manifest{}
91
			if err := json.Unmarshal(b.Manifest, &v1Manifest); err != nil {
92
				return fmt.Errorf("parsing OCI manifest %q: %w", string(b.Manifest), err)
93
			}
94
			for k, v := range v1Manifest.Annotations {
95
				b.ImageAnnotations[k] = v
96
			}
97
		}
98
	}
99

100
	b.setupLogger()
101
	b.fixupConfig(sys)
102
	return nil
103
}
104

105
func (b *Builder) fixupConfig(sys *types.SystemContext) {
106
	if b.Docker.Config != nil {
107
		// Prefer image-level settings over those from the container it was built from.
108
		b.Docker.ContainerConfig = *b.Docker.Config
109
	}
110
	b.Docker.Config = &b.Docker.ContainerConfig
111
	b.Docker.DockerVersion = ""
112
	now := time.Now().UTC()
113
	if b.Docker.Created.IsZero() {
114
		b.Docker.Created = now
115
	}
116
	if b.OCIv1.Created == nil || b.OCIv1.Created.IsZero() {
117
		b.OCIv1.Created = &now
118
	}
119
	if b.OS() == "" {
120
		if sys != nil && sys.OSChoice != "" {
121
			b.SetOS(sys.OSChoice)
122
		} else {
123
			b.SetOS(runtime.GOOS)
124
		}
125
	}
126
	if b.Architecture() == "" {
127
		if sys != nil && sys.ArchitectureChoice != "" {
128
			b.SetArchitecture(sys.ArchitectureChoice)
129
		} else {
130
			b.SetArchitecture(runtime.GOARCH)
131
		}
132
		// in case the arch string we started with was shorthand for a known arch+variant pair, normalize it
133
		ps := internalUtil.NormalizePlatform(ociv1.Platform{OS: b.OS(), Architecture: b.Architecture(), Variant: b.Variant()})
134
		b.SetArchitecture(ps.Architecture)
135
		b.SetVariant(ps.Variant)
136
	}
137
	if b.Variant() == "" {
138
		if sys != nil && sys.VariantChoice != "" {
139
			b.SetVariant(sys.VariantChoice)
140
		}
141
		// in case the arch string we started with was shorthand for a known arch+variant pair, normalize it
142
		ps := internalUtil.NormalizePlatform(ociv1.Platform{OS: b.OS(), Architecture: b.Architecture(), Variant: b.Variant()})
143
		b.SetArchitecture(ps.Architecture)
144
		b.SetVariant(ps.Variant)
145
	}
146
	if b.Format == define.Dockerv2ImageManifest && b.Hostname() == "" {
147
		b.SetHostname(stringid.TruncateID(stringid.GenerateRandomID()))
148
	}
149
}
150

151
func (b *Builder) setupLogger() {
152
	if b.Logger == nil {
153
		b.Logger = logrus.New()
154
		b.Logger.SetOutput(os.Stderr)
155
		b.Logger.SetLevel(logrus.GetLevel())
156
	}
157
}
158

159
// Annotations returns a set of key-value pairs from the image's manifest.
160
func (b *Builder) Annotations() map[string]string {
161
	return copyStringStringMap(b.ImageAnnotations)
162
}
163

164
// SetAnnotation adds or overwrites a key's value from the image's manifest.
165
// Note: this setting is not present in the Docker v2 image format, so it is
166
// discarded when writing images using Docker v2 formats.
167
func (b *Builder) SetAnnotation(key, value string) {
168
	if b.ImageAnnotations == nil {
169
		b.ImageAnnotations = map[string]string{}
170
	}
171
	b.ImageAnnotations[key] = value
172
}
173

174
// UnsetAnnotation removes a key and its value from the image's manifest, if
175
// it's present.
176
func (b *Builder) UnsetAnnotation(key string) {
177
	delete(b.ImageAnnotations, key)
178
}
179

180
// ClearAnnotations removes all keys and their values from the image's
181
// manifest.
182
func (b *Builder) ClearAnnotations() {
183
	b.ImageAnnotations = map[string]string{}
184
}
185

186
// CreatedBy returns a description of how this image was built.
187
func (b *Builder) CreatedBy() string {
188
	return b.ImageCreatedBy
189
}
190

191
// SetCreatedBy sets the description of how this image was built.
192
func (b *Builder) SetCreatedBy(how string) {
193
	b.ImageCreatedBy = how
194
}
195

196
// OS returns a name of the OS on which the container, or a container built
197
// using an image built from this container, is intended to be run.
198
func (b *Builder) OS() string {
199
	return b.OCIv1.OS
200
}
201

202
// SetOS sets the name of the OS on which the container, or a container built
203
// using an image built from this container, is intended to be run.
204
func (b *Builder) SetOS(os string) {
205
	b.OCIv1.OS = os
206
	b.Docker.OS = os
207
}
208

209
// OSVersion returns a version of the OS on which the container, or a container
210
// built using an image built from this container, is intended to be run.
211
func (b *Builder) OSVersion() string {
212
	return b.OCIv1.OSVersion
213
}
214

215
// SetOSVersion sets the version of the OS on which the container, or a
216
// container built using an image built from this container, is intended to be
217
// run.
218
func (b *Builder) SetOSVersion(version string) {
219
	b.OCIv1.OSVersion = version
220
	b.Docker.OSVersion = version
221
}
222

223
// OSFeatures returns a list of OS features which the container, or a container
224
// built using an image built from this container, depends on the OS supplying.
225
func (b *Builder) OSFeatures() []string {
226
	return copyStringSlice(b.OCIv1.OSFeatures)
227
}
228

229
// SetOSFeature adds a feature of the OS which the container, or a container
230
// built using an image built from this container, depends on the OS supplying.
231
func (b *Builder) SetOSFeature(feature string) {
232
	if !slices.Contains(b.OCIv1.OSFeatures, feature) {
233
		b.OCIv1.OSFeatures = append(b.OCIv1.OSFeatures, feature)
234
	}
235
	if !slices.Contains(b.Docker.OSFeatures, feature) {
236
		b.Docker.OSFeatures = append(b.Docker.OSFeatures, feature)
237
	}
238
}
239

240
// UnsetOSFeature removes a feature of the OS which the container, or a
241
// container built using an image built from this container, depends on the OS
242
// supplying.
243
func (b *Builder) UnsetOSFeature(feature string) {
244
	if slices.Contains(b.OCIv1.OSFeatures, feature) {
245
		features := make([]string, 0, len(b.OCIv1.OSFeatures))
246
		for _, f := range b.OCIv1.OSFeatures {
247
			if f != feature {
248
				features = append(features, f)
249
			}
250
		}
251
		b.OCIv1.OSFeatures = features
252
	}
253
	if slices.Contains(b.Docker.OSFeatures, feature) {
254
		features := make([]string, 0, len(b.Docker.OSFeatures))
255
		for _, f := range b.Docker.OSFeatures {
256
			if f != feature {
257
				features = append(features, f)
258
			}
259
		}
260
		b.Docker.OSFeatures = features
261
	}
262
}
263

264
// ClearOSFeatures clears the list of features of the OS which the container,
265
// or a container built using an image built from this container, depends on
266
// the OS supplying.
267
func (b *Builder) ClearOSFeatures() {
268
	b.OCIv1.OSFeatures = []string{}
269
	b.Docker.OSFeatures = []string{}
270
}
271

272
// Architecture returns a name of the architecture on which the container, or a
273
// container built using an image built from this container, is intended to be
274
// run.
275
func (b *Builder) Architecture() string {
276
	return b.OCIv1.Architecture
277
}
278

279
// SetArchitecture sets the name of the architecture on which the container, or
280
// a container built using an image built from this container, is intended to
281
// be run.
282
func (b *Builder) SetArchitecture(arch string) {
283
	b.OCIv1.Architecture = arch
284
	b.Docker.Architecture = arch
285
}
286

287
// Variant returns a name of the architecture variant on which the container,
288
// or a container built using an image built from this container, is intended
289
// to be run.
290
func (b *Builder) Variant() string {
291
	return b.OCIv1.Variant
292
}
293

294
// SetVariant sets the name of the architecture variant on which the container,
295
// or a container built using an image built from this container, is intended
296
// to be run.
297
func (b *Builder) SetVariant(variant string) {
298
	b.Docker.Variant = variant
299
	b.OCIv1.Variant = variant
300
}
301

302
// Maintainer returns contact information for the person who built the image.
303
func (b *Builder) Maintainer() string {
304
	return b.OCIv1.Author
305
}
306

307
// SetMaintainer sets contact information for the person who built the image.
308
func (b *Builder) SetMaintainer(who string) {
309
	b.OCIv1.Author = who
310
	b.Docker.Author = who
311
}
312

313
// User returns information about the user as whom the container, or a
314
// container built using an image built from this container, should be run.
315
func (b *Builder) User() string {
316
	return b.OCIv1.Config.User
317
}
318

319
// SetUser sets information about the user as whom the container, or a
320
// container built using an image built from this container, should be run.
321
// Acceptable forms are a user name or ID, optionally followed by a colon and a
322
// group name or ID.
323
func (b *Builder) SetUser(spec string) {
324
	b.OCIv1.Config.User = spec
325
	b.Docker.Config.User = spec
326
}
327

328
// OnBuild returns the OnBuild value from the container.
329
func (b *Builder) OnBuild() []string {
330
	return copyStringSlice(b.Docker.Config.OnBuild)
331
}
332

333
// ClearOnBuild removes all values from the OnBuild structure
334
func (b *Builder) ClearOnBuild() {
335
	b.Docker.Config.OnBuild = []string{}
336
}
337

338
// SetOnBuild sets a trigger instruction to be executed when the image is used
339
// as the base of another image.
340
// Note: this setting is not present in the OCIv1 image format, so it is
341
// discarded when writing images using OCIv1 formats.
342
func (b *Builder) SetOnBuild(onBuild string) {
343
	if onBuild != "" && b.Format != define.Dockerv2ImageManifest {
344
		b.Logger.Warnf("ONBUILD is not supported for OCI image format, %s will be ignored. Must use `docker` format", onBuild)
345
	}
346
	b.Docker.Config.OnBuild = append(b.Docker.Config.OnBuild, onBuild)
347
}
348

349
// WorkDir returns the default working directory for running commands in the
350
// container, or in a container built using an image built from this container.
351
func (b *Builder) WorkDir() string {
352
	return b.OCIv1.Config.WorkingDir
353
}
354

355
// SetWorkDir sets the location of the default working directory for running
356
// commands in the container, or in a container built using an image built from
357
// this container.
358
func (b *Builder) SetWorkDir(there string) {
359
	b.OCIv1.Config.WorkingDir = there
360
	b.Docker.Config.WorkingDir = there
361
}
362

363
// Shell returns the default shell for running commands in the
364
// container, or in a container built using an image built from this container.
365
func (b *Builder) Shell() []string {
366
	return copyStringSlice(b.Docker.Config.Shell)
367
}
368

369
// SetShell sets the default shell for running
370
// commands in the container, or in a container built using an image built from
371
// this container.
372
// Note: this setting is not present in the OCIv1 image format, so it is
373
// discarded when writing images using OCIv1 formats.
374
func (b *Builder) SetShell(shell []string) {
375
	if len(shell) > 0 && b.Format != define.Dockerv2ImageManifest {
376
		b.Logger.Warnf("SHELL is not supported for OCI image format, %s will be ignored. Must use `docker` format", shell)
377
	}
378

379
	b.Docker.Config.Shell = copyStringSlice(shell)
380
}
381

382
// Env returns a list of key-value pairs to be set when running commands in the
383
// container, or in a container built using an image built from this container.
384
func (b *Builder) Env() []string {
385
	return copyStringSlice(b.OCIv1.Config.Env)
386
}
387

388
// SetEnv adds or overwrites a value to the set of environment strings which
389
// should be set when running commands in the container, or in a container
390
// built using an image built from this container.
391
func (b *Builder) SetEnv(k string, v string) {
392
	reset := func(s *[]string) {
393
		n := []string{}
394
		for i := range *s {
395
			if !strings.HasPrefix((*s)[i], k+"=") {
396
				n = append(n, (*s)[i])
397
			}
398
		}
399
		n = append(n, k+"="+v)
400
		*s = n
401
	}
402
	reset(&b.OCIv1.Config.Env)
403
	reset(&b.Docker.Config.Env)
404
}
405

406
// UnsetEnv removes a value from the set of environment strings which should be
407
// set when running commands in this container, or in a container built using
408
// an image built from this container.
409
func (b *Builder) UnsetEnv(k string) {
410
	unset := func(s *[]string) {
411
		n := []string{}
412
		for i := range *s {
413
			if !strings.HasPrefix((*s)[i], k+"=") {
414
				n = append(n, (*s)[i])
415
			}
416
		}
417
		*s = n
418
	}
419
	unset(&b.OCIv1.Config.Env)
420
	unset(&b.Docker.Config.Env)
421
}
422

423
// ClearEnv removes all values from the set of environment strings which should
424
// be set when running commands in this container, or in a container built
425
// using an image built from this container.
426
func (b *Builder) ClearEnv() {
427
	b.OCIv1.Config.Env = []string{}
428
	b.Docker.Config.Env = []string{}
429
}
430

431
// Cmd returns the default command, or command parameters if an Entrypoint is
432
// set, to use when running a container built from an image built from this
433
// container.
434
func (b *Builder) Cmd() []string {
435
	return copyStringSlice(b.OCIv1.Config.Cmd)
436
}
437

438
// SetCmd sets the default command, or command parameters if an Entrypoint is
439
// set, to use when running a container built from an image built from this
440
// container.
441
func (b *Builder) SetCmd(cmd []string) {
442
	b.OCIv1.Config.Cmd = copyStringSlice(cmd)
443
	b.Docker.Config.Cmd = copyStringSlice(cmd)
444
}
445

446
// Entrypoint returns the command to be run for containers built from images
447
// built from this container.
448
func (b *Builder) Entrypoint() []string {
449
	if len(b.OCIv1.Config.Entrypoint) > 0 {
450
		return copyStringSlice(b.OCIv1.Config.Entrypoint)
451
	}
452
	return nil
453
}
454

455
// SetEntrypoint sets the command to be run for in containers built from images
456
// built from this container.
457
func (b *Builder) SetEntrypoint(ep []string) {
458
	b.OCIv1.Config.Entrypoint = copyStringSlice(ep)
459
	b.Docker.Config.Entrypoint = copyStringSlice(ep)
460
}
461

462
// Labels returns a set of key-value pairs from the image's runtime
463
// configuration.
464
func (b *Builder) Labels() map[string]string {
465
	return copyStringStringMap(b.OCIv1.Config.Labels)
466
}
467

468
// SetLabel adds or overwrites a key's value from the image's runtime
469
// configuration.
470
func (b *Builder) SetLabel(k string, v string) {
471
	if b.OCIv1.Config.Labels == nil {
472
		b.OCIv1.Config.Labels = map[string]string{}
473
	}
474
	b.OCIv1.Config.Labels[k] = v
475
	if b.Docker.Config.Labels == nil {
476
		b.Docker.Config.Labels = map[string]string{}
477
	}
478
	b.Docker.Config.Labels[k] = v
479
}
480

481
// UnsetLabel removes a key and its value from the image's runtime
482
// configuration, if it's present.
483
func (b *Builder) UnsetLabel(k string) {
484
	delete(b.OCIv1.Config.Labels, k)
485
	delete(b.Docker.Config.Labels, k)
486
}
487

488
// ClearLabels removes all keys and their values from the image's runtime
489
// configuration.
490
func (b *Builder) ClearLabels() {
491
	b.OCIv1.Config.Labels = map[string]string{}
492
	b.Docker.Config.Labels = map[string]string{}
493
}
494

495
// Ports returns the set of ports which should be exposed when a container
496
// based on an image built from this container is run.
497
func (b *Builder) Ports() []string {
498
	p := []string{}
499
	for k := range b.OCIv1.Config.ExposedPorts {
500
		p = append(p, k)
501
	}
502
	return p
503
}
504

505
// SetPort adds or overwrites an exported port in the set of ports which should
506
// be exposed when a container based on an image built from this container is
507
// run.
508
func (b *Builder) SetPort(p string) {
509
	if b.OCIv1.Config.ExposedPorts == nil {
510
		b.OCIv1.Config.ExposedPorts = map[string]struct{}{}
511
	}
512
	b.OCIv1.Config.ExposedPorts[p] = struct{}{}
513
	if b.Docker.Config.ExposedPorts == nil {
514
		b.Docker.Config.ExposedPorts = make(docker.PortSet)
515
	}
516
	b.Docker.Config.ExposedPorts[docker.Port(p)] = struct{}{}
517
}
518

519
// UnsetPort removes an exposed port from the set of ports which should be
520
// exposed when a container based on an image built from this container is run.
521
func (b *Builder) UnsetPort(p string) {
522
	delete(b.OCIv1.Config.ExposedPorts, p)
523
	delete(b.Docker.Config.ExposedPorts, docker.Port(p))
524
}
525

526
// ClearPorts empties the set of ports which should be exposed when a container
527
// based on an image built from this container is run.
528
func (b *Builder) ClearPorts() {
529
	b.OCIv1.Config.ExposedPorts = map[string]struct{}{}
530
	b.Docker.Config.ExposedPorts = docker.PortSet{}
531
}
532

533
// Volumes returns a list of filesystem locations which should be mounted from
534
// outside of the container when a container built from an image built from
535
// this container is run.
536
func (b *Builder) Volumes() []string {
537
	v := []string{}
538
	for k := range b.OCIv1.Config.Volumes {
539
		v = append(v, k)
540
	}
541
	if len(v) > 0 {
542
		return v
543
	}
544
	return nil
545
}
546

547
// CheckVolume returns True if the location exists in the image's list of locations
548
// which should be mounted from outside of the container when a container
549
// based on an image built from this container is run
550

551
func (b *Builder) CheckVolume(v string) bool {
552
	_, OCIv1Volume := b.OCIv1.Config.Volumes[v]
553
	_, DockerVolume := b.Docker.Config.Volumes[v]
554
	return OCIv1Volume || DockerVolume
555
}
556

557
// AddVolume adds a location to the image's list of locations which should be
558
// mounted from outside of the container when a container based on an image
559
// built from this container is run.
560
func (b *Builder) AddVolume(v string) {
561
	if b.OCIv1.Config.Volumes == nil {
562
		b.OCIv1.Config.Volumes = map[string]struct{}{}
563
	}
564
	b.OCIv1.Config.Volumes[v] = struct{}{}
565
	if b.Docker.Config.Volumes == nil {
566
		b.Docker.Config.Volumes = map[string]struct{}{}
567
	}
568
	b.Docker.Config.Volumes[v] = struct{}{}
569
}
570

571
// RemoveVolume removes a location from the list of locations which should be
572
// mounted from outside of the container when a container based on an image
573
// built from this container is run.
574
func (b *Builder) RemoveVolume(v string) {
575
	delete(b.OCIv1.Config.Volumes, v)
576
	delete(b.Docker.Config.Volumes, v)
577
}
578

579
// ClearVolumes removes all locations from the image's list of locations which
580
// should be mounted from outside of the container when a container based on an
581
// image built from this container is run.
582
func (b *Builder) ClearVolumes() {
583
	b.OCIv1.Config.Volumes = map[string]struct{}{}
584
	b.Docker.Config.Volumes = map[string]struct{}{}
585
}
586

587
// Hostname returns the hostname which will be set in the container and in
588
// containers built using images built from the container.
589
func (b *Builder) Hostname() string {
590
	return b.Docker.Config.Hostname
591
}
592

593
// SetHostname sets the hostname which will be set in the container and in
594
// containers built using images built from the container.
595
// Note: this setting is not present in the OCIv1 image format, so it is
596
// discarded when writing images using OCIv1 formats.
597
func (b *Builder) SetHostname(name string) {
598
	b.Docker.Config.Hostname = name
599
}
600

601
// Domainname returns the domainname which will be set in the container and in
602
// containers built using images built from the container.
603
func (b *Builder) Domainname() string {
604
	return b.Docker.Config.Domainname
605
}
606

607
// SetDomainname sets the domainname which will be set in the container and in
608
// containers built using images built from the container.
609
// Note: this setting is not present in the OCIv1 image format, so it is
610
// discarded when writing images using OCIv1 formats.
611
func (b *Builder) SetDomainname(name string) {
612
	if name != "" && b.Format != define.Dockerv2ImageManifest {
613
		b.Logger.Warnf("DOMAINNAME is not supported for OCI image format, domainname %s will be ignored. Must use `docker` format", name)
614
	}
615
	b.Docker.Config.Domainname = name
616
}
617

618
// SetDefaultMountsFilePath sets the mounts file path for testing purposes
619
func (b *Builder) SetDefaultMountsFilePath(path string) {
620
	b.DefaultMountsFilePath = path
621
}
622

623
// Comment returns the comment which will be set in the container and in
624
// containers built using images built from the container
625
func (b *Builder) Comment() string {
626
	return b.Docker.Comment
627
}
628

629
// SetComment sets the comment which will be set in the container and in
630
// containers built using images built from the container.
631
// Note: this setting is not present in the OCIv1 image format, so it is
632
// discarded when writing images using OCIv1 formats.
633
func (b *Builder) SetComment(comment string) {
634
	if comment != "" && b.Format != define.Dockerv2ImageManifest {
635
		logrus.Warnf("COMMENT is not supported for OCI image format, comment %s will be ignored. Must use `docker` format", comment)
636
	}
637
	b.Docker.Comment = comment
638
}
639

640
// HistoryComment returns the comment which will be used in the history item
641
// which will describe the latest layer when we commit an image.
642
func (b *Builder) HistoryComment() string {
643
	return b.ImageHistoryComment
644
}
645

646
// SetHistoryComment sets the comment which will be used in the history item
647
// which will describe the latest layer when we commit an image.
648
func (b *Builder) SetHistoryComment(comment string) {
649
	b.ImageHistoryComment = comment
650
}
651

652
// StopSignal returns the signal which will be set in the container and in
653
// containers built using images built from the container
654
func (b *Builder) StopSignal() string {
655
	return b.Docker.Config.StopSignal
656
}
657

658
// SetStopSignal sets the signal which will be set in the container and in
659
// containers built using images built from the container.
660
func (b *Builder) SetStopSignal(stopSignal string) {
661
	b.OCIv1.Config.StopSignal = stopSignal
662
	b.Docker.Config.StopSignal = stopSignal
663
}
664

665
// Healthcheck returns information that recommends how a container engine
666
// should check if a running container is "healthy".
667
func (b *Builder) Healthcheck() *docker.HealthConfig {
668
	if b.Docker.Config.Healthcheck == nil {
669
		return nil
670
	}
671
	return &docker.HealthConfig{
672
		Test:        copyStringSlice(b.Docker.Config.Healthcheck.Test),
673
		Interval:    b.Docker.Config.Healthcheck.Interval,
674
		Timeout:     b.Docker.Config.Healthcheck.Timeout,
675
		StartPeriod: b.Docker.Config.Healthcheck.StartPeriod,
676
		Retries:     b.Docker.Config.Healthcheck.Retries,
677
	}
678
}
679

680
// SetHealthcheck sets recommended commands to run in order to verify that a
681
// running container based on this image is "healthy", along with information
682
// specifying how often that test should be run, and how many times the test
683
// should fail before the container should be considered unhealthy.
684
// Note: this setting is not present in the OCIv1 image format, so it is
685
// discarded when writing images using OCIv1 formats.
686
func (b *Builder) SetHealthcheck(config *docker.HealthConfig) {
687
	b.Docker.Config.Healthcheck = nil
688
	if config != nil {
689
		if b.Format != define.Dockerv2ImageManifest {
690
			b.Logger.Warnf("HEALTHCHECK is not supported for OCI image format and will be ignored. Must use `docker` format")
691
		}
692
		b.Docker.Config.Healthcheck = &docker.HealthConfig{
693
			Test:        copyStringSlice(config.Test),
694
			Interval:    config.Interval,
695
			Timeout:     config.Timeout,
696
			StartPeriod: config.StartPeriod,
697
			Retries:     config.Retries,
698
		}
699
	}
700
}
701

702
// AddPrependedEmptyLayer adds an item to the history that we'll create when
703
// committing the image, after any history we inherit from the base image, but
704
// before the history item that we'll use to describe the new layer that we're
705
// adding.
706
func (b *Builder) AddPrependedEmptyLayer(created *time.Time, createdBy, author, comment string) {
707
	if created != nil {
708
		copiedTimestamp := *created
709
		created = &copiedTimestamp
710
	}
711
	b.PrependedEmptyLayers = append(b.PrependedEmptyLayers, ociv1.History{
712
		Created:    created,
713
		CreatedBy:  createdBy,
714
		Author:     author,
715
		Comment:    comment,
716
		EmptyLayer: true,
717
	})
718
}
719

720
// ClearPrependedEmptyLayers clears the list of history entries that we'll add
721
// to the committed image before the entry for the layer that we're adding.
722
func (b *Builder) ClearPrependedEmptyLayers() {
723
	b.PrependedEmptyLayers = nil
724
}
725

726
// AddAppendedEmptyLayer adds an item to the history that we'll create when
727
// committing the image, after the history item that we'll use to describe the
728
// new layer that we're adding.
729
func (b *Builder) AddAppendedEmptyLayer(created *time.Time, createdBy, author, comment string) {
730
	if created != nil {
731
		copiedTimestamp := *created
732
		created = &copiedTimestamp
733
	}
734
	b.AppendedEmptyLayers = append(b.AppendedEmptyLayers, ociv1.History{
735
		Created:    created,
736
		CreatedBy:  createdBy,
737
		Author:     author,
738
		Comment:    comment,
739
		EmptyLayer: true,
740
	})
741
}
742

743
// ClearAppendedEmptyLayers clears the list of history entries that we'll add
744
// to the committed image after the entry for the layer that we're adding.
745
func (b *Builder) ClearAppendedEmptyLayers() {
746
	b.AppendedEmptyLayers = nil
747
}
748

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.