Refactor project structure
This commit is contained in:
parent
cb85168cbd
commit
8834dd8aec
40
cmd/images.go
Normal file
40
cmd/images.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gitea.stuzer.link/stuzer05/docker-registry-manager/internal/app"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegistryImages(app *app.App) {
|
||||||
|
type catalog struct {
|
||||||
|
Repositories []string `json:"repositories"`
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Get(app.RegistryURL + "/v2/_catalog")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error fetching images:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
fmt.Println("No images found in the registry.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var cat catalog
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&cat); err != nil {
|
||||||
|
fmt.Println("Error decoding response:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cat.Repositories) == 0 {
|
||||||
|
fmt.Println("No images found in the registry.")
|
||||||
|
} else {
|
||||||
|
for _, img := range cat.Repositories {
|
||||||
|
fmt.Println(img)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
cmd/push.go
Normal file
22
cmd/push.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gitea.stuzer.link/stuzer05/docker-registry-manager/internal/app"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegistryPush(app *app.App, imageName string) {
|
||||||
|
if !strings.HasPrefix(imageName, app.RegistryName) {
|
||||||
|
imageName = app.RegistryName + "/" + imageName
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("docker", "push", imageName)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Println("Error pushing image:", err)
|
||||||
|
}
|
||||||
|
}
|
101
cmd/rm.go
Normal file
101
cmd/rm.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gitea.stuzer.link/stuzer05/docker-registry-manager/internal/app"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegistryRm(app *app.App, imageArg string) {
|
||||||
|
parts := strings.SplitN(imageArg, ":", 2)
|
||||||
|
imageName := parts[0]
|
||||||
|
tag := ""
|
||||||
|
if len(parts) > 1 {
|
||||||
|
tag = parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == "" {
|
||||||
|
deleteImageByName(app, imageName)
|
||||||
|
} else {
|
||||||
|
deleteImageByTag(app, imageName, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteImageByName(app *app.App, imageName string) {
|
||||||
|
type tagList struct {
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Get(fmt.Sprintf("%s/v2/%s/tags/list", app.RegistryURL, imageName))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error fetching tags:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
fmt.Printf("Error: Image '%s' not found in the registry.\n", imageName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var tl tagList
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&tl); err != nil {
|
||||||
|
fmt.Println("Error decoding response:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tag := range tl.Tags {
|
||||||
|
deleteImageByTag(app, imageName, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteImageByTag(app *app.App, imageName, tag string) {
|
||||||
|
client := &http.Client{}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("HEAD", fmt.Sprintf("%s/v2/%s/manifests/%s", app.RegistryURL, imageName, tag), nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error creating request:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error fetching manifest:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
fmt.Printf("Error: Image '%s:%s' not found in the registry.\n", imageName, tag)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
digest := resp.Header.Get("Docker-Content-Digest")
|
||||||
|
|
||||||
|
req, err = http.NewRequest("DELETE", fmt.Sprintf("%s/v2/%s/manifests/%s", app.RegistryURL, imageName, digest), nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error creating delete request:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join username and password for Basic Auth
|
||||||
|
registryCredentials := app.RegistryUsername + ":" + app.RegistryPassword
|
||||||
|
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(registryCredentials)))
|
||||||
|
|
||||||
|
resp, err = client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error deleting image:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusAccepted {
|
||||||
|
fmt.Printf("Deleted image: %s:%s\n", imageName, tag)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Failed to delete image: %s:%s (status code: %d)\n", imageName, tag, resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
22
cmd/tag.go
Normal file
22
cmd/tag.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gitea.stuzer.link/stuzer05/docker-registry-manager/internal/app"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegistryTag(app *app.App, sourceImage, targetImage string) {
|
||||||
|
if !strings.HasPrefix(targetImage, app.RegistryName) {
|
||||||
|
targetImage = app.RegistryName + "/" + targetImage
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("docker", "tag", sourceImage, targetImage)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Println("Error tagging image:", err)
|
||||||
|
}
|
||||||
|
}
|
40
cmd/tags.go
Normal file
40
cmd/tags.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gitea.stuzer.link/stuzer05/docker-registry-manager/internal/app"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegistryTags(app *app.App, imageName string) {
|
||||||
|
type tagList struct {
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Get(fmt.Sprintf("%s/v2/%s/tags/list", app.RegistryURL, imageName))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error fetching tags:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
|
fmt.Printf("Error: Image '%s' not found in the registry.\n", imageName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var tl tagList
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&tl); err != nil {
|
||||||
|
fmt.Println("Error decoding response:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tl.Tags) == 0 {
|
||||||
|
fmt.Printf("No tags found for image: %s\n", imageName)
|
||||||
|
} else {
|
||||||
|
for _, tag := range tl.Tags {
|
||||||
|
fmt.Println(tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
internal/app/app.go
Normal file
33
internal/app/app.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
RegistryName string
|
||||||
|
RegistryURL string
|
||||||
|
RegistryUsername string
|
||||||
|
RegistryPassword string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApp() (*App, error) {
|
||||||
|
registryName := os.Getenv("REGISTRY_NAME")
|
||||||
|
if registryName == "" {
|
||||||
|
return nil, fmt.Errorf("REGISTRY_NAME not found in .env")
|
||||||
|
}
|
||||||
|
|
||||||
|
registryUsername := os.Getenv("REGISTRY_USERNAME")
|
||||||
|
registryPassword := os.Getenv("REGISTRY_PASSWORD")
|
||||||
|
if registryUsername == "" || registryPassword == "" {
|
||||||
|
return nil, fmt.Errorf("REGISTRY_USERNAME or REGISTRY_PASSWORD not found in .env")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &App{
|
||||||
|
RegistryName: registryName,
|
||||||
|
RegistryURL: "https://" + registryName,
|
||||||
|
RegistryUsername: registryUsername,
|
||||||
|
RegistryPassword: registryPassword,
|
||||||
|
}, nil
|
||||||
|
}
|
225
main.go
225
main.go
@ -1,46 +1,30 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/joho/godotenv"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
"gitea.stuzer.link/stuzer05/docker-registry-manager/cmd"
|
||||||
registryName string
|
"gitea.stuzer.link/stuzer05/docker-registry-manager/internal/app"
|
||||||
registryURL string
|
|
||||||
registryUsername string
|
"github.com/joho/godotenv"
|
||||||
registryPassword string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Load .env file
|
// Load .env file
|
||||||
_, b, _, _ := runtime.Caller(0) // @refactor
|
_, b, _, _ := runtime.Caller(0)
|
||||||
err := godotenv.Load(filepath.Join(filepath.Dir(b), ".env"))
|
err := godotenv.Load(filepath.Join(filepath.Dir(b), ".env"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error loading .env file:", err)
|
fmt.Println("Error loading .env file:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read values from environment
|
// Initialize app
|
||||||
registryName = os.Getenv("REGISTRY_NAME")
|
app, err := app.NewApp()
|
||||||
if registryName == "" {
|
if err != nil {
|
||||||
fmt.Println("REGISTRY_NAME not found in .env")
|
fmt.Println("Error initializing app:", err)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
registryURL = "https://" + registryName
|
|
||||||
registryUsername = os.Getenv("REGISTRY_USERNAME")
|
|
||||||
registryPassword = os.Getenv("REGISTRY_PASSWORD")
|
|
||||||
if registryUsername == "" || registryPassword == "" {
|
|
||||||
fmt.Println("REGISTRY_USERNAME or REGISTRY_PASSWORD not found in .env")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,213 +35,32 @@ func main() {
|
|||||||
|
|
||||||
switch os.Args[1] {
|
switch os.Args[1] {
|
||||||
case "images":
|
case "images":
|
||||||
registryImages()
|
cmd.RegistryImages(app)
|
||||||
case "tags":
|
case "tags":
|
||||||
if len(os.Args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
fmt.Println("Error: Please provide an image name.")
|
fmt.Println("Error: Please provide an image name.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
registryTags(os.Args[2])
|
cmd.RegistryTags(app, os.Args[2])
|
||||||
case "rm":
|
case "rm":
|
||||||
if len(os.Args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
fmt.Println("Error: Please provide an image name and optionally a tag (e.g., my-image or my-image:latest).")
|
fmt.Println("Error: Please provide an image name and optionally a tag (e.g., my-image or my-image:latest).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
registryRm(os.Args[2])
|
cmd.RegistryRm(app, os.Args[2])
|
||||||
case "push":
|
case "push":
|
||||||
if len(os.Args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
fmt.Println("Error: Please provide an image name to push.")
|
fmt.Println("Error: Please provide an image name to push.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
registryPush(os.Args[2])
|
cmd.RegistryPush(app, os.Args[2])
|
||||||
case "tag":
|
case "tag":
|
||||||
if len(os.Args) < 4 {
|
if len(os.Args) < 4 {
|
||||||
fmt.Println("Error: Please provide both source and target image names.")
|
fmt.Println("Error: Please provide both source and target image names.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
registryTag(os.Args[2], os.Args[3])
|
cmd.RegistryTag(app, os.Args[2], os.Args[3])
|
||||||
default:
|
default:
|
||||||
fmt.Println("Invalid command. Usage: registry [images|tags|rm|push|tag] <args>")
|
fmt.Println("Invalid command. Usage: registry [images|tags|rm|push|tag] <args>")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func registryImages() {
|
|
||||||
type catalog struct {
|
|
||||||
Repositories []string `json:"repositories"`
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(registryURL + "/v2/_catalog")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error fetching images:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusNotFound {
|
|
||||||
fmt.Println("No images found in the registry.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var cat catalog
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&cat); err != nil {
|
|
||||||
fmt.Println("Error decoding response:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cat.Repositories) == 0 {
|
|
||||||
fmt.Println("No images found in the registry.")
|
|
||||||
} else {
|
|
||||||
for _, img := range cat.Repositories {
|
|
||||||
fmt.Println(img)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func registryTags(imageName string) {
|
|
||||||
type tagList struct {
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(fmt.Sprintf("%s/v2/%s/tags/list", registryURL, imageName))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error fetching tags:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusNotFound {
|
|
||||||
fmt.Printf("Error: Image '%s' not found in the registry.\n", imageName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var tl tagList
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&tl); err != nil {
|
|
||||||
fmt.Println("Error decoding response:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(tl.Tags) == 0 {
|
|
||||||
fmt.Printf("No tags found for image: %s\n", imageName)
|
|
||||||
} else {
|
|
||||||
for _, tag := range tl.Tags {
|
|
||||||
fmt.Println(tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func registryRm(imageArg string) {
|
|
||||||
parts := strings.SplitN(imageArg, ":", 2)
|
|
||||||
imageName := parts[0]
|
|
||||||
tag := ""
|
|
||||||
if len(parts) > 1 {
|
|
||||||
tag = parts[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
if tag == "" {
|
|
||||||
deleteImageByName(imageName)
|
|
||||||
} else {
|
|
||||||
deleteImageByTag(imageName, tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteImageByName(imageName string) {
|
|
||||||
type tagList struct {
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(fmt.Sprintf("%s/v2/%s/tags/list", registryURL, imageName))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error fetching tags:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusNotFound {
|
|
||||||
fmt.Printf("Error: Image '%s' not found in the registry.\n", imageName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var tl tagList
|
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&tl); err != nil {
|
|
||||||
fmt.Println("Error decoding response:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tag := range tl.Tags {
|
|
||||||
deleteImageByTag(imageName, tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteImageByTag(imageName, tag string) {
|
|
||||||
client := &http.Client{}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("HEAD", fmt.Sprintf("%s/v2/%s/manifests/%s", registryURL, imageName, tag), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error creating request:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
|
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error fetching manifest:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusNotFound {
|
|
||||||
fmt.Printf("Error: Image '%s:%s' not found in the registry.\n", imageName, tag)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
digest := resp.Header.Get("Docker-Content-Digest")
|
|
||||||
|
|
||||||
req, err = http.NewRequest("DELETE", fmt.Sprintf("%s/v2/%s/manifests/%s", registryURL, imageName, digest), nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error creating delete request:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Join username and password for Basic Auth
|
|
||||||
registryCredentials := registryUsername + ":" + registryPassword
|
|
||||||
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(registryCredentials)))
|
|
||||||
|
|
||||||
resp, err = client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error deleting image:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusAccepted {
|
|
||||||
fmt.Printf("Deleted image: %s:%s\n", imageName, tag)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("Failed to delete image: %s:%s (status code: %d)\n", imageName, tag, resp.StatusCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func registryPush(imageName string) {
|
|
||||||
if !strings.HasPrefix(imageName, registryName) {
|
|
||||||
imageName = registryName + "/" + imageName
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command("docker", "push", imageName)
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
fmt.Println("Error pushing image:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func registryTag(sourceImage, targetImage string) {
|
|
||||||
if !strings.HasPrefix(targetImage, registryName) {
|
|
||||||
targetImage = registryName + "/" + targetImage
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := exec.Command("docker", "tag", sourceImage, targetImage)
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
fmt.Println("Error tagging image:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user