-
Notifications
You must be signed in to change notification settings - Fork 950
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: add pouch save functionality
Signed-off-by: xiechengsheng <XIE1995@whut.edu.cn>
- Loading branch information
1 parent
c83ff22
commit 175b63f
Showing
15 changed files
with
333 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"io" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
// saveDescription is used to describe save command in detail and auto generate command doc. | ||
var saveDescription = "save an image to a tar archive." | ||
|
||
// SaveCommand use to implement 'save' command. | ||
type SaveCommand struct { | ||
baseCommand | ||
output string | ||
} | ||
|
||
// Init initialize save command. | ||
func (save *SaveCommand) Init(c *Cli) { | ||
save.cli = c | ||
save.cmd = &cobra.Command{ | ||
Use: "save [OPTIONS] IMAGE", | ||
Short: "Save an image to a tar archive or STDOUT", | ||
Long: saveDescription, | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(_ *cobra.Command, args []string) error { | ||
return save.runSave(args) | ||
}, | ||
Example: saveExample(), | ||
} | ||
save.addFlags() | ||
} | ||
|
||
// addFlags adds flags for specific command. | ||
func (save *SaveCommand) addFlags() { | ||
flagSet := save.cmd.Flags() | ||
flagSet.StringVarP(&save.output, "output", "o", "", "Save to a tar archive file, instead of STDOUT") | ||
} | ||
|
||
// runSave is the entry of save command. | ||
func (save *SaveCommand) runSave(args []string) error { | ||
ctx := context.Background() | ||
apiClient := save.cli.Client() | ||
|
||
r, err := apiClient.ImageSave(ctx, args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
defer r.Close() | ||
|
||
out := os.Stdout | ||
if save.output != "" { | ||
out, err = os.Create(save.output) | ||
if err != nil { | ||
return nil | ||
} | ||
defer out.Close() | ||
} | ||
|
||
if _, err := io.Copy(out, r); err != nil { | ||
return err | ||
} | ||
if save.output != "" { | ||
if err := out.Close(); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// saveExample shows examples in save command, and is used in auto-generated cli docs. | ||
func saveExample() string { | ||
return `$ pouch save -o busybox.tar busybox:latest | ||
$ pouch load -i busybox.tar foo | ||
$ pouch images | ||
IMAGE ID IMAGE NAME SIZE | ||
8c811b4aec35 registry.hub.docker.com/library/busybox:latest 710.81 KB | ||
8c811b4aec35 foo:latest 710.81 KB | ||
` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"io" | ||
"net/url" | ||
) | ||
|
||
// ImageSave requests daemon to save an image to a tar archive. | ||
func (client *APIClient) ImageSave(ctx context.Context, imageName string) (io.ReadCloser, error) { | ||
q := url.Values{} | ||
q.Set("name", imageName) | ||
|
||
resp, err := client.get(ctx, "/images/save", q, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return resp.Body, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package client | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestImageSaveServerError(t *testing.T) { | ||
expectedError := "Server error" | ||
|
||
client := &APIClient{ | ||
HTTPCli: newMockClient(errorMockResponse(http.StatusInternalServerError, expectedError)), | ||
} | ||
|
||
_, err := client.ImageSave(context.Background(), "test_image_save_500") | ||
if err == nil || !strings.Contains(err.Error(), expectedError) { | ||
t.Fatalf("expected (%v), got (%v)", expectedError, err) | ||
} | ||
} | ||
|
||
func TestImageSaveOK(t *testing.T) { | ||
expectedImageName := "test_image_save_ok" | ||
expectedURL := "/images/save" | ||
|
||
httpClient := newMockClient(func(req *http.Request) (*http.Response, error) { | ||
if !strings.HasPrefix(req.URL.Path, expectedURL) { | ||
return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL) | ||
} | ||
|
||
if req.Method != "GET" { | ||
return nil, fmt.Errorf("expected GET method, got %s", req.Method) | ||
} | ||
|
||
if got := req.FormValue("name"); got != expectedImageName { | ||
return nil, fmt.Errorf("expected (%s), got %s", expectedImageName, got) | ||
} | ||
|
||
return &http.Response{ | ||
StatusCode: http.StatusOK, | ||
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), | ||
}, nil | ||
}) | ||
|
||
client := &APIClient{ | ||
HTTPCli: httpClient, | ||
} | ||
|
||
if _, err := client.ImageSave(context.Background(), expectedImageName); err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package mgr | ||
|
||
import ( | ||
"context" | ||
"io" | ||
|
||
ociimage "github.com/containerd/containerd/images/oci" | ||
) | ||
|
||
// SaveImage saves image to the oci.v1 format tarstream. | ||
func (mgr *ImageManager) SaveImage(ctx context.Context, idOrRef string) (io.ReadCloser, error) { | ||
_, _, ref, err := mgr.CheckReference(ctx, idOrRef) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
exportedStream, err := mgr.client.SaveImage(ctx, &ociimage.V1Exporter{}, ref.String()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return exportedStream, nil | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.