Fix error 500 when uploading an image for the first time
- commit
- d925f248fa72f4441fd4f5f0e6937c759860b161
- author
- bnema · · 2023-09-25 07:30 UTC
- parent
- 339e684
- signature
- unsigned
5 files · +53 -37
M internal/gotemplate/models/html/fragments/imagelist.gohtml +25 -10
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | id="upload-button" | |
| 7 | 7 | hx-get="/htmx/upload-image" | |
| 8 | 8 | hx-target="#upload-image" | |
| 9 | - | hx-swap="outerHTML" | |
| 9 | + | hx-swap="innerHTML" | |
| 10 | 10 | class="py-1 px-2 bg-blue-500 hover:bg-blue-700 text-white font-bold rounded" | |
| 11 | 11 | > | |
| 12 | 12 | <span class="iconoir-upload text-xl align-middle"></span> | |
| @@ -14,14 +14,6 @@ | |||
| 14 | 14 | </button> | |
| 15 | 15 | </div> | |
| 16 | 16 | <table class="p-4 border-t-2"> | |
| 17 | - | <!-- <thead> | |
| 18 | - | <tr> | |
| 19 | - | <th>Name</th> | |
| 20 | - | <th>Created</th> | |
| 21 | - | <th>Size</th> | |
| 22 | - | <th>Action</th> | |
| 23 | - | </tr> | |
| 24 | - | </thead> --> | |
| 25 | 17 | <tbody> | |
| 26 | 18 | {{ | |
| 27 | 19 | range.Images | |
| @@ -41,7 +33,7 @@ | |||
| 41 | 33 | hx-get="/htmx/create-container/{{.ID}}" | |
| 42 | 34 | hx-target="#create-container" | |
| 43 | 35 | hx-target-*="#error-message-div-{{.ID}}" | |
| 44 | - | hx-swap="outerHTML" | |
| 36 | + | hx-swap="innerHTML" | |
| 45 | 37 | class="py-2 px-4" | |
| 46 | 38 | > | |
| 47 | 39 | <span title="Deploy a container using this image" class="iconoir-add-circle text-xl text-blue-800 font-bold"></span> | |
| @@ -77,3 +69,26 @@ | |||
| 77 | 69 | <div id="upload-image"></div> | |
| 78 | 70 | <div id="create-container"></div> | |
| 79 | 71 | </div> | |
| 72 | + | ||
| 73 | + | <script> | |
| 74 | + | // Hide upload form if add button is clicked | |
| 75 | + | document.querySelectorAll('[id^="add-button-img-"]').forEach((button) => { | |
| 76 | + | button.addEventListener("click", () => { | |
| 77 | + | document.getElementById("upload-image").innerHTML = ""; | |
| 78 | + | }); | |
| 79 | + | }); | |
| 80 | + | ||
| 81 | + | // Hide create container form if upload button is clicke | |
| 82 | + | document.getElementById("upload-button").addEventListener("click", () => { | |
| 83 | + | document.getElementById("create-container").innerHTML = ""; | |
| 84 | + | }); | |
| 85 | + | ||
| 86 | + | // Remove image from list if remove button is clicked (after confirmation) | |
| 87 | + | document.querySelectorAll('[id^="remove-button-img-"]').forEach((button) => { | |
| 88 | + | button.addEventListener("click", () => { | |
| 89 | + | const id = button.id.split("-")[3]; | |
| 90 | + | const tr = document.getElementById(`img-${id}`); | |
| 91 | + | tr.style.display = "none"; | |
| 92 | + | }); | |
| 93 | + | }); | |
| 94 | + | </script>⏎̸ | |
| @@ -6,7 +6,7 @@ | |||||
| 6 | id="upload-button" | 6 | id="upload-button" | ||
| 7 | hx-get="/htmx/upload-image" | 7 | hx-get="/htmx/upload-image" | ||
| 8 | hx-target="#upload-image" | 8 | hx-target="#upload-image" | ||
| 9 | - | hx-swap="outerHTML" | 9 | + | hx-swap="innerHTML" |
| 10 | class="py-1 px-2 bg-blue-500 hover:bg-blue-700 text-white font-bold rounded" | 10 | class="py-1 px-2 bg-blue-500 hover:bg-blue-700 text-white font-bold rounded" | ||
| 11 | > | 11 | > | ||
| 12 | <span class="iconoir-upload text-xl align-middle"></span> | 12 | <span class="iconoir-upload text-xl align-middle"></span> | ||
| @@ -14,14 +14,6 @@ | |||||
| 14 | </button> | 14 | </button> | ||
| 15 | </div> | 15 | </div> | ||
| 16 | <table class="p-4 border-t-2"> | 16 | <table class="p-4 border-t-2"> | ||
| 17 | - | <!-- <thead> | |||
| 18 | - | <tr> | |||
| 19 | - | <th>Name</th> | |||
| 20 | - | <th>Created</th> | |||
| 21 | - | <th>Size</th> | |||
| 22 | - | <th>Action</th> | |||
| 23 | - | </tr> | |||
| 24 | - | </thead> --> | |||
| 25 | <tbody> | 17 | <tbody> | ||
| 26 | {{ | 18 | {{ | ||
| 27 | range.Images | 19 | range.Images | ||
| @@ -41,7 +33,7 @@ | |||||
| 41 | hx-get="/htmx/create-container/{{.ID}}" | 33 | hx-get="/htmx/create-container/{{.ID}}" | ||
| 42 | hx-target="#create-container" | 34 | hx-target="#create-container" | ||
| 43 | hx-target-*="#error-message-div-{{.ID}}" | 35 | hx-target-*="#error-message-div-{{.ID}}" | ||
| 44 | - | hx-swap="outerHTML" | 36 | + | hx-swap="innerHTML" |
| 45 | class="py-2 px-4" | 37 | class="py-2 px-4" | ||
| 46 | > | 38 | > | ||
| 47 | <span title="Deploy a container using this image" class="iconoir-add-circle text-xl text-blue-800 font-bold"></span> | 39 | <span title="Deploy a container using this image" class="iconoir-add-circle text-xl text-blue-800 font-bold"></span> | ||
| @@ -77,3 +69,26 @@ | |||||
| 77 | <div id="upload-image"></div> | 69 | <div id="upload-image"></div> | ||
| 78 | <div id="create-container"></div> | 70 | <div id="create-container"></div> | ||
| 79 | </div> | 71 | </div> | ||
| 72 | + | ||||
| 73 | + | <script> | |||
| 74 | + | // Hide upload form if add button is clicked | |||
| 75 | + | document.querySelectorAll('[id^="add-button-img-"]').forEach((button) => { | |||
| 76 | + | button.addEventListener("click", () => { | |||
| 77 | + | document.getElementById("upload-image").innerHTML = ""; | |||
| 78 | + | }); | |||
| 79 | + | }); | |||
| 80 | + | ||||
| 81 | + | // Hide create container form if upload button is clicke | |||
| 82 | + | document.getElementById("upload-button").addEventListener("click", () => { | |||
| 83 | + | document.getElementById("create-container").innerHTML = ""; | |||
| 84 | + | }); | |||
| 85 | + | ||||
| 86 | + | // Remove image from list if remove button is clicked (after confirmation) | |||
| 87 | + | document.querySelectorAll('[id^="remove-button-img-"]').forEach((button) => { | |||
| 88 | + | button.addEventListener("click", () => { | |||
| 89 | + | const id = button.id.split("-")[3]; | |||
| 90 | + | const tr = document.getElementById(`img-${id}`); | |||
| 91 | + | tr.style.display = "none"; | |||
| 92 | + | }); | |||
| 93 | + | }); | |||
| 94 | + | </script>⏎̸ | |||
M internal/httpserve/handler/uploadimage.go +11 -6
| @@ -1,7 +1,8 @@ | |||
| 1 | 1 | package handler | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | - | "fmt" | |
| 4 | + | "bytes" | |
| 5 | + | "io" | |
| 5 | 6 | "net/http" | |
| 6 | 7 | ||
| 7 | 8 | "github.com/bnema/gordon/internal/app" | |
| @@ -37,23 +38,27 @@ func UploadImagePOSTHandler(c echo.Context, a *app.App) error { | |||
| 37 | 38 | if err := c.Request().ParseMultipartForm(MaxUploadSize); err != nil { | |
| 38 | 39 | return c.String(http.StatusRequestEntityTooLarge, "File size exceeded") | |
| 39 | 40 | } | |
| 41 | + | ||
| 40 | 42 | // Get the file from the form | |
| 41 | 43 | file, header, err := c.Request().FormFile("file") | |
| 42 | 44 | if err != nil { | |
| 43 | 45 | return sendError(c, err) | |
| 44 | 46 | } | |
| 45 | - | defer file.Close() | |
| 47 | + | ||
| 48 | + | // Get the file size | |
| 49 | + | buf := new(bytes.Buffer) | |
| 50 | + | _, err = io.Copy(buf, file) | |
| 51 | + | if err != nil { | |
| 52 | + | return sendError(c, err) | |
| 53 | + | } | |
| 46 | 54 | ||
| 47 | 55 | // Get the filename | |
| 48 | 56 | filename := header.Filename | |
| 49 | - | fmt.Println("Uploaded file:", filename) | |
| 50 | 57 | ||
| 51 | 58 | // Save the image to the storage directory | |
| 52 | - | imageId, err := store.SaveImageToStorage(&a.Config, filename, file) | |
| 59 | + | _, err = store.SaveImageToStorage(&a.Config, filename, buf) | |
| 53 | 60 | if err != nil { | |
| 54 | 61 | return sendError(c, err) | |
| 55 | 62 | } | |
| 56 | - | // Just print for now but add to the database later | |
| 57 | - | fmt.Println(imageId) | |
| 58 | 63 | return c.HTML(http.StatusOK, "Success") | |
| 59 | 64 | } | |
| @@ -1,7 +1,8 @@ | |||||
| 1 | package handler | 1 | package handler | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | - | "fmt" | 4 | + | "bytes" |
| 5 | + | "io" | |||
| 5 | "net/http" | 6 | "net/http" | ||
| 6 | 7 | ||||
| 7 | "github.com/bnema/gordon/internal/app" | 8 | "github.com/bnema/gordon/internal/app" | ||
| @@ -37,23 +38,27 @@ func UploadImagePOSTHandler(c echo.Context, a *app.App) error { | |||||
| 37 | if err := c.Request().ParseMultipartForm(MaxUploadSize); err != nil { | 38 | if err := c.Request().ParseMultipartForm(MaxUploadSize); err != nil { | ||
| 38 | return c.String(http.StatusRequestEntityTooLarge, "File size exceeded") | 39 | return c.String(http.StatusRequestEntityTooLarge, "File size exceeded") | ||
| 39 | } | 40 | } | ||
| 41 | + | ||||
| 40 | // Get the file from the form | 42 | // Get the file from the form | ||
| 41 | file, header, err := c.Request().FormFile("file") | 43 | file, header, err := c.Request().FormFile("file") | ||
| 42 | if err != nil { | 44 | if err != nil { | ||
| 43 | return sendError(c, err) | 45 | return sendError(c, err) | ||
| 44 | } | 46 | } | ||
| 45 | - | defer file.Close() | 47 | + | |
| 48 | + | // Get the file size | |||
| 49 | + | buf := new(bytes.Buffer) | |||
| 50 | + | _, err = io.Copy(buf, file) | |||
| 51 | + | if err != nil { | |||
| 52 | + | return sendError(c, err) | |||
| 53 | + | } | |||
| 46 | 54 | ||||
| 47 | // Get the filename | 55 | // Get the filename | ||
| 48 | filename := header.Filename | 56 | filename := header.Filename | ||
| 49 | - | fmt.Println("Uploaded file:", filename) | |||
| 50 | 57 | ||||
| 51 | // Save the image to the storage directory | 58 | // Save the image to the storage directory | ||
| 52 | - | imageId, err := store.SaveImageToStorage(&a.Config, filename, file) | 59 | + | _, err = store.SaveImageToStorage(&a.Config, filename, buf) |
| 53 | if err != nil { | 60 | if err != nil { | ||
| 54 | return sendError(c, err) | 61 | return sendError(c, err) | ||
| 55 | } | 62 | } | ||
| 56 | - | // Just print for now but add to the database later | |||
| 57 | - | fmt.Println(imageId) | |||
| 58 | return c.HTML(http.StatusOK, "Success") | 63 | return c.HTML(http.StatusOK, "Success") | ||
| 59 | } | 64 | } | ||
M internal/webui/public/assets/js/custom.js +2 -1
| @@ -5,6 +5,7 @@ document.body.addEventListener("htmx:afterOnLoad", function(event) { | |||
| 5 | 5 | ) { | |
| 6 | 6 | setTimeout(function() { | |
| 7 | 7 | location.reload(); | |
| 8 | - | }, 3000); | |
| 8 | + | }, 2000); | |
| 9 | 9 | } | |
| 10 | 10 | }); | |
| 11 | + | ||
| @@ -5,6 +5,7 @@ document.body.addEventListener("htmx:afterOnLoad", function(event) { | |||||
| 5 | ) { | 5 | ) { | ||
| 6 | setTimeout(function() { | 6 | setTimeout(function() { | ||
| 7 | location.reload(); | 7 | location.reload(); | ||
| 8 | - | }, 3000); | 8 | + | }, 2000); |
| 9 | } | 9 | } | ||
| 10 | }); | 10 | }); | ||
| 11 | + | ||||
M pkg/utils/docker/images.go +7 -15
| @@ -2,7 +2,6 @@ package docker | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "context" | |
| 5 | - | "fmt" | |
| 6 | 5 | "os" | |
| 7 | 6 | ||
| 8 | 7 | "github.com/docker/docker/api/types" | |
| @@ -20,10 +19,9 @@ func ListContainerImages() ([]types.ImageSummary, error) { | |||
| 20 | 19 | ||
| 21 | 20 | return images, nil | |
| 22 | 21 | } | |
| 23 | - | func DeleteContainerImage(imageID string) error { | |
| 24 | - | // Check if the Docker client has been initialized | |
| 25 | 22 | ||
| 26 | - | // Delete the image using the Docker client | |
| 23 | + | // DeleteContainerImage deletes an image from the Docker engine | |
| 24 | + | func DeleteContainerImage(imageID string) error { | |
| 27 | 25 | _, err := dockerCli.ImageRemove(context.Background(), imageID, types.ImageRemoveOptions{}) | |
| 28 | 26 | if err != nil { | |
| 29 | 27 | return err | |
| @@ -32,22 +30,20 @@ func DeleteContainerImage(imageID string) error { | |||
| 32 | 30 | return nil | |
| 33 | 31 | } | |
| 34 | 32 | ||
| 33 | + | // ImportImageToEngine imports an image to the Docker engine | |
| 35 | 34 | func ImportImageToEngine(imagePath string) (string, error) { | |
| 36 | - | // Check if the Docker client has been initialized | |
| 37 | - | CheckIfInitialized() | |
| 38 | - | ||
| 39 | 35 | // Open the image file | |
| 40 | 36 | imageFile, err := os.Open(imagePath) | |
| 41 | 37 | if err != nil { | |
| 42 | 38 | return "", err | |
| 43 | 39 | } | |
| 44 | - | defer imageFile.Close() | |
| 45 | 40 | ||
| 46 | - | // Import the image into Docker | |
| 47 | 41 | _, err = dockerCli.ImageLoad(context.Background(), imageFile, false) | |
| 48 | 42 | if err != nil { | |
| 49 | 43 | return "", err | |
| 50 | 44 | } | |
| 45 | + | // Close the image file | |
| 46 | + | imageFile.Close() | |
| 51 | 47 | ||
| 52 | 48 | // List all images | |
| 53 | 49 | images, err := dockerCli.ImageList(context.Background(), types.ImageListOptions{}) | |
| @@ -59,18 +55,14 @@ func ImportImageToEngine(imagePath string) (string, error) { | |||
| 59 | 55 | var imageID string | |
| 60 | 56 | for _, image := range images { | |
| 61 | 57 | for _, tag := range image.RepoTags { | |
| 62 | - | if tag == "alpine:latest" { | |
| 58 | + | if tag == "<none>:<none>" { | |
| 63 | 59 | imageID = image.ID | |
| 64 | - | break | |
| 65 | 60 | } | |
| 66 | 61 | } | |
| 67 | - | if imageID != "" { | |
| 68 | - | break | |
| 69 | - | } | |
| 70 | 62 | } | |
| 71 | 63 | ||
| 72 | 64 | if imageID == "" { | |
| 73 | - | return "", fmt.Errorf("could not find the loaded image") | |
| 65 | + | return "", err | |
| 74 | 66 | } | |
| 75 | 67 | ||
| 76 | 68 | return imageID, nil | |
| @@ -2,7 +2,6 @@ package docker | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "context" | 4 | "context" | ||
| 5 | - | "fmt" | |||
| 6 | "os" | 5 | "os" | ||
| 7 | 6 | ||||
| 8 | "github.com/docker/docker/api/types" | 7 | "github.com/docker/docker/api/types" | ||
| @@ -20,10 +19,9 @@ func ListContainerImages() ([]types.ImageSummary, error) { | |||||
| 20 | 19 | ||||
| 21 | return images, nil | 20 | return images, nil | ||
| 22 | } | 21 | } | ||
| 23 | - | func DeleteContainerImage(imageID string) error { | |||
| 24 | - | // Check if the Docker client has been initialized | |||
| 25 | 22 | ||||
| 26 | - | // Delete the image using the Docker client | 23 | + | // DeleteContainerImage deletes an image from the Docker engine |
| 24 | + | func DeleteContainerImage(imageID string) error { | |||
| 27 | _, err := dockerCli.ImageRemove(context.Background(), imageID, types.ImageRemoveOptions{}) | 25 | _, err := dockerCli.ImageRemove(context.Background(), imageID, types.ImageRemoveOptions{}) | ||
| 28 | if err != nil { | 26 | if err != nil { | ||
| 29 | return err | 27 | return err | ||
| @@ -32,22 +30,20 @@ func DeleteContainerImage(imageID string) error { | |||||
| 32 | return nil | 30 | return nil | ||
| 33 | } | 31 | } | ||
| 34 | 32 | ||||
| 33 | + | // ImportImageToEngine imports an image to the Docker engine | |||
| 35 | func ImportImageToEngine(imagePath string) (string, error) { | 34 | func ImportImageToEngine(imagePath string) (string, error) { | ||
| 36 | - | // Check if the Docker client has been initialized | |||
| 37 | - | CheckIfInitialized() | |||
| 38 | - | ||||
| 39 | // Open the image file | 35 | // Open the image file | ||
| 40 | imageFile, err := os.Open(imagePath) | 36 | imageFile, err := os.Open(imagePath) | ||
| 41 | if err != nil { | 37 | if err != nil { | ||
| 42 | return "", err | 38 | return "", err | ||
| 43 | } | 39 | } | ||
| 44 | - | defer imageFile.Close() | |||
| 45 | 40 | ||||
| 46 | - | // Import the image into Docker | |||
| 47 | _, err = dockerCli.ImageLoad(context.Background(), imageFile, false) | 41 | _, err = dockerCli.ImageLoad(context.Background(), imageFile, false) | ||
| 48 | if err != nil { | 42 | if err != nil { | ||
| 49 | return "", err | 43 | return "", err | ||
| 50 | } | 44 | } | ||
| 45 | + | // Close the image file | |||
| 46 | + | imageFile.Close() | |||
| 51 | 47 | ||||
| 52 | // List all images | 48 | // List all images | ||
| 53 | images, err := dockerCli.ImageList(context.Background(), types.ImageListOptions{}) | 49 | images, err := dockerCli.ImageList(context.Background(), types.ImageListOptions{}) | ||
| @@ -59,18 +55,14 @@ func ImportImageToEngine(imagePath string) (string, error) { | |||||
| 59 | var imageID string | 55 | var imageID string | ||
| 60 | for _, image := range images { | 56 | for _, image := range images { | ||
| 61 | for _, tag := range image.RepoTags { | 57 | for _, tag := range image.RepoTags { | ||
| 62 | - | if tag == "alpine:latest" { | 58 | + | if tag == "<none>:<none>" { |
| 63 | imageID = image.ID | 59 | imageID = image.ID | ||
| 64 | - | break | |||
| 65 | } | 60 | } | ||
| 66 | } | 61 | } | ||
| 67 | - | if imageID != "" { | |||
| 68 | - | break | |||
| 69 | - | } | |||
| 70 | } | 62 | } | ||
| 71 | 63 | ||||
| 72 | if imageID == "" { | 64 | if imageID == "" { | ||
| 73 | - | return "", fmt.Errorf("could not find the loaded image") | 65 | + | return "", err |
| 74 | } | 66 | } | ||
| 75 | 67 | ||||
| 76 | return imageID, nil | 68 | return imageID, nil | ||
M pkg/utils/store/storeimages.go +8 -5
| @@ -3,7 +3,6 @@ package store | |||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | 5 | "io" | |
| 6 | - | "mime/multipart" | |
| 7 | 6 | "os" | |
| 8 | 7 | "path/filepath" | |
| 9 | 8 | ||
| @@ -24,7 +23,7 @@ func NewStorageConfig(config *app.AppConfig) *StorageConfig { | |||
| 24 | 23 | } | |
| 25 | 24 | } | |
| 26 | 25 | ||
| 27 | - | func SaveImageToStorage(config *app.AppConfig, filename string, file multipart.File) (string, error) { | |
| 26 | + | func SaveImageToStorage(config *app.AppConfig, filename string, buf io.Reader) (string, error) { | |
| 28 | 27 | // Check if the folder exist if not create it | |
| 29 | 28 | if _, err := os.Stat(config.General.StorageDir); os.IsNotExist(err) { | |
| 30 | 29 | err := os.MkdirAll(config.General.StorageDir, 0755) | |
| @@ -41,18 +40,22 @@ func SaveImageToStorage(config *app.AppConfig, filename string, file multipart.F | |||
| 41 | 40 | if err != nil { | |
| 42 | 41 | return "", fmt.Errorf("failed to open file: %v", err) | |
| 43 | 42 | } | |
| 44 | - | defer outFile.Close() | |
| 45 | 43 | ||
| 46 | 44 | // Write the uploaded file's content to the outFile | |
| 47 | - | _, err = io.Copy(outFile, file) | |
| 45 | + | _, err = io.Copy(outFile, buf) | |
| 48 | 46 | if err != nil { | |
| 49 | 47 | return "", fmt.Errorf("failed to write file: %v", err) | |
| 50 | 48 | } | |
| 51 | 49 | ||
| 50 | + | // Check if file exists | |
| 51 | + | if _, err := os.Stat(saveInPath); os.IsNotExist(err) { | |
| 52 | + | return "", fmt.Errorf("file does not exist: %v", err) | |
| 53 | + | } | |
| 54 | + | ||
| 52 | 55 | // Import the image into Docker | |
| 53 | 56 | imageId, err := docker.ImportImageToEngine(saveInPath) | |
| 54 | 57 | if err != nil { | |
| 55 | - | return "", fmt.Errorf("failed to save image to storage directory: %v", err) | |
| 58 | + | return "", fmt.Errorf("failed to import image to Docker: %v", err) | |
| 56 | 59 | } | |
| 57 | 60 | ||
| 58 | 61 | return imageId, nil | |
| @@ -3,7 +3,6 @@ package store | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | "io" | 5 | "io" | ||
| 6 | - | "mime/multipart" | |||
| 7 | "os" | 6 | "os" | ||
| 8 | "path/filepath" | 7 | "path/filepath" | ||
| 9 | 8 | ||||
| @@ -24,7 +23,7 @@ func NewStorageConfig(config *app.AppConfig) *StorageConfig { | |||||
| 24 | } | 23 | } | ||
| 25 | } | 24 | } | ||
| 26 | 25 | ||||
| 27 | - | func SaveImageToStorage(config *app.AppConfig, filename string, file multipart.File) (string, error) { | 26 | + | func SaveImageToStorage(config *app.AppConfig, filename string, buf io.Reader) (string, error) { |
| 28 | // Check if the folder exist if not create it | 27 | // Check if the folder exist if not create it | ||
| 29 | if _, err := os.Stat(config.General.StorageDir); os.IsNotExist(err) { | 28 | if _, err := os.Stat(config.General.StorageDir); os.IsNotExist(err) { | ||
| 30 | err := os.MkdirAll(config.General.StorageDir, 0755) | 29 | err := os.MkdirAll(config.General.StorageDir, 0755) | ||
| @@ -41,18 +40,22 @@ func SaveImageToStorage(config *app.AppConfig, filename string, file multipart.F | |||||
| 41 | if err != nil { | 40 | if err != nil { | ||
| 42 | return "", fmt.Errorf("failed to open file: %v", err) | 41 | return "", fmt.Errorf("failed to open file: %v", err) | ||
| 43 | } | 42 | } | ||
| 44 | - | defer outFile.Close() | |||
| 45 | 43 | ||||
| 46 | // Write the uploaded file's content to the outFile | 44 | // Write the uploaded file's content to the outFile | ||
| 47 | - | _, err = io.Copy(outFile, file) | 45 | + | _, err = io.Copy(outFile, buf) |
| 48 | if err != nil { | 46 | if err != nil { | ||
| 49 | return "", fmt.Errorf("failed to write file: %v", err) | 47 | return "", fmt.Errorf("failed to write file: %v", err) | ||
| 50 | } | 48 | } | ||
| 51 | 49 | ||||
| 50 | + | // Check if file exists | |||
| 51 | + | if _, err := os.Stat(saveInPath); os.IsNotExist(err) { | |||
| 52 | + | return "", fmt.Errorf("file does not exist: %v", err) | |||
| 53 | + | } | |||
| 54 | + | ||||
| 52 | // Import the image into Docker | 55 | // Import the image into Docker | ||
| 53 | imageId, err := docker.ImportImageToEngine(saveInPath) | 56 | imageId, err := docker.ImportImageToEngine(saveInPath) | ||
| 54 | if err != nil { | 57 | if err != nil { | ||
| 55 | - | return "", fmt.Errorf("failed to save image to storage directory: %v", err) | 58 | + | return "", fmt.Errorf("failed to import image to Docker: %v", err) |
| 56 | } | 59 | } | ||
| 57 | 60 | ||||
| 58 | return imageId, nil | 61 | return imageId, nil | ||