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