podman

Форк
0
/
runtime_img.go 
148 строк · 4.8 Кб
1
//go:build !remote
2

3
package libpod
4

5
import (
6
	"context"
7
	"errors"
8
	"fmt"
9
	"io"
10
	"os"
11

12
	buildahDefine "github.com/containers/buildah/define"
13
	"github.com/containers/buildah/imagebuildah"
14
	"github.com/containers/common/libimage"
15
	"github.com/containers/image/v5/docker/reference"
16
	"github.com/containers/podman/v5/libpod/define"
17
	"github.com/containers/podman/v5/libpod/events"
18
	"github.com/containers/podman/v5/pkg/util"
19
	"github.com/sirupsen/logrus"
20
)
21

22
// Runtime API
23

24
// RemoveContainersForImageCallback returns a callback that can be used in
25
// `libimage`.  When forcefully removing images, containers using the image
26
// should be removed as well.  The callback allows for more graceful removal as
27
// we can use the libpod-internal removal logic.
28
func (r *Runtime) RemoveContainersForImageCallback(ctx context.Context) libimage.RemoveContainerFunc {
29
	return func(imageID string) error {
30
		if !r.valid {
31
			return define.ErrRuntimeStopped
32
		}
33
		ctrs, err := r.state.AllContainers(false)
34
		if err != nil {
35
			return err
36
		}
37
		for _, ctr := range ctrs {
38
			if ctr.config.RootfsImageID != imageID {
39
				continue
40
			}
41
			var timeout *uint
42
			if ctr.config.IsInfra {
43
				pod, err := r.state.Pod(ctr.config.Pod)
44
				if err != nil {
45
					return fmt.Errorf("container %s is in pod %s, but pod cannot be retrieved: %w", ctr.ID(), ctr.config.Pod, err)
46
				}
47
				if _, err := r.removePod(ctx, pod, true, true, timeout); err != nil {
48
					return fmt.Errorf("removing image %s: container %s using image could not be removed: %w", imageID, ctr.ID(), err)
49
				}
50
			} else {
51
				opts := ctrRmOpts{
52
					Force:   true,
53
					Timeout: timeout,
54
				}
55
				if _, _, err := r.removeContainer(ctx, ctr, opts); err != nil {
56
					return fmt.Errorf("removing image %s: container %s using image could not be removed: %w", imageID, ctr.ID(), err)
57
				}
58
			}
59
		}
60

61
		// Need to handle volumes with the image driver
62
		vols, err := r.state.AllVolumes()
63
		if err != nil {
64
			return err
65
		}
66
		for _, vol := range vols {
67
			if vol.config.Driver != define.VolumeDriverImage || vol.config.StorageImageID != imageID {
68
				continue
69
			}
70
			// Do a force removal of the volume, and all containers
71
			// using it.
72
			if err := r.RemoveVolume(ctx, vol, true, nil); err != nil {
73
				return fmt.Errorf("removing image %s: volume %s backed by image could not be removed: %w", imageID, vol.Name(), err)
74
			}
75
		}
76

77
		// Note that `libimage` will take care of removing any leftover
78
		// containers from the storage.
79
		return nil
80
	}
81
}
82

83
// IsExternalContainerCallback returns a callback that be used in `libimage` to
84
// figure out whether a given container is an external one.  A container is
85
// considered external if it is not present in libpod's database.
86
func (r *Runtime) IsExternalContainerCallback(_ context.Context) libimage.IsExternalContainerFunc {
87
	// NOTE: pruning external containers is subject to race conditions
88
	// (e.g., when a container gets removed). To address this and similar
89
	// races, pruning had to happen inside c/storage.  Containers has to be
90
	// labeled with "podman/libpod" along with callbacks similar to
91
	// libimage.
92
	return func(idOrName string) (bool, error) {
93
		_, err := r.LookupContainer(idOrName)
94
		if err == nil {
95
			return false, nil
96
		}
97
		if errors.Is(err, define.ErrNoSuchCtr) {
98
			return true, nil
99
		}
100
		isVol, err := r.state.ContainerIDIsVolume(idOrName)
101
		if err == nil && !isVol {
102
			return true, nil
103
		}
104
		return false, nil
105
	}
106
}
107

108
// newBuildEvent creates a new event based on completion of a built image
109
func (r *Runtime) newImageBuildCompleteEvent(idOrName string) {
110
	e := events.NewEvent(events.Build)
111
	e.Type = events.Image
112
	e.Name = idOrName
113
	if err := r.eventer.Write(e); err != nil {
114
		logrus.Errorf("Unable to write build event: %q", err)
115
	}
116
}
117

118
// Build adds the runtime to the imagebuildah call
119
func (r *Runtime) Build(ctx context.Context, options buildahDefine.BuildOptions, dockerfiles ...string) (string, reference.Canonical, error) {
120
	if options.Runtime == "" {
121
		options.Runtime = r.GetOCIRuntimePath()
122
	}
123
	// share the network interface between podman and buildah
124
	options.NetworkInterface = r.network
125
	id, ref, err := imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...)
126
	// Write event for build completion
127
	r.newImageBuildCompleteEvent(id)
128
	return id, ref, err
129
}
130

131
// DownloadFromFile reads all of the content from the reader and temporarily
132
// saves in it $TMPDIR/importxyz, which is deleted after the image is imported
133
func DownloadFromFile(reader *os.File) (string, error) {
134
	outFile, err := os.CreateTemp(util.Tmpdir(), "import")
135
	if err != nil {
136
		return "", fmt.Errorf("creating file: %w", err)
137
	}
138
	defer outFile.Close()
139

140
	logrus.Debugf("saving %s to %s", reader.Name(), outFile.Name())
141

142
	_, err = io.Copy(outFile, reader)
143
	if err != nil {
144
		return "", fmt.Errorf("saving %s to %s: %w", reader.Name(), outFile.Name(), err)
145
	}
146

147
	return outFile.Name(), nil
148
}
149

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

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

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

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