diff --git a/app/handler/file.go b/app/handler/file.go index 5cb238b..09b7d49 100644 --- a/app/handler/file.go +++ b/app/handler/file.go @@ -18,22 +18,25 @@ import ( const zeroContentLength = "0" -func (hand *Handler) FileExists(rctx *router.Context) { +func (hand *Handler) FileInfo(rctx *router.Context) { filepath, _ := rctx.GetSubpath("filepath") - params := &operator.FileExistsParams{ + params := &operator.FileInfoParams{ Filepath: filepath, } ctx := rctx.GetContext() - code, res, err := hand.oper.FileExists(ctx, params) + code, res, err := hand.oper.FileInfo(ctx, params) if err != nil { - hand.logg.Errorf("FileExists error: %v", err) + hand.logg.Errorf("FileInfo error: %v", err) rctx.SetStatus(code) return } + rctx.SetHeader("Content-Collection", res.ContentCollection) + rctx.SetHeader("Content-Name", res.ContentName) rctx.SetHeader("Content-Type", res.ContentType) rctx.SetHeader("Content-Size", res.ContentSize) rctx.SetHeader("Content-Digest", res.ContentDigest) + rctx.SetHeader("Content-Length", zeroContentLength) rctx.SetStatus(code) } diff --git a/app/maindb/account.go b/app/maindb/account.go index 4116c1e..4e1796a 100644 --- a/app/maindb/account.go +++ b/app/maindb/account.go @@ -21,7 +21,6 @@ func (db *Database) InsertAccount(ctx context.Context, account *descr.Account) e func (db *Database) UpdateAccountByID(ctx context.Context, accountID string, account *descr.Account) error { var err error - request := `UPDATE accounts SET username = $1, passhash = $2, disabled = $3, updated_at = $4 WHERE id = $6` _, err = db.db.Exec(request, account.Username, account.Passhash, account.Disabled, account.UpdatedAt, accountID) if err != nil { @@ -41,7 +40,7 @@ func (db *Database) ReducedListAccounts(ctx context.Context) ([]descr.Account, e return res, err } -func (db *Database) CompletedListAccounts(ctx context.Context) ([]descr.Account, error) { +func (db *Database) ListAccounts(ctx context.Context) ([]descr.Account, error) { var err error request := `SELECT * FROM accounts` res := make([]descr.Account, 0) @@ -56,6 +55,7 @@ func (db *Database) GetAccountByID(ctx context.Context, accountID string) (bool, var err error var res *descr.Account var exists bool + request := `SELECT * FROM accounts WHERE id = $1 LiMIT 1` dbRes := make([]descr.Account, 0) err = db.db.Select(&dbRes, request, accountID) diff --git a/app/operator/account.go b/app/operator/account.go index 6fae01b..36b4ceb 100644 --- a/app/operator/account.go +++ b/app/operator/account.go @@ -100,15 +100,19 @@ func (oper *Operator) UpdateAccount(ctx context.Context, params *UpdateAccountPa if err != nil { return res, err } + if !accountExists { + err := fmt.Errorf("Account with ID %s dont exists", params.AccountID) + return res, err + } case params.Username != "": accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username) if err != nil { return res, err } - } - if !accountExists { - err := fmt.Errorf("Account with this is or name dont exists") - return res, err + if !accountExists { + err := fmt.Errorf("Account with name %s dont exists", params.Username) + return res, err + } } now := auxtool.TimeNow() if params.NewUsername != "" { @@ -150,15 +154,19 @@ func (oper *Operator) DeleteAccount(ctx context.Context, params *DeleteAccountPa if err != nil { return res, err } + if !accountExists { + err := fmt.Errorf("Account with ID %s dont exists", params.AccountID) + return res, err + } case params.Username != "": accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username) if err != nil { return res, err } - } - if !accountExists { - err := fmt.Errorf("Account with this is or name dont exists") - return res, err + if !accountExists { + err := fmt.Errorf("Account with name %s dont exists", params.Username) + return res, err + } } err = oper.mdb.DeleteAllGrantsForAccountID(ctx, accountDescr.ID) @@ -216,7 +224,7 @@ type GetAccountParams struct { AccountID string } type GetAccountResult struct { - Account *descr.AccountShortDescr `json:"accountDescr"` + Account *descr.AccountShortDescr `json:"account"` } func (oper *Operator) GetAccount(ctx context.Context, params *GetAccountParams) (*GetAccountResult, error) { @@ -227,19 +235,23 @@ func (oper *Operator) GetAccount(ctx context.Context, params *GetAccountParams) var accountExists bool switch { case params.AccountID != "": - accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.Username) + accountExists, accountDescr, err = oper.mdb.GetAccountByID(ctx, params.AccountID) if err != nil { return res, err } + if !accountExists { + err := fmt.Errorf("Account with ID %s dont exists", params.AccountID) + return res, err + } case params.Username != "": accountExists, accountDescr, err = oper.mdb.GetAccountByUsername(ctx, params.Username) if err != nil { return res, err } - } - if !accountExists { - err := fmt.Errorf("Account with this is or name dont exists") - return res, err + if !accountExists { + err := fmt.Errorf("Account with name %s dont exists", params.Username) + return res, err + } } accountShortDescr := &descr.AccountShortDescr{ Username: accountDescr.Username, diff --git a/app/operator/file.go b/app/operator/file.go index e0e45e8..0a52f82 100644 --- a/app/operator/file.go +++ b/app/operator/file.go @@ -23,16 +23,18 @@ import ( "mstore/pkg/auxuuid" ) -// FileExists -type FileExistsParams struct { +// FileInfo +type FileInfoParams struct { Filepath string Source string Dest string } -type FileExistsResult struct { - ContentType string - ContentSize string - ContentDigest string +type FileInfoResult struct { + ContentCollection string + ContentName string + ContentType string + ContentSize string + ContentDigest string } func cleanFilepath(filename string) (string, error) { @@ -40,10 +42,10 @@ func cleanFilepath(filename string) (string, error) { return filepath.Clean(filename), nil } -func (oper *Operator) FileExists(ctx context.Context, param *FileExistsParams) (int, *FileExistsResult, error) { +func (oper *Operator) FileInfo(ctx context.Context, param *FileInfoParams) (int, *FileInfoResult, error) { var err error code := http.StatusOK - res := &FileExistsResult{} + res := &FileInfoResult{} xfilepath, err := cleanFilepath(param.Filepath) if err != nil { @@ -63,10 +65,12 @@ func (oper *Operator) FileExists(ctx context.Context, param *FileExistsParams) ( code = http.StatusNotFound return code, res, err } - res = &FileExistsResult{ - ContentSize: strconv.FormatInt(fileDescr.Size, 10), - ContentType: fileDescr.Type, - ContentDigest: fileDescr.Checksum, + res = &FileInfoResult{ + ContentCollection: fileDescr.Collection, + ContentName: fileDescr.Name, + ContentSize: strconv.FormatInt(fileDescr.Size, 10), + ContentType: fileDescr.Type, + ContentDigest: fileDescr.Checksum, } return code, res, err } diff --git a/app/service/service.go b/app/service/service.go index 792105a..895d9ba 100644 --- a/app/service/service.go +++ b/app/service/service.go @@ -72,10 +72,11 @@ func (svc *Service) Build() error { svc.rout.Get(`/v3/api/service/hello`, svc.hand.SendHello) - svc.rout.Head(`/v3/api/file/{filepath}`, svc.hand.FileExists) + svc.rout.Head(`/v3/api/file/{filepath}`, svc.hand.FileInfo) svc.rout.Put(`/v3/api/file/{filepath}`, svc.hand.PutFile) svc.rout.Get(`/v3/api/file/{filepath}`, svc.hand.GetFile) svc.rout.Delete(`/v3/api/file/{filepath}`, svc.hand.DeleteFile) + svc.rout.Get(`/v3/api/files/{filepath}`, svc.hand.ListFiles) svc.rout.Get(`/v3/api/files/`, svc.hand.ListFiles) diff --git a/cmd/mstorectl/filecmd.go b/cmd/mstorectl/filecmd.go index 8cc2af4..4cad868 100644 --- a/cmd/mstorectl/filecmd.go +++ b/cmd/mstorectl/filecmd.go @@ -10,7 +10,14 @@ package main import ( + "context" + "fmt" + "time" + "github.com/spf13/cobra" + + "mstore/app/descr" + "mstore/pkg/client" ) func (util *FileUtil) CreateFileCmds() *cobra.Command { @@ -18,6 +25,7 @@ func (util *FileUtil) CreateFileCmds() *cobra.Command { Use: "file", Short: "File operation", } + const defaultTimeout uint64 = 10 // PutFile var putFileCmd = &cobra.Command{ Use: "put", @@ -28,6 +36,7 @@ func (util *FileUtil) CreateFileCmds() *cobra.Command { putFileCmd.Flags().StringVarP(&util.putFileParams.Password, "password", "p", "", "Password") putFileCmd.Flags().StringVarP(&util.putFileParams.Source, "src", "s", "", "Source path") putFileCmd.Flags().StringVarP(&util.putFileParams.Dest, "dest", "d", "", "Desctination path") + putFileCmd.Flags().Uint64VarP(&util.putFileParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") subCmd.AddCommand(putFileCmd) @@ -41,22 +50,24 @@ func (util *FileUtil) CreateFileCmds() *cobra.Command { getFileCmd.Flags().StringVarP(&util.getFileParams.Password, "password", "p", "", "Password") getFileCmd.Flags().StringVarP(&util.getFileParams.Source, "src", "s", "", "Source path") getFileCmd.Flags().StringVarP(&util.getFileParams.Dest, "dest", "d", "", "Desctination path") + getFileCmd.Flags().Uint64VarP(&util.getFileParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") subCmd.AddCommand(getFileCmd) - // FileExists - var fileExistsCmd = &cobra.Command{ - Use: "exist", - Short: "Check file into storage", - Run: util.FileExists, + // FileInfo + var fileInfoCmd = &cobra.Command{ + Use: "info", + Short: "Show file information", + Run: util.FileInfo, } - fileExistsCmd.Flags().StringVarP(&util.fileExistsParams.Username, "username", "u", "", "Username") - fileExistsCmd.Flags().StringVarP(&util.fileExistsParams.Password, "password", "p", "", "Password") - fileExistsCmd.Flags().StringVarP(&util.fileExistsParams.Filepath, "path", "d", "", "File path") + fileInfoCmd.Flags().StringVarP(&util.fileInfoParams.Username, "username", "u", "", "Username") + fileInfoCmd.Flags().StringVarP(&util.fileInfoParams.Password, "password", "p", "", "Password") + fileInfoCmd.Flags().StringVarP(&util.fileInfoParams.Filepath, "path", "d", "", "File path") + fileInfoCmd.Flags().Uint64VarP(&util.fileInfoParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") - subCmd.AddCommand(fileExistsCmd) + subCmd.AddCommand(fileInfoCmd) - // FileExists + // DeleteFile var deleteFileCmd = &cobra.Command{ Use: "delete", Short: "Delete file in storage", @@ -65,38 +76,111 @@ func (util *FileUtil) CreateFileCmds() *cobra.Command { deleteFileCmd.Flags().StringVarP(&util.deleteFileParams.Username, "username", "u", "", "Username") deleteFileCmd.Flags().StringVarP(&util.deleteFileParams.Password, "password", "p", "", "Password") deleteFileCmd.Flags().StringVarP(&util.deleteFileParams.Filepath, "path", "d", "", "File path") + deleteFileCmd.Flags().Uint64VarP(&util.deleteFileParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") subCmd.AddCommand(deleteFileCmd) return subCmd } +func (util *FileUtil) CreateFilesCmds() *cobra.Command { + var subCmd = &cobra.Command{ + Use: "files", + Short: "Files operation", + } + const defaultTimeout uint64 = 10 + + // ListFiles + var listFilesCmd = &cobra.Command{ + Use: "list", + Short: "List file in storage", + Run: util.ListFiles, + } + listFilesCmd.Flags().StringVarP(&util.listFilesParams.Username, "username", "u", "", "Username") + listFilesCmd.Flags().StringVarP(&util.listFilesParams.Password, "password", "p", "", "Password") + listFilesCmd.Flags().StringVarP(&util.listFilesParams.Filepath, "catalog", "c", "", "Catalog path") + listFilesCmd.Flags().Uint64VarP(&util.listFilesParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") + listFilesCmd.MarkFlagRequired("catalog") + + subCmd.AddCommand(listFilesCmd) + + return subCmd +} + type FileUtil struct { - fileExistsParams FileExistsParams + fileInfoParams FileInfoParams putFileParams PutFileParams getFileParams GetFileParams deleteFileParams DeleteFileParams + listFilesParams ListFilesParams } -// File exists -type FileExistsParams struct { +// FileInfo +type FileInfoParams struct { Filepath string Username string Password string + Timeout uint64 +} +type FileInfoResult struct { + File *descr.File `json:"file,omitempty"` } -func (util *FileUtil) FileExists(cmd *cobra.Command, args []string) { +func (util *FileUtil) FileInfo(cmd *cobra.Command, args []string) { + res, err := util.fileInfo(&util.fileInfoParams) + printResponse(res, err) } -// Put file +func (util *FileUtil) fileInfo(params *FileInfoParams) (*FileInfoResult, error) { + var err error + res := &FileInfoResult{} + params.Filepath, err = packUserinfo(params.Filepath, params.Username, params.Password) + if err != nil { + return res, err + } + timeout := time.Duration(params.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + exists, opres, err := client.NewClient().FileInfo(ctx, params.Filepath) + if err != nil { + return res, err + } + if !exists { + err = fmt.Errorf("File %s not exists", params.Filepath) + return res, err + } + res.File = opres + return res, err +} + +// PutFile type PutFileParams struct { Source string Dest string Username string Password string + Timeout uint64 } +type PutFileResult struct{} func (util *FileUtil) PutFile(cmd *cobra.Command, args []string) { + res, err := util.putFile(&util.putFileParams) + printResponse(res, err) +} + +func (util *FileUtil) putFile(params *PutFileParams) (*PutFileResult, error) { + var err error + res := &PutFileResult{} + params.Dest, err = packUserinfo(params.Dest, params.Username, params.Password) + if err != nil { + return res, err + } + timeout := time.Duration(params.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + err = client.NewClient().PutFile(ctx, params.Source, params.Dest) + if err != nil { + return res, err + } + return res, err } // Get file @@ -105,17 +189,91 @@ type GetFileParams struct { Dest string Username string Password string + Timeout uint64 } func (util *FileUtil) GetFile(cmd *cobra.Command, args []string) { + res, err := util.getFile(&util.getFileParams) + printResponse(res, err) } -// Delete file +type GetFileResult struct{} + +func (util *FileUtil) getFile(params *GetFileParams) (*GetFileResult, error) { + var err error + res := &GetFileResult{} + params.Dest, err = packUserinfo(params.Source, params.Username, params.Password) + if err != nil { + return res, err + } + timeout := time.Duration(params.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + _, err = client.NewClient().GetFile(ctx, params.Dest, params.Source) + if err != nil { + return res, err + } + return res, err +} + +// DeleteFile type DeleteFileParams struct { Filepath string Username string Password string + Timeout uint64 } +type DeleteFileResult struct{} + func (util *FileUtil) DeleteFile(cmd *cobra.Command, args []string) { + res, err := util.deleteFile(&util.deleteFileParams) + printResponse(res, err) +} +func (util *FileUtil) deleteFile(params *DeleteFileParams) (*DeleteFileResult, error) { + var err error + res := &DeleteFileResult{} + params.Filepath, err = packUserinfo(params.Filepath, params.Username, params.Password) + if err != nil { + return res, err + } + timeout := time.Duration(params.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + err = client.NewClient().DeleteFile(ctx, params.Filepath) + if err != nil { + return res, err + } + return res, err +} + +// ListFiles +type ListFilesParams struct { + Filepath string + Username string + Password string + Timeout uint64 +} + +type ListFilesResult struct { + Files []descr.File `json:"files"` +} + +func (util *FileUtil) ListFiles(cmd *cobra.Command, args []string) { + res, err := util.listFiles(&util.listFilesParams) + printResponse(res, err) +} +func (util *FileUtil) listFiles(params *ListFilesParams) (*ListFilesResult, error) { + var err error + res := &ListFilesResult{} + params.Filepath, err = packUserinfo(params.Filepath, params.Username, params.Password) + if err != nil { + return res, err + } + timeout := time.Duration(params.Timeout) * time.Second + ctx, _ := context.WithTimeout(context.Background(), timeout) + files, err := client.NewClient().ListFiles(ctx, params.Filepath) + if err != nil { + return res, err + } + res.Files = files + return res, err } diff --git a/cmd/mstorectl/imagecmd.go b/cmd/mstorectl/imagecmd.go index d020e7b..be5e9fd 100644 --- a/cmd/mstorectl/imagecmd.go +++ b/cmd/mstorectl/imagecmd.go @@ -129,7 +129,8 @@ func (util *ImageUtil) imageInfo(params *ImageInfoParams) (*ImageInfoResult, err if err != nil { return res, err } - opres, err := cli.ImageInfo(ctx, params.Imagepath, timeout) + ctx, _ = context.WithTimeout(ctx, timeout) + opres, err := cli.ImageInfo(ctx, params.Imagepath) if err != nil { return res, err } @@ -165,7 +166,8 @@ func (util *ImageUtil) pullImage(params *PullImageParams) (*PullImageResult, err if err != nil { return res, err } - err = cli.PullImage(ctx, params.Imagepath, params.Filepath, timeout) + ctx, _ = context.WithTimeout(ctx, timeout) + err = cli.PullImage(ctx, params.Imagepath, params.Filepath) if err != nil { return res, err } @@ -199,7 +201,8 @@ func (util *ImageUtil) pushImage(params *PushImageParams) (*PushImageResult, err if err != nil { return res, err } - err = cli.PushImage(ctx, params.Filepath, params.Imagepath, timeout) + ctx, _ = context.WithTimeout(ctx, timeout) + err = cli.PushImage(ctx, params.Filepath, params.Imagepath) if err != nil { return res, err } diff --git a/cmd/mstorectl/main.go b/cmd/mstorectl/main.go index 3c4032b..07c50be 100644 --- a/cmd/mstorectl/main.go +++ b/cmd/mstorectl/main.go @@ -51,6 +51,7 @@ func (util *Util) Build() error { } rootCmd.CompletionOptions.DisableDefaultCmd = true rootCmd.AddCommand(util.CreateFileCmds()) + rootCmd.AddCommand(util.CreateFilesCmds()) rootCmd.AddCommand(util.CreateImageCmds()) util.rootCmd = rootCmd diff --git a/pkg/client/file.go b/pkg/client/file.go index 118fb44..717cb58 100644 --- a/pkg/client/file.go +++ b/pkg/client/file.go @@ -24,20 +24,21 @@ import ( "mstore/pkg/auxhttp" ) -func (cli *Client) FileExists(ctx context.Context, fileuri string) (bool, error) { - var res bool +func (cli *Client) FileInfo(ctx context.Context, fileuri string) (bool, *descr.File, error) { + var exists bool var err error + file := &descr.File{} fileuri, username, password, err := repackServiceURI(fileuri) if err != nil { - return res, err + return exists, file, err } fileuri, err = convertFileURI(fileuri) if err != nil { - return res, err + return exists, file, err } req, err := http.NewRequestWithContext(ctx, http.MethodHead, fileuri, nil) if err != nil { - return res, err + return exists, file, err } if username != "" && password != "" { basic := auxhttp.EncodeBasicAuth(username, password) @@ -46,13 +47,23 @@ func (cli *Client) FileExists(ctx context.Context, fileuri string) (bool, error) client := makeHTTPClient() resp, err := client.Do(req) if err != nil { - return res, err + return exists, file, err } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { - res = true + file.Collection = resp.Header.Get("Content-Collection") + file.Name = resp.Header.Get("Content-Name") + contentSize := resp.Header.Get("Content-Size") + size, err := strconv.ParseInt(contentSize, 10, 64) + if err != nil { + return exists, file, err + } + file.Size = size + file.Type = resp.Header.Get("Content-Type") + file.Checksum = resp.Header.Get("Content-Digest") + exists = true } - return res, err + return exists, file, err } func (cli *Client) PutFile(ctx context.Context, filename, fileuri string) error { @@ -164,7 +175,7 @@ func (cli *Client) GetFile(ctx context.Context, fileuri, filename string) (int64 return size, err } -func (cli *Client) DeleteFile(ctx context.Context, fileuri, filename string) error { +func (cli *Client) DeleteFile(ctx context.Context, fileuri string) error { var err error fileuri, username, password, err := repackServiceURI(fileuri) @@ -247,7 +258,6 @@ func (cli *Client) ListFiles(ctx context.Context, catalogURI string) ([]descr.Fi err := fmt.Errorf("Mismatch Content-Length and recorded filesize") return res, err } - fmt.Printf("list: %s\n",string(respBytes)) err = json.Unmarshal(respBytes, &res) if err != nil { return res, err diff --git a/pkg/client/filelife_test.go b/pkg/client/filelife_test.go index a1280f2..e36d248 100644 --- a/pkg/client/filelife_test.go +++ b/pkg/client/filelife_test.go @@ -101,9 +101,10 @@ func TestFileLife(t *testing.T) { ctx := context.Background() ctx, _ = context.WithTimeout(ctx, 1*time.Second) - exists, err := cli.FileExists(ctx, srvaddr+"/foo.bin") + exists, file, err := cli.FileInfo(ctx, srvaddr+"/foo.bin") require.NoError(t, err) require.True(t, exists) + require.NotNil(t, file) } { // GetFile @@ -151,9 +152,10 @@ func TestFileLife(t *testing.T) { ctx := context.Background() ctx, _ = context.WithTimeout(ctx, 1*time.Second) - exists, err := cli.FileExists(ctx, srvaddr+"/foo.bin") + exists, _, err := cli.FileInfo(ctx, srvaddr+"/foo.bin") require.NoError(t, err) require.False(t, exists) + } } diff --git a/pkg/client/imageinfo.go b/pkg/client/imageinfo.go index 3738758..11e2985 100644 --- a/pkg/client/imageinfo.go +++ b/pkg/client/imageinfo.go @@ -11,7 +11,6 @@ package client import ( "context" - "time" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/crane" @@ -27,7 +26,7 @@ type ImageDescr struct { Tags []string `json:"avilableTags,omitempty"` } -func (cli *Client) ImageInfo(ctx context.Context, imagepath string, timeout time.Duration) (*ImageDescr, error) { +func (cli *Client) ImageInfo(ctx context.Context, imagepath string) (*ImageDescr, error) { var err error res := &ImageDescr{} @@ -35,7 +34,6 @@ func (cli *Client) ImageInfo(ctx context.Context, imagepath string, timeout time if err != nil { return res, err } - ctx, _ = context.WithTimeout(ctx, timeout) options := make([]crane.Option, 0) options = append(options, crane.WithContext(ctx)) diff --git a/pkg/client/imagelife_test.go b/pkg/client/imagelife_test.go index bb611ce..3cef5a1 100644 --- a/pkg/client/imagelife_test.go +++ b/pkg/client/imagelife_test.go @@ -19,9 +19,10 @@ import ( "mstore/app/server" "github.com/stretchr/testify/require" + "sigs.k8s.io/yaml" ) -func xxxTestImageLife(t *testing.T) { +func TestImageLife(t *testing.T) { var srvport int64 = 10250 srvdir := t.TempDir() srvaddr := fmt.Sprintf("127.0.0.1:%d", srvport) @@ -72,14 +73,24 @@ func xxxTestImageLife(t *testing.T) { require.NoError(t, err) require.True(t, helloRes) } - { // PishImage fmt.Printf("=== PushImage ===\n") cli := NewClient() - ctx := context.Background() - err := cli.PushImage(ctx, "test-oci.img", srvaddr+"/foo/test:123", 1*time.Second) + ctx, _ := context.WithTimeout(context.Background(), 1*time.Second) + err := cli.PushImage(ctx, "test-oci.img", srvaddr+"/foo/test:123") require.NoError(t, err) } + { + // ImageInfo + fmt.Printf("=== ImageInfo ===\n") + cli := NewClient() + ctx, _ := context.WithTimeout(context.Background(), 1*time.Second) + info, err := cli.ImageInfo(ctx, srvaddr+"/foo/test:123") + require.NoError(t, err) + infoYaml, err := yaml.Marshal(info) + require.NoError(t, err) + fmt.Printf("imageInfo:\n%s\n", string(infoYaml)) + } } diff --git a/pkg/client/imagepull.go b/pkg/client/imagepull.go index 2f00f6c..db0efb5 100644 --- a/pkg/client/imagepull.go +++ b/pkg/client/imagepull.go @@ -12,7 +12,6 @@ package client import ( "context" "os" - "time" "mstore/pkg/auxtool" "mstore/pkg/auxutar" @@ -23,9 +22,8 @@ import ( "github.com/google/go-containerregistry/pkg/v1/remote/transport" ) -func (cli *Client) PullImage(ctx context.Context, filepath, imagepath string, timeout time.Duration) error { +func (cli *Client) PullImage(ctx context.Context, filepath, imagepath string) error { var err error - ctx, _ = context.WithTimeout(ctx, timeout) imagepath, username, password, err := repackReference(imagepath) if err != nil { diff --git a/pkg/client/imagepush.go b/pkg/client/imagepush.go index 35ffbfe..7b5f3ca 100644 --- a/pkg/client/imagepush.go +++ b/pkg/client/imagepush.go @@ -13,7 +13,6 @@ import ( "context" "fmt" "os" - "time" "mstore/pkg/auxtool" "mstore/pkg/auxutar" @@ -26,15 +25,13 @@ import ( "github.com/google/go-containerregistry/pkg/v1/remote/transport" ) -func (cli *Client) PushImage(ctx context.Context, filepath, imagepath string, timeout time.Duration) error { +func (cli *Client) PushImage(ctx context.Context, filepath, imagepath string) error { var err error - ctx, _ = context.WithTimeout(ctx, timeout) imagepath, username, password, err := repackReference(imagepath) if err != nil { return err } - options := make([]crane.Option, 0) options = append(options, crane.WithContext(ctx)) if username != "" && password != "" { diff --git a/test/account_test.go b/test/account_test.go index 841e1f3..43e71e3 100644 --- a/test/account_test.go +++ b/test/account_test.go @@ -43,9 +43,10 @@ func TestAccountOperations(t *testing.T) { err = srv.Configure() require.NoError(t, err) - var tmpdir bool - tmpdir = true - if tmpdir { + + useTmpdir := true + + if useTmpdir { srv.SetDatadir(srvdir) srv.SetLogdir(srvdir) srv.SetRundir(srvdir) @@ -79,7 +80,7 @@ func TestAccountOperations(t *testing.T) { fmt.Printf("Response body: %s\n", string(bodyBytes)) } var accountID string - var accountName = "testname" + var accountName = "testname1" { fmt.Printf("=== CreateAccount ===\n") reqpath := `/v3/api/account/create` @@ -123,13 +124,61 @@ func TestAccountOperations(t *testing.T) { require.NoError(t, err) fmt.Printf("Formatted body: \n%s\n", jsonBuffer.String()) - resp := handler.GenericResponse[operator.CreateAccountResult]{} + resp := handler.Response[operator.CreateAccountResult]{} err = json.Unmarshal(bodyBytes, &resp) require.False(t, resp.Error) require.Equal(t, len(resp.Result.AccountID), 36) accountID = resp.Result.AccountID } - fmt.Printf("AccountID: %s", accountID) + fmt.Printf("AccountID: %s\n", accountID) + { + fmt.Printf("=== UpdateAccount ===\n") + reqpath := `/v3/api/account/create` + routepath := `/v3/api/account/create` + + rout := router.NewRouter() + hand := srv.Handler() + require.NotNil(t, hand) + + req := operator.UpdateAccountParams{ + AccountID: accountID, + NewPassword: "newpass", + } + reqdata, err := json.Marshal(req) + require.NoError(t, err) + + reqsize := len(reqdata) + reqsrc := bytes.NewReader(reqdata) + + request, err := http.NewRequest("POST", reqpath, reqsrc) + require.NoError(t, err) + + request.ContentLength = int64(reqsize) + request.Header.Set("Content-Type", "application/json") + + recorder := httptest.NewRecorder() + + rout.Post(routepath, hand.UpdateAccount) + rout.ServeHTTP(recorder, request) + + fmt.Printf("Response code: %d\n", recorder.Code) + + bodyReader := recorder.Body + bodyBytes, err := io.ReadAll(bodyReader) + + fmt.Printf("Response body: %s\n", string(bodyBytes)) + require.Equal(t, http.StatusOK, recorder.Code) + + jsonBuffer := bytes.NewBuffer(nil) + err = json.Indent(jsonBuffer, bodyBytes, "", " ") + require.NoError(t, err) + fmt.Printf("Formatted body: \n%s\n", jsonBuffer.String()) + + resp := handler.Response[operator.UpdateAccountResult]{} + err = json.Unmarshal(bodyBytes, &resp) + require.False(t, resp.Error) + } + { fmt.Printf("=== GetAccount ===\n") reqpath := `/v3/api/account/get` @@ -140,7 +189,7 @@ func TestAccountOperations(t *testing.T) { require.NotNil(t, hand) req := operator.GetAccountParams{ - Username: accountName, + AccountID: accountID, } reqdata, err := json.Marshal(req) require.NoError(t, err) @@ -172,7 +221,7 @@ func TestAccountOperations(t *testing.T) { require.NoError(t, err) fmt.Printf("Formatted body: \n%s\n", jsonBuffer.String()) - resp := handler.GenericResponse[operator.GetAccountResult]{} + resp := handler.Response[operator.GetAccountResult]{} err = json.Unmarshal(bodyBytes, &resp) require.False(t, resp.Error) require.Equal(t, resp.Result.Account.Username, accountName) @@ -217,7 +266,7 @@ func TestAccountOperations(t *testing.T) { require.NoError(t, err) fmt.Printf("Formatted body: \n%s\n", jsonBuffer.String()) - resp := handler.GenericResponse[operator.ListAccountsResult]{} + resp := handler.Response[operator.ListAccountsResult]{} err = json.Unmarshal(bodyBytes, &resp) require.False(t, resp.Error) require.Equal(t, len(resp.Result.Accounts), 1) @@ -233,7 +282,7 @@ func TestAccountOperations(t *testing.T) { require.NotNil(t, hand) req := operator.DeleteAccountParams{ - Username: accountName, + AccountID: accountID, } reqdata, err := json.Marshal(req) require.NoError(t, err) @@ -265,7 +314,7 @@ func TestAccountOperations(t *testing.T) { require.NoError(t, err) fmt.Printf("Formatted body: \n%s\n", jsonBuffer.String()) - resp := handler.GenericResponse[operator.DeleteAccountResult]{} + resp := handler.Response[operator.DeleteAccountResult]{} err = json.Unmarshal(bodyBytes, &resp) require.False(t, resp.Error) } @@ -309,7 +358,7 @@ func TestAccountOperations(t *testing.T) { require.NoError(t, err) fmt.Printf("Formatted body: \n%s\n", jsonBuffer.String()) - resp := handler.GenericResponse[operator.ListAccountsResult]{} + resp := handler.Response[operator.ListAccountsResult]{} err = json.Unmarshal(bodyBytes, &resp) require.False(t, resp.Error) require.Equal(t, len(resp.Result.Accounts), 0)