working commit
This commit is contained in:
@@ -15,20 +15,18 @@ import (
|
||||
"mstore/app/router"
|
||||
)
|
||||
|
||||
type xxxResponse struct {
|
||||
Error bool `json:"error" yaml:"error"`
|
||||
Message string `json:"message,omitempty" yaml:"message,omitempty"`
|
||||
Result any `json:"result,omitempty" yaml:"result,result"`
|
||||
}
|
||||
|
||||
type GenericResponse[T any] struct {
|
||||
type Response[T any] struct {
|
||||
Error bool `json:"error" yaml:"error"`
|
||||
Message string `json:"message,omitempty" yaml:"message,omitempty"`
|
||||
Result T `json:"result,omitempty" yaml:"result,result"`
|
||||
}
|
||||
|
||||
func NewResponse[T any]() *Response[T] {
|
||||
return &Response[T]{}
|
||||
}
|
||||
|
||||
func (hand *Handler) SendResult(rctx *router.Context, result any) {
|
||||
response := &GenericResponse[any]{
|
||||
response := &Response[any]{
|
||||
Error: false,
|
||||
Result: result,
|
||||
}
|
||||
@@ -36,7 +34,7 @@ func (hand *Handler) SendResult(rctx *router.Context, result any) {
|
||||
}
|
||||
|
||||
func (hand *Handler) SendError(rctx *router.Context, err error) {
|
||||
response := &GenericResponse[any]{
|
||||
response := &Response[any]{
|
||||
Error: true,
|
||||
Message: err.Error(),
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"mstore/pkg/client"
|
||||
@@ -18,6 +21,24 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func packUserinfo(resurseuri, username, password string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
if !strings.Contains(resurseuri, "://") {
|
||||
resurseuri = "https://" + resurseuri
|
||||
}
|
||||
uri, err := url.Parse(resurseuri)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
uri.Path = path.Clean(uri.Path)
|
||||
if username != "" && password != "" {
|
||||
uri.User = url.UserPassword(username, password)
|
||||
}
|
||||
res = uri.String()
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (util *ImageUtil) CreateImageCmds() *cobra.Command {
|
||||
const defaultTimeout uint64 = 30 // Second
|
||||
|
||||
@@ -101,10 +122,17 @@ func (util *ImageUtil) imageInfo(params *ImageInfoParams) (*ImageInfoResult, err
|
||||
res := &ImageInfoResult{}
|
||||
ctx := context.Background()
|
||||
|
||||
cli := client.NewClientWithAuth(params.Username, params.Password)
|
||||
cli := client.NewClient()
|
||||
timeout := time.Duration(params.Timeout) * time.Second
|
||||
opres, err := cli.ImageInfo(ctx, params.Imagepath, timeout)
|
||||
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
opres, err := cli.ImageInfo(ctx, params.Imagepath, timeout)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.ImageInfo = opres
|
||||
return res, err
|
||||
}
|
||||
@@ -131,10 +159,16 @@ func (util *ImageUtil) pullImage(params *PullImageParams) (*PullImageResult, err
|
||||
ctx := context.Background()
|
||||
res := &PullImageResult{}
|
||||
|
||||
cli := client.NewClientWithAuth(params.Username, params.Password)
|
||||
cli := client.NewClient()
|
||||
timeout := time.Duration(params.Timeout) * time.Second
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
err = cli.PullImage(ctx, params.Imagepath, params.Filepath, timeout)
|
||||
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -159,9 +193,15 @@ func (util *ImageUtil) pushImage(params *PushImageParams) (*PushImageResult, err
|
||||
ctx := context.Background()
|
||||
res := &PushImageResult{}
|
||||
|
||||
cli := client.NewClientWithAuth(params.Username, params.Password)
|
||||
cli := client.NewClient()
|
||||
timeout := time.Duration(params.Timeout) * time.Second
|
||||
params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
err = cli.PushImage(ctx, params.Filepath, params.Imagepath, timeout)
|
||||
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func EncodeBasicAuth(username, password string) string {
|
||||
auth := username + ":" + password
|
||||
return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
|
||||
}
|
||||
|
||||
func ParseBasicAuth(basicFields string) (string, string, error) {
|
||||
var err error
|
||||
var username string
|
||||
|
||||
@@ -7,15 +7,20 @@
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package client
|
||||
package auxtool
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
func makeTmpFileName(prefix string) string {
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func MakeTmpFilename(prefix string) string {
|
||||
randBytes := make([]byte, 6)
|
||||
rand.Read(randBytes)
|
||||
suffix := hex.EncodeToString(randBytes)
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"mstore/app/handler"
|
||||
"mstore/app/operator"
|
||||
"mstore/pkg/auxhttp"
|
||||
)
|
||||
|
||||
func (cli *Client) CreateAccount(ctx context.Context, hosturi, username, password string) error {
|
||||
var err error
|
||||
|
||||
apiuri, err := url.JoinPath(hosturi, "/v3/api/account/get")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
operParams := operator.CreateAccountParams{
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
paramsJson, err := json.Marshal(operParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
respBytes, err := doHTTPCall(ctx, apiuri, paramsJson)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
operRes := handler.NewResponse[operator.CreateAccountResult]()
|
||||
err = json.Unmarshal(respBytes, operRes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !operRes.Error {
|
||||
err = fmt.Errorf("%s", operRes.Message)
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (cli *Client) GetAccount(ctx context.Context, hosturi, id, username string) error {
|
||||
var err error
|
||||
|
||||
apipath, err := url.JoinPath(hosturi, "/v3/api/account/get")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
operParams := operator.GetAccountParams{
|
||||
Username: username,
|
||||
AccountID: id,
|
||||
}
|
||||
paramsJson, err := json.Marshal(operParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
respBytes, err := doHTTPCall(ctx, apipath, paramsJson)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
operRes := handler.NewResponse[operator.CreateAccountResult]()
|
||||
err = json.Unmarshal(respBytes, operRes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !operRes.Error {
|
||||
err = fmt.Errorf("%s", operRes.Message)
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func doHTTPCall(ctx context.Context, apiuri string, reqBytes []byte) ([]byte, error) {
|
||||
var err error
|
||||
respBytes := make([]byte, 0)
|
||||
|
||||
apiuri, username, password, err := repackServiceURI(apiuri)
|
||||
if err != nil {
|
||||
return respBytes, err
|
||||
}
|
||||
reqBuffer := bytes.NewBuffer(reqBytes)
|
||||
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiuri, reqBuffer)
|
||||
if err != nil {
|
||||
return respBytes, err
|
||||
}
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
if username != "" && password != "" {
|
||||
basicHeader := auxhttp.EncodeBasicAuth(username, password)
|
||||
httpReq.Header.Add("Authorization", basicHeader)
|
||||
}
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
httpClient := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
httpResp, err := httpClient.Do(httpReq)
|
||||
if err != nil {
|
||||
return respBytes, err
|
||||
}
|
||||
defer httpResp.Body.Close()
|
||||
if httpResp.StatusCode != http.StatusOK {
|
||||
err := fmt.Errorf("Wrong StatusCode header: %s", httpResp.Status)
|
||||
return respBytes, err
|
||||
}
|
||||
respBuffer := bytes.NewBuffer(nil)
|
||||
_, err = io.Copy(respBuffer, httpResp.Body)
|
||||
if err != nil {
|
||||
return respBytes, err
|
||||
}
|
||||
respBytes = respBuffer.Bytes()
|
||||
return respBytes, err
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
serviceAPI = "/v3/api/service/"
|
||||
fileAPI = "/v3/api/file/"
|
||||
filesAPI = "/v3/api/files/"
|
||||
)
|
||||
|
||||
func encodeBasicAuth(username, password string) string {
|
||||
auth := username + ":" + password
|
||||
return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
|
||||
}
|
||||
|
||||
func convertServiceRefer(ref string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
if !strings.Contains(ref, "://") {
|
||||
ref = "https://" + ref
|
||||
}
|
||||
url, err := url.Parse(ref)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
url.Path = path.Clean(url.Path)
|
||||
url.Path = path.Join(serviceAPI, url.Path)
|
||||
url.User = nil
|
||||
res = url.String()
|
||||
return res, err
|
||||
}
|
||||
|
||||
func convertFileRefer(ref string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
if !strings.Contains(ref, "://") {
|
||||
ref = "https://" + ref
|
||||
}
|
||||
url, err := url.Parse(ref)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
url.Path = path.Clean(url.Path)
|
||||
url.Path = path.Join(fileAPI, url.Path)
|
||||
url.User = nil
|
||||
res = url.String()
|
||||
return res, err
|
||||
}
|
||||
|
||||
func convertFilesRefer(ref string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
if !strings.Contains(ref, "://") {
|
||||
ref = "https://" + ref
|
||||
}
|
||||
url, err := url.Parse(ref)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
url.Path = path.Clean(url.Path)
|
||||
url.Path = path.Join(filesAPI, url.Path)
|
||||
url.User = nil
|
||||
res = url.String()
|
||||
return res, err
|
||||
}
|
||||
+21
-14
@@ -13,40 +13,47 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
username string
|
||||
password string
|
||||
}
|
||||
type Client struct{}
|
||||
|
||||
func NewClient() *Client {
|
||||
return &Client{}
|
||||
}
|
||||
|
||||
func NewClientWithAuth(username, password string) *Client {
|
||||
return &Client{
|
||||
username: username,
|
||||
password: password,
|
||||
func convertServiceURI(ref string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
const serviceAPI = "/v3/api/service/"
|
||||
const serviceScheme = "https"
|
||||
uri, err := url.Parse(ref)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
uri.Path = serviceAPI
|
||||
uri.Scheme = serviceScheme
|
||||
res = uri.String()
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (cli *Client) ServiceHello(ctx context.Context, ref string, timeout time.Duration) (bool, error) {
|
||||
func (cli *Client) ServiceHello(ctx context.Context, serviceuri string, timeout time.Duration) (bool, error) {
|
||||
var res bool
|
||||
var err error
|
||||
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
|
||||
ref, err = convertServiceRefer(ref)
|
||||
serviceuri, _, _, err = repackServiceURI(serviceuri)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, ref, nil)
|
||||
serviceuri, err = convertServiceURI(serviceuri)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, serviceuri, nil)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
|
||||
+120
-61
@@ -15,28 +15,17 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"mstore/pkg/auxhttp"
|
||||
)
|
||||
|
||||
func (cli *Client) FileExists(ctx context.Context, ref string) (bool, error) {
|
||||
var res bool
|
||||
var err error
|
||||
|
||||
ref, err = convertFileRefer(ref)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, ref, nil)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
if cli.username != "" && cli.password != "" {
|
||||
req.Header.Add("Authorization", encodeBasicAuth(cli.username, cli.password))
|
||||
}
|
||||
|
||||
func makeHTTPClient() *http.Client {
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
@@ -45,6 +34,80 @@ func (cli *Client) FileExists(ctx context.Context, ref string) (bool, error) {
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
func convertFileURI(fileuri string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
uri, err := url.Parse(fileuri)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
const fileAPI = "/v3/api/file/"
|
||||
uri.Path, err = url.JoinPath(fileAPI, uri.Path)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res = uri.String()
|
||||
return res, err
|
||||
}
|
||||
|
||||
func convertFilesURI(fileuri string) (string, error) {
|
||||
var err error
|
||||
var res string
|
||||
uri, err := url.Parse(fileuri)
|
||||
const filesAPI = "/v3/api/files/"
|
||||
uri.Path, err = url.JoinPath(filesAPI, uri.Path)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res = uri.String()
|
||||
return res, err
|
||||
}
|
||||
|
||||
func repackServiceURI(fileuri string) (string, string, string, error) {
|
||||
var err error
|
||||
var res, username, password string
|
||||
if !strings.Contains(fileuri, "://") {
|
||||
fileuri = "https://" + fileuri
|
||||
}
|
||||
uri, err := url.Parse(fileuri)
|
||||
if err != nil {
|
||||
return res, username, password, err
|
||||
}
|
||||
uri.Path = path.Clean(uri.Path)
|
||||
if uri.User != nil {
|
||||
username = uri.User.Username()
|
||||
password, _ = uri.User.Password()
|
||||
}
|
||||
uri.User = nil
|
||||
uri.Scheme = "https"
|
||||
res = uri.String()
|
||||
return res, username, password, err
|
||||
}
|
||||
|
||||
func (cli *Client) FileExists(ctx context.Context, fileuri string) (bool, error) {
|
||||
var res bool
|
||||
var err error
|
||||
fileuri, username, password, err := repackServiceURI(fileuri)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
fileuri, err = convertFileURI(fileuri)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, fileuri, nil)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
if username != "" && password != "" {
|
||||
basic := auxhttp.EncodeBasicAuth(username, password)
|
||||
req.Header.Add("Authorization", basic)
|
||||
}
|
||||
client := makeHTTPClient()
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return res, err
|
||||
@@ -56,9 +119,14 @@ func (cli *Client) FileExists(ctx context.Context, ref string) (bool, error) {
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (cli *Client) PutFile(ctx context.Context, filename, ref string) error {
|
||||
func (cli *Client) PutFile(ctx context.Context, filename, fileuri string) error {
|
||||
var err error
|
||||
ref, err = convertFileRefer(ref)
|
||||
fileuri, username, password, err := repackServiceURI(fileuri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fileuri, err = convertFileURI(fileuri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -68,23 +136,10 @@ func (cli *Client) PutFile(ctx context.Context, filename, ref string) error {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, ref, file)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fileuri, file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cli.username != "" && cli.password != "" {
|
||||
req.Header.Add("Authorization", encodeBasicAuth(cli.username, cli.password))
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
fileinfo, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -93,6 +148,11 @@ func (cli *Client) PutFile(ctx context.Context, filename, ref string) error {
|
||||
|
||||
req.ContentLength = filesize
|
||||
req.Header.Set("Content-Type", "application/octet-stream")
|
||||
if username != "" && password != "" {
|
||||
basic := auxhttp.EncodeBasicAuth(username, password)
|
||||
req.Header.Add("Authorization", basic)
|
||||
}
|
||||
client := makeHTTPClient()
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
@@ -107,31 +167,31 @@ func (cli *Client) PutFile(ctx context.Context, filename, ref string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (cli *Client) GetFile(ctx context.Context, ref, filename string) (int64, error) {
|
||||
func (cli *Client) GetFile(ctx context.Context, fileuri, filename string) (int64, error) {
|
||||
var err error
|
||||
var size int64
|
||||
ref, err = convertFileRefer(ref)
|
||||
|
||||
fileuri, username, password, err := repackServiceURI(fileuri)
|
||||
if err != nil {
|
||||
return size, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, ref, nil)
|
||||
fileuri, err = convertFileURI(fileuri)
|
||||
if err != nil {
|
||||
return size, err
|
||||
}
|
||||
|
||||
if cli.username != "" && cli.password != "" {
|
||||
req.Header.Add("Authorization", encodeBasicAuth(cli.username, cli.password))
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fileuri, nil)
|
||||
if err != nil {
|
||||
return size, err
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
if username != "" && password != "" {
|
||||
basic := auxhttp.EncodeBasicAuth(username, password)
|
||||
req.Header.Add("Authorization", basic)
|
||||
}
|
||||
|
||||
client := makeHTTPClient()
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return size, err
|
||||
@@ -172,29 +232,28 @@ func (cli *Client) GetFile(ctx context.Context, ref, filename string) (int64, er
|
||||
return size, err
|
||||
}
|
||||
|
||||
func (cli *Client) DeleteFile(ctx context.Context, ref, filename string) error {
|
||||
func (cli *Client) DeleteFile(ctx context.Context, fileuri, filename string) error {
|
||||
var err error
|
||||
ref, err = convertFileRefer(ref)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, ref, nil)
|
||||
|
||||
fileuri, username, password, err := repackServiceURI(fileuri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cli.username != "" && cli.password != "" {
|
||||
req.Header.Add("Authorization", encodeBasicAuth(cli.username, cli.password))
|
||||
fileuri, err = convertFileURI(fileuri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, fileuri, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if username != "" && password != "" {
|
||||
basic := auxhttp.EncodeBasicAuth(username, password)
|
||||
req.Header.Add("Authorization", basic)
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
client := makeHTTPClient()
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -12,6 +12,8 @@ package client
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type roundTripper struct{}
|
||||
@@ -25,3 +27,26 @@ func (t *roundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
}
|
||||
return httpTransport.RoundTrip(r)
|
||||
}
|
||||
|
||||
func repackReference(ref string) (string, string, string, error) {
|
||||
var err error
|
||||
var username string
|
||||
var password string
|
||||
if !strings.Contains(ref, `://`) {
|
||||
ref = "https://" + ref
|
||||
}
|
||||
uri, err := url.Parse(ref)
|
||||
if err != nil {
|
||||
return ref, username, password, err
|
||||
}
|
||||
username = uri.User.Username()
|
||||
password, _ = uri.User.Password()
|
||||
uri.User = nil
|
||||
|
||||
uri.Path, _ = url.JoinPath("/", uri.Path)
|
||||
if err != nil {
|
||||
return ref, username, password, err
|
||||
}
|
||||
ref = uri.Host + uri.Path
|
||||
return ref, username, password, err
|
||||
}
|
||||
|
||||
+10
-7
@@ -31,8 +31,11 @@ func (cli *Client) ImageInfo(ctx context.Context, imagepath string, timeout time
|
||||
var err error
|
||||
res := &ImageDescr{}
|
||||
|
||||
imagepath, username, password, err := repackReference(imagepath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, timeout)
|
||||
|
||||
options := make([]crane.Option, 0)
|
||||
options = append(options, crane.WithContext(ctx))
|
||||
|
||||
@@ -45,7 +48,7 @@ func (cli *Client) ImageInfo(ctx context.Context, imagepath string, timeout time
|
||||
return res, err
|
||||
}
|
||||
|
||||
if cli.username != "" && cli.password != "" {
|
||||
if username != "" && password != "" {
|
||||
defaultTransport := &roundTripper{}
|
||||
scopes := []string{repo.Scope(transport.PullScope)}
|
||||
|
||||
@@ -55,8 +58,8 @@ func (cli *Client) ImageInfo(ctx context.Context, imagepath string, timeout time
|
||||
return res, err
|
||||
}
|
||||
basicAuth := &authn.Basic{
|
||||
Username: cli.username,
|
||||
Password: cli.password,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
|
||||
if err != nil {
|
||||
@@ -90,7 +93,7 @@ func (cli *Client) ImageInfo(ctx context.Context, imagepath string, timeout time
|
||||
remoteOptions := make([]remote.Option, 0)
|
||||
remoteOptions = append(remoteOptions, remote.WithContext(ctx))
|
||||
|
||||
if cli.username != "" && cli.password != "" {
|
||||
if username != "" && password != "" {
|
||||
defaultTransport := &roundTripper{}
|
||||
scopes := []string{repo.Scope(transport.PullScope)}
|
||||
|
||||
@@ -100,8 +103,8 @@ func (cli *Client) ImageInfo(ctx context.Context, imagepath string, timeout time
|
||||
return res, err
|
||||
}
|
||||
basicAuth := &authn.Basic{
|
||||
Username: cli.username,
|
||||
Password: cli.password,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
|
||||
if err != nil {
|
||||
|
||||
+10
-4
@@ -14,6 +14,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"mstore/pkg/auxtool"
|
||||
"mstore/pkg/auxutar"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
@@ -26,10 +27,15 @@ func (cli *Client) PullImage(ctx context.Context, filepath, imagepath string, ti
|
||||
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 cli.username != "" && cli.password != "" {
|
||||
if username != "" && password != "" {
|
||||
ref, err := name.ParseReference(imagepath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -48,8 +54,8 @@ func (cli *Client) PullImage(ctx context.Context, filepath, imagepath string, ti
|
||||
return err
|
||||
}
|
||||
basicAuth := &authn.Basic{
|
||||
Username: cli.username,
|
||||
Password: cli.password,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
|
||||
if err != nil {
|
||||
@@ -65,7 +71,7 @@ func (cli *Client) PullImage(ctx context.Context, filepath, imagepath string, ti
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dstdir := makeTmpFileName(filepath)
|
||||
dstdir := auxtool.MakeTmpFilename(filepath)
|
||||
err = os.MkdirAll(dstdir, 0750)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+10
-4
@@ -15,6 +15,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"mstore/pkg/auxtool"
|
||||
"mstore/pkg/auxutar"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
@@ -29,9 +30,14 @@ func (cli *Client) PushImage(ctx context.Context, filepath, imagepath string, ti
|
||||
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 cli.username != "" && cli.password != "" {
|
||||
if username != "" && password != "" {
|
||||
ref, err := name.ParseReference(imagepath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -53,8 +59,8 @@ func (cli *Client) PushImage(ctx context.Context, filepath, imagepath string, ti
|
||||
return err
|
||||
}
|
||||
basicAuth := &authn.Basic{
|
||||
Username: cli.username,
|
||||
Password: cli.password,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
|
||||
authTransport, err := transport.NewWithContext(ctx, reg, basicAuth, defaultTransport, scopes)
|
||||
@@ -67,7 +73,7 @@ func (cli *Client) PushImage(ctx context.Context, filepath, imagepath string, ti
|
||||
options = append(options, crane.WithTransport(defaultTransport))
|
||||
}
|
||||
|
||||
dstdir := makeTmpFileName(filepath)
|
||||
dstdir := auxtool.MakeTmpFilename(filepath)
|
||||
err = auxutar.Unarchive(filepath, dstdir)
|
||||
if err != nil {
|
||||
os.RemoveAll(dstdir)
|
||||
|
||||
Reference in New Issue
Block a user