podman
129 строк · 3.0 Кб
1package registry
2
3import (
4"fmt"
5"os"
6"strings"
7
8"github.com/containers/podman/v5/utils"
9"github.com/sirupsen/logrus"
10)
11
12const (
13ImageKey = "PODMAN_REGISTRY_IMAGE"
14UserKey = "PODMAN_REGISTRY_USER"
15PassKey = "PODMAN_REGISTRY_PASS"
16PortKey = "PODMAN_REGISTRY_PORT"
17)
18
19var binary = "podman-registry"
20
21// Registry is locally running registry.
22type Registry struct {
23// Image - container image of the registry.
24Image string
25// User - the user to authenticate against the registry.
26User string
27// Password - the accompanying password for the user.
28Password string
29// Port - the port the registry is listening to on the host.
30Port string
31// running indicates if the registry is running.
32running bool
33}
34
35// Options allows for customizing a registry.
36type Options struct {
37// PodmanPath - path to podman executable
38PodmanPath string
39// PodmanArgs - array of podman options
40PodmanArgs []string
41// Image - custom registry image.
42Image string
43}
44
45// StartWithOptions a new registry and return it along with its image, user, password, and port.
46func StartWithOptions(options *Options) (*Registry, error) {
47if options == nil {
48options = &Options{}
49}
50
51var args []string
52if options.Image != "" {
53args = append(args, "-i", options.Image)
54}
55args = append(args, "start")
56
57podmanCmd := []string{"podman"}
58if options.PodmanPath != "" {
59podmanCmd[0] = options.PodmanPath
60}
61if len(options.PodmanArgs) != 0 {
62podmanCmd = append(podmanCmd, options.PodmanArgs...)
63}
64
65// Start a registry.
66os.Setenv("PODMAN", strings.Join(podmanCmd, " "))
67out, err := utils.ExecCmd(binary, args...)
68os.Unsetenv("PODMAN")
69if err != nil {
70return nil, fmt.Errorf("running %q: %s: %w", binary, out, err)
71}
72
73// Parse the output.
74registry := Registry{}
75for _, s := range strings.Split(out, "\n") {
76if s == "" {
77continue
78}
79spl := strings.Split(s, "=")
80if len(spl) != 2 {
81return nil, fmt.Errorf("unexpected output format %q: want 'PODMAN_...=...'", s)
82}
83key := spl[0]
84val := strings.TrimSuffix(strings.TrimPrefix(spl[1], "\""), "\"")
85switch key {
86case ImageKey:
87registry.Image = val
88case UserKey:
89registry.User = val
90case PassKey:
91registry.Password = val
92case PortKey:
93registry.Port = val
94default:
95logrus.Errorf("Unexpected podman-registry output: %q", s)
96}
97}
98
99// Extra sanity check.
100if registry.Image == "" {
101return nil, fmt.Errorf("unexpected output %q: %q missing", out, ImageKey)
102}
103if registry.User == "" {
104return nil, fmt.Errorf("unexpected output %q: %q missing", out, UserKey)
105}
106if registry.Password == "" {
107return nil, fmt.Errorf("unexpected output %q: %q missing", out, PassKey)
108}
109if registry.Port == "" {
110return nil, fmt.Errorf("unexpected output %q: %q missing", out, PortKey)
111}
112
113registry.running = true
114
115return ®istry, nil
116}
117
118// Stop the registry.
119func (r *Registry) Stop() error {
120// Stop a registry.
121if !r.running {
122return nil
123}
124if _, err := utils.ExecCmd(binary, "-P", r.Port, "stop"); err != nil {
125return fmt.Errorf("stopping registry (%v) with %q: %w", *r, binary, err)
126}
127r.running = false
128return nil
129}
130