podman

Форк
0
/
runtime_cstorage.go 
135 строк · 4.1 Кб
1
//go:build !remote
2

3
package libpod
4

5
import (
6
	"errors"
7
	"fmt"
8
	"time"
9

10
	"github.com/containers/podman/v5/libpod/define"
11
	"github.com/containers/storage"
12
	"github.com/sirupsen/logrus"
13
)
14

15
// StorageContainer represents a container present in c/storage but not in
16
// libpod.
17
type StorageContainer struct {
18
	ID              string
19
	Names           []string
20
	Image           string
21
	CreateTime      time.Time
22
	PresentInLibpod bool
23
}
24

25
// ListStorageContainers lists all containers visible to c/storage.
26
func (r *Runtime) ListStorageContainers() ([]*StorageContainer, error) {
27
	finalCtrs := []*StorageContainer{}
28

29
	ctrs, err := r.store.Containers()
30
	if err != nil {
31
		return nil, err
32
	}
33

34
	for _, ctr := range ctrs {
35
		storageCtr := new(StorageContainer)
36
		storageCtr.ID = ctr.ID
37
		storageCtr.Names = ctr.Names
38
		storageCtr.Image = ctr.ImageID
39
		storageCtr.CreateTime = ctr.Created
40

41
		// Look up if container is in state
42
		hasCtr, err := r.state.HasContainer(ctr.ID)
43
		if err != nil {
44
			return nil, fmt.Errorf("looking up container %s in state: %w", ctr.ID, err)
45
		}
46

47
		storageCtr.PresentInLibpod = hasCtr
48

49
		finalCtrs = append(finalCtrs, storageCtr)
50
	}
51

52
	return finalCtrs, nil
53
}
54

55
func (r *Runtime) StorageContainer(idOrName string) (*storage.Container, error) {
56
	return r.store.Container(idOrName)
57
}
58

59
// RemoveStorageContainer removes a container from c/storage.
60
// The container WILL NOT be removed if it exists in libpod.
61
// Accepts ID or full name of container.
62
// If force is set, the container will be unmounted first to ensure removal.
63
func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error {
64
	targetID, err := r.store.Lookup(idOrName)
65
	if err != nil {
66
		if errors.Is(err, storage.ErrLayerUnknown) {
67
			return fmt.Errorf("no container with ID or name %q found: %w", idOrName, define.ErrNoSuchCtr)
68
		}
69
		return fmt.Errorf("looking up container %q: %w", idOrName, err)
70
	}
71

72
	// Lookup returns an ID but it's not guaranteed to be a container ID.
73
	// So we can still error here.
74
	ctr, err := r.store.Container(targetID)
75
	if err != nil {
76
		if errors.Is(err, storage.ErrContainerUnknown) {
77
			return fmt.Errorf("%q does not refer to a container: %w", idOrName, define.ErrNoSuchCtr)
78
		}
79
		return fmt.Errorf("retrieving container %q: %w", idOrName, err)
80
	}
81

82
	// Error out if the container exists in libpod
83
	exists, err := r.state.HasContainer(ctr.ID)
84
	if err != nil {
85
		return err
86
	}
87
	if exists {
88
		return fmt.Errorf("refusing to remove %q as it exists in libpod as container %s: %w", idOrName, ctr.ID, define.ErrCtrExists)
89
	}
90

91
	// Error out if this is an image-backed volume
92
	allVols, err := r.state.AllVolumes()
93
	if err != nil {
94
		return err
95
	}
96
	for _, vol := range allVols {
97
		if vol.config.Driver == define.VolumeDriverImage && vol.config.StorageID == ctr.ID {
98
			return fmt.Errorf("refusing to remove %q as it exists in libpod as an image-backed volume %s: %w", idOrName, vol.Name(), define.ErrCtrExists)
99
		}
100
	}
101

102
	if !force {
103
		timesMounted, err := r.store.Mounted(ctr.ID)
104
		if err != nil {
105
			if errors.Is(err, storage.ErrContainerUnknown) {
106
				// Container was removed from under us.
107
				// It's gone, so don't bother erroring.
108
				logrus.Infof("Storage for container %s already removed", ctr.ID)
109
				return nil
110
			}
111
			logrus.Warnf("Checking if container %q is mounted, attempting to delete: %v", idOrName, err)
112
		}
113
		if timesMounted > 0 {
114
			return fmt.Errorf("container %q is mounted and cannot be removed without using force: %w", idOrName, define.ErrCtrStateInvalid)
115
		}
116
	} else if _, err := r.store.Unmount(ctr.ID, true); err != nil {
117
		if errors.Is(err, storage.ErrContainerUnknown) {
118
			// Container again gone, no error
119
			logrus.Infof("Storage for container %s already removed", ctr.ID)
120
			return nil
121
		}
122
		logrus.Warnf("Unmounting container %q while attempting to delete storage: %v", idOrName, err)
123
	}
124

125
	if err := r.store.DeleteContainer(ctr.ID); err != nil {
126
		if errors.Is(err, storage.ErrNotAContainer) || errors.Is(err, storage.ErrContainerUnknown) {
127
			// Container again gone, no error
128
			logrus.Infof("Storage for container %s already removed", ctr.ID)
129
			return nil
130
		}
131
		return fmt.Errorf("removing storage for container %q: %w", idOrName, err)
132
	}
133

134
	return nil
135
}
136

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

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

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

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