From 1d4d18136b8d8e6efd9367df492379d0b09a9098 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 27 May 2021 13:51:52 +0800 Subject: [PATCH 1/4] add s3 storager --- cmd/ipasd/ipasd.go | 49 +++++++++++-------- go.mod | 4 ++ go.sum | 31 ++++++++++++ pkg/storager/alioss.go | 1 + pkg/storager/qiniu.go | 2 +- pkg/storager/s3.go | 103 ++++++++++++++++++++++++++++++++++++++++ pkg/storager/s3_test.go | 21 ++++++++ public/app/index.html | 16 ++++--- public/js/core.js | 3 ++ 9 files changed, 203 insertions(+), 27 deletions(-) create mode 100644 pkg/storager/s3.go create mode 100644 pkg/storager/s3_test.go diff --git a/cmd/ipasd/ipasd.go b/cmd/ipasd/ipasd.go index d1c4e84..3ff15bd 100644 --- a/cmd/ipasd/ipasd.go +++ b/cmd/ipasd/ipasd.go @@ -37,11 +37,9 @@ func main() { storageDir := flag.String("dir", "upload", "upload data storage dir") publicURL := flag.String("public-url", "", "server public url") metadataPath := flag.String("meta-path", "appList.json", "metadata storage path, use random secret path to keep your metadata safer") - qiniuConfig := flag.String("qiniu", "", "qiniu config AK:SK:[ZONE]:BUCKET") - qiniuURL := flag.String("qiniu-url", "", "qiniu bucket public url, https://cdn.example.com") - aliossConfig := flag.String("alioss", "", "alicloud OSS config ENDPOINT:ID:SECRET:BUCKET") - aliossURL := flag.String("alioss-url", "", "alicloud OSS bucket public url, https://cdn.example.com") enabledDelete := flag.Bool("del", false, "delete app enabled") + remoteCfg := flag.String("remote", "", "remote storager config, s3://ENDPOINT:AK:SK:BUCKET, alioss://ENDPOINT:AK:SK:BUCKET, qiniu://[ZONE]:AK:SK:BUCKET") + remoteURL := flag.String("remote-url", "", "remote storager public url, https://cdn.example.com") flag.Usage = usage flag.Parse() @@ -52,30 +50,41 @@ func main() { logger = log.With(logger, "ts", log.TimestampFormat(time.Now, "2006-01-02 15:04:05.000"), "caller", log.DefaultCaller) var store storager.Storager - if *qiniuConfig != "" && *qiniuURL != "" { - logger.Log("msg", "used qiniu storager") - args := strings.Split(*qiniuConfig, ":") - if len(args) != 4 { + if *remoteCfg != "" && *remoteURL != "" { + r := strings.Split(*remoteCfg, "://") + if len(r) != 2 { usage() os.Exit(0) } - s, err := storager.NewQiniuStorager(args[0], args[1], args[2], args[3], *qiniuURL) - if err != nil { - panic(err) - } - store = s - } else if *aliossConfig != "" && *aliossURL != "" { - logger.Log("msg", "used alioss storager") - args := strings.Split(*aliossConfig, ":") + args := strings.Split(r[1], ":") if len(args) != 4 { usage() os.Exit(0) } - s, err := storager.NewAliOssStorager(args[0], args[1], args[2], args[3], *aliossURL) - if err != nil { - panic(err) + + switch r[0] { + case "s3": + logger.Log("msg", "used s3 storager") + s, err := storager.NewS3Storager(args[0], args[1], args[2], args[3], *remoteURL) + if err != nil { + panic(err) + } + store = s + case "alioss": + logger.Log("msg", "used alioss storager") + s, err := storager.NewAliOssStorager(args[0], args[1], args[2], args[3], *remoteURL) + if err != nil { + panic(err) + } + store = s + case "qiniu": + logger.Log("msg", "used qiniu storager") + s, err := storager.NewQiniuStorager(args[0], args[1], args[2], args[3], *remoteURL) + if err != nil { + panic(err) + } + store = s } - store = s } else { logger.Log("msg", "used os file storager") store = storager.NewOsFileStorager(*storageDir) diff --git a/go.mod b/go.mod index 8dbecac..742fd0b 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,10 @@ go 1.16 require ( github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible + github.com/aws/aws-sdk-go-v2 v1.6.0 + github.com/aws/aws-sdk-go-v2/config v1.3.0 + github.com/aws/aws-sdk-go-v2/credentials v1.2.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.9.0 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/go-kit/kit v0.10.0 github.com/google/uuid v1.2.0 // indirect diff --git a/go.sum b/go.sum index a37e365..ea8eab3 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,30 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.6.0 h1:r20hdhm8wZmKkClREfacXrKfX0Y7/s0aOoeraFbf/sY= +github.com/aws/aws-sdk-go-v2 v1.6.0/go.mod h1:tI4KhsR5VkzlUa2DZAdwx7wCAYGwkZZ1H31PYrBFx1w= +github.com/aws/aws-sdk-go-v2/config v1.3.0 h1:0JAnp0WcsgKilFLiZEScUTKIvTKa2LkicadZADza+u0= +github.com/aws/aws-sdk-go-v2/config v1.3.0/go.mod h1:lOxzHWDt/k7MMidA/K8DgXL4+ynnZYsDq65Qhs/l3dg= +github.com/aws/aws-sdk-go-v2/credentials v1.2.1 h1:AqQ8PzWll1wegNUOfIKcbp/JspTbJl54gNonrO6VUsY= +github.com/aws/aws-sdk-go-v2/credentials v1.2.1/go.mod h1:Rfvim1eZTC9W5s8YJyYYtl1KMk6e8fHv+wMRQGO4Ru0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.1.1 h1:w1ocBIhQkLgupEB3d0uOuBddqVYl0xpubz7HSTzWG8A= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.1.1/go.mod h1:GTXAhrxHQOj9N+J5tYVjwt+rpRyy/42qLjlgw9pz1a0= +github.com/aws/aws-sdk-go-v2/internal/ini v1.0.0 h1:k7I9E6tyVWBo7H9ffpnxDWudtjau6Qt9rnOYgV+ciEQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.0.0/go.mod h1:g3XMXuxvqSMUjnsXXp/960152w0wFS4CXVYgQaSVOHE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.1.0 h1:XwqxIO9LtNXznBbEMNGumtLN60k4nVqDpVwVWx3XU/o= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.1.0/go.mod h1:zdjOOy0ojUn3iNELo6ycIHSMCp4xUbycSHfb8PnbbyM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.1.1 h1:l7pDLsmOGrnR8LT+3gIv8NlHpUhs7220E457KEC2UM0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.1.1/go.mod h1:2+ehJPkdIdl46VCj67Emz/EH2hpebHZtaLdzqg+sWOI= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.3.1 h1:VH1Y4k+IZ5kcRVqSNw7eAkXyfS7k2/ibKjrNtbhYhV4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.3.1/go.mod h1:IpjxfORBAFfkMM0VEx5gPPnEy6WV4Hk0F/+zb/SUWyw= +github.com/aws/aws-sdk-go-v2/service/s3 v1.9.0 h1:FZ5UL5aiybSJKiJglPT7YMMwc431IgOX5gvlFAzSjzs= +github.com/aws/aws-sdk-go-v2/service/s3 v1.9.0/go.mod h1:zHCjYoODbYRLz/iFicYswq1gRoxBnHvpY5h2Vg3/tJ4= +github.com/aws/aws-sdk-go-v2/service/sso v1.2.1 h1:alpXc5UG7al7QnttHe/9hfvUfitV8r3w0onPpPkGzi0= +github.com/aws/aws-sdk-go-v2/service/sso v1.2.1/go.mod h1:VimPFPltQ/920i1X0Sb0VJBROLIHkDg2MNP10D46OGs= +github.com/aws/aws-sdk-go-v2/service/sts v1.4.1 h1:9Z00tExoaLutWVDmY6LyvIAcKjHetkbdmpRt4JN/FN0= +github.com/aws/aws-sdk-go-v2/service/sts v1.4.1/go.mod h1:G9osDWA52WQ38BDcj65VY1cNmcAQXAXTsE8IWH8j81w= +github.com/aws/smithy-go v1.4.0 h1:3rsQpgRe+OoQgJhEwGNpIkosl0fJLdmQqF4gSFRjg+4= +github.com/aws/smithy-go v1.4.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -84,6 +108,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -125,6 +151,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -338,6 +366,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -370,6 +400,7 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/storager/alioss.go b/pkg/storager/alioss.go index 25d093a..988e865 100644 --- a/pkg/storager/alioss.go +++ b/pkg/storager/alioss.go @@ -16,6 +16,7 @@ type aliossStorager struct { var _ Storager = (*aliossStorager)(nil) +// endpoint: https://help.aliyun.com/document_detail/31837.htm func NewAliOssStorager(endpoint, accessKeyId, accessKeySecret, bucketName, domain string) (Storager, error) { client, err := oss.New(endpoint, accessKeyId, accessKeySecret, oss.Timeout(10, 120)) if err != nil { diff --git a/pkg/storager/qiniu.go b/pkg/storager/qiniu.go index 5247941..cdc26f8 100644 --- a/pkg/storager/qiniu.go +++ b/pkg/storager/qiniu.go @@ -31,7 +31,7 @@ var ( // zone option: huadong:z0 huabei:z1 huanan:z2 northAmerica:na0 singapore:as0 fogCnEast1:fog-cn-east-1 // domain required: https://file.example.com -func NewQiniuStorager(accessKey, secretKey, zone, bucket, domain string) (Storager, error) { +func NewQiniuStorager(zone, accessKey, secretKey, bucket, domain string) (Storager, error) { config := &storage.Config{ UseHTTPS: true, UseCdnDomains: false, diff --git a/pkg/storager/s3.go b/pkg/storager/s3.go new file mode 100644 index 0000000..feba384 --- /dev/null +++ b/pkg/storager/s3.go @@ -0,0 +1,103 @@ +package storager + +import ( + "context" + "io" + "io/ioutil" + "net/url" + + "github.com/aws/aws-sdk-go-v2/aws" + v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/iineva/ipa-server/pkg/storager/helper" +) + +type s3Storager struct { + endpoint string + ak string + sk string + bucket string + domain string + client *s3.Client +} + +func NewS3Storager(endpoint, ak, sk, bucket, domain string) (Storager, error) { + + u, err := url.Parse(endpoint) + if err != nil { + return nil, err + } + if u.Scheme == "" { + u.Scheme = "https" + } + + customResolver := aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) { + return aws.Endpoint{ + URL: u.String(), + }, nil + }) + + cfg, err := config.LoadDefaultConfig( + context.Background(), + config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(ak, sk, "")), + config.WithEndpointResolver(customResolver), + ) + if err != nil { + return nil, err + } + + return &s3Storager{ + endpoint: endpoint, + ak: ak, + sk: sk, + bucket: bucket, + domain: domain, + client: s3.NewFromConfig(cfg), + }, nil +} + +func (s *s3Storager) Save(name string, reader io.Reader) error { + r := ioutil.NopCloser(reader) // avoid oss SDK to close reader + _, err := s.client.PutObject(context.Background(), &s3.PutObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(name), + Body: r, + }, s3.WithAPIOptions( + v4.SwapComputePayloadSHA256ForUnsignedPayloadMiddleware, + )) + return err +} + +func (s *s3Storager) OpenMetadata(name string) (io.ReadCloser, error) { + out, err := s.client.GetObject(context.Background(), &s3.GetObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(name), + }) + return out.Body, err +} + +func (s *s3Storager) Delete(name string) error { + _, err := s.client.DeleteObject(context.Background(), &s3.DeleteObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(name), + }) + return err +} + +func (s *s3Storager) Move(src, dest string) error { + _, err := s.client.CopyObject(context.Background(), &s3.CopyObjectInput{ + Bucket: aws.String(s.bucket), + CopySource: aws.String(s.bucket + "/" + src), + Key: aws.String(dest), + }) + if err != nil { + return err + } + return s.Delete(src) +} + +func (s *s3Storager) PublicURL(publicURL, name string) (string, error) { + return helper.UrlJoin(s.domain, name) +} diff --git a/pkg/storager/s3_test.go b/pkg/storager/s3_test.go new file mode 100644 index 0000000..055ce18 --- /dev/null +++ b/pkg/storager/s3_test.go @@ -0,0 +1,21 @@ +package storager + +import ( + "testing" +) + +func TestS3(t *testing.T) { + + endpoint := "oss-cn-shenzhen.aliyuncs.com" + accessKeyId := "" + accessKeySecret := "" + bucketName := "" + domain := "" + + a, err := NewS3Storager(endpoint, accessKeyId, accessKeySecret, bucketName, domain) + if err != nil { + t.Fatal(err) + } + + testStorager(a, t) +} diff --git a/public/app/index.html b/public/app/index.html index 6a58427..6db85b9 100644 --- a/public/app/index.html +++ b/public/app/index.html @@ -111,6 +111,12 @@ instance.update().check().handlers(true) }) } + function onWindowsLoad() { + IPA.fetch(`/api/delete?v=${parseInt(new Date().getTime() / 1000)}`).then(d => { + loadInfo(d.delete) + }) + } + function onClickInstall(plist) { window.location.href = 'itms-services://?action=download-manifest&url=' + plist } @@ -132,18 +138,16 @@ return } - if (confirm(`${json.msg}\n${IPA.langString('Back to home?')}`)) { + if (confirm(`${IPA.langString('Delete Success!')}\n${IPA.langString('Back to home?')}`)) { window.location.href = '/' + } else { + onWindowsLoad() } }).catch(err => { console.error(err) }) } - window.addEventListener('load', () => { - IPA.fetch(`/api/delete?v=${parseInt(new Date().getTime() / 1000)}`).then(d => { - loadInfo(d.delete) - }) - }) + window.addEventListener('load', onWindowsLoad) diff --git a/public/js/core.js b/public/js/core.js index f41d23a..f96774c 100644 --- a/public/js/core.js +++ b/public/js/core.js @@ -82,6 +82,9 @@ 'Confirm to Delete?': { 'zh-cn': '确认删除?' }, + 'Delete Success!': { + 'zh-cn': '删除成功!' + }, } const lang = (localStr[key] || key)[language().toLowerCase()] return lang ? lang : key From 5642182e4e808511b3f7b901fd86427005dc06c2 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 27 May 2021 13:54:47 +0800 Subject: [PATCH 2/4] Update qiniu_test.go --- pkg/storager/qiniu_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/storager/qiniu_test.go b/pkg/storager/qiniu_test.go index 4d4cc68..3586515 100644 --- a/pkg/storager/qiniu_test.go +++ b/pkg/storager/qiniu_test.go @@ -5,7 +5,13 @@ import ( ) func TestQiniuUpload(t *testing.T) { - q, err := NewQiniuStorager("", "", "", "", "") + zone := "" + accessKeyId := "" + accessKeySecret := "" + bucketName := "" + domain := "" + + q, err := NewQiniuStorager(zone, accessKeyId, accessKeySecret, bucketName, domain) if err != nil { t.Fatal(err) } From 00593f7af58efe4f356b7e4f1a3aa37aa078d1e3 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 27 May 2021 13:56:27 +0800 Subject: [PATCH 3/4] Update alioss_test.go --- pkg/storager/alioss_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/storager/alioss_test.go b/pkg/storager/alioss_test.go index 061b52c..e399370 100644 --- a/pkg/storager/alioss_test.go +++ b/pkg/storager/alioss_test.go @@ -6,7 +6,7 @@ import ( func TestAliOss(t *testing.T) { - endpoint := "http://oss-cn-shenzhen.aliyuncs.com" + endpoint := "oss-cn-shenzhen.aliyuncs.com" accessKeyId := "" accessKeySecret := "" bucketName := "" From 5474dee06ac4a0438b28b5696d9f4a3956884fb7 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 27 May 2021 14:13:59 +0800 Subject: [PATCH 4/4] Update docs --- Makefile | 4 ++-- README.md | 18 ++++++------------ README_zh.md | 20 ++++++++------------ app.json | 18 ++++-------------- docker-compose.yml | 10 ++++++---- docker-entrypoint.sh | 20 +++++--------------- 6 files changed, 31 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index 4d8d2f0..70f84bb 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,10 @@ all:: web web:: - go run cmd/ipasd/ipasd.go + go run cmd/ipasd/ipasd.go -del debug:: - go run cmd/ipasd/ipasd.go -d + go run cmd/ipasd/ipasd.go -d -del build:: go build cmd/ipasd/ipasd.go diff --git a/README.md b/README.md index f3b1cfa..427c5aa 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,8 @@ docker-compose up -d ### config * PUBLIC_URL: public URL for this server, empty to use `$DOMAIN` -* QINIU: qiniu config `AK:SK:[ZONE]:BUCKET` -* QINIU_URL: qiniu bucket public url, https://cdn.example.com -* ALIOSS: alioss config `ENDPOINT:ID:SECRET:BUCKET` -* ALIOSS_URL: alioss bucket public url, https://xxxx.oss-cn-shenzhen.aliyuncs.com +* REMOTE: remote storager config, s3://ENDPOINT:AK:SK:BUCKET, alioss://ENDPOINT:AK:SK:BUCKET, qiniu://[ZONE]:AK:SK:BUCKET +* REMOTE_URL: remote storager public url, https://cdn.example.com * DELETE_ENABLED: delete app enabled, `true` `false` [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/iineva/ipa-server) @@ -58,14 +56,10 @@ services: environment: # server public url - PUBLIC_URL=https:// - # option, qiniu config AK:SK:[ZONE]:BUCKET - - QINIU= - # option, qiniu public url - - QINIU_URL= - # option, alicloud OSS config ENDPOINT:ID:SECRET:BUCKET - - ALIOSS= - # option, alioss public url - - ALIOSS_URL= + # option, remote storager config, s3://ENDPOINT:AK:SK:BUCKET, alioss://ENDPOINT:AK:SK:BUCKET, qiniu://[ZONE]:AK:SK:BUCKET + - REMOTE= + # option, remote storager public url, https://cdn.example.com + - REMOTE_URL= # option, metadata storage path, use random secret path to keep your metadata safer in case of remote storage - META_PATH=appList.json # delete app enabled, true/false diff --git a/README_zh.md b/README_zh.md index 21140b9..ffff1aa 100644 --- a/README_zh.md +++ b/README_zh.md @@ -32,10 +32,8 @@ docker-compose up -d ### 配置 * PUBLIC_URL: 本服务的公网URL, 如果为空试用Heroku默认的 `$DOMAIN` -* QINIU: 七牛配置 `AK:SK:[ZONE]:BUCKET`, `ZONE` 区域参数可选, 绝大多数情况可以自动检测 -* QINIU_URL: 七牛CDN对应的URL,注意需要开启HTTPS支持才能正常安装!例子:https://cdn.example.com -* ALIOSS: 阿里云OSS配置 `ENDPOINT:ID:SECRET:BUCKET` -* ALIOSS_URL: Bucket域名,必须指定https才能保证ipa正常下载!例子: https://xxxx.oss-cn-shenzhen.aliyuncs.com +* REMOTE: option, 远程存储配置, s3://ENDPOINT:AK:SK:BUCKET, alioss://ENDPOINT:AK:SK:BUCKET, qiniu://[ZONE]:AK:SK:BUCKET +* REMOTE_URL: option, 远程存储访问URL, 注意需要开启HTTPS支持iOS才能正常安装!例子:https://cdn.example.com * DELETE_ENABLED: 是否开启删除APP功能 `true` `false` [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/iineva/ipa-server) @@ -63,14 +61,10 @@ services: environment: # 本服务公网IP - PUBLIC_URL=https:// - # option, 七牛配置 AK:SK:[ZONE]:BUCKET - - QINIU= - # option, 七牛CDN域名,注意要加 https:// - - QINIU_URL= - # option, 阿里云OSS 配置 ENDPOINT:ID:SECRET:BUCKET - - ALIOSS= - # option, 阿里云OSS Bucket 域名,注意要加 https:// - - ALIOSS_URL= + # option, 远程存储配置, s3://ENDPOINT:AK:SK:BUCKET, alioss://ENDPOINT:AK:SK:BUCKET, qiniu://[ZONE]:AK:SK:BUCKET + - REMOTE= + # option, 远程存储访问URL, https://cdn.example.com + - REMOTE_URL= # option, 元数据存储路径, 使用一个随机路径来保护元数据,因为在使用远程存储的时候,没有更好的方法防止外部直接访问元数据文件 - META_PATH=appList.json # 是否开启删除APP功能, true/false @@ -110,5 +104,7 @@ make - [ ] 设计全新的鉴权方式,初步考虑试用GitHub登录鉴权 - [x] 支持七牛存储 +- [x] 支持阿里云OSS存储 +- [x] 支持S3存储 - [x] 兼容v1产生数据,无缝升级 - [ ] 支持命令行生成静态文件部署 diff --git a/app.json b/app.json index ee52c53..eef7659 100644 --- a/app.json +++ b/app.json @@ -10,23 +10,13 @@ "required": false, "value": "" }, - "QINIU": { - "description": "qiniu config AK:SK:[ZONE]:BUCKET", + "REMOTE": { + "description": "remote storager config, s3://ENDPOINT:AK:SK:BUCKET, alioss://ENDPOINT:AK:SK:BUCKET, qiniu://[ZONE]:AK:SK:BUCKET", "required": false, "value": "" }, - "QINIU_URL": { - "description": "qiniu bucket public url, https://cdn.example.com", - "required": false, - "value": "" - }, - "ALIOSS": { - "description": "alicloud OSS config ENDPOINT:ID:SECRET:BUCKET", - "required": false, - "value": "" - }, - "ALIOSS_URL": { - "description": "alicloud OSS bucket public url, https://cdn.example.com", + "REMOTE_URL": { + "description": "remote storager public url, https://cdn.example.com", "required": false, "value": "" }, diff --git a/docker-compose.yml b/docker-compose.yml index 1639129..93a428d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,12 +8,14 @@ services: environment: # server public url - PUBLIC_URL= - # option, qiniu config AK:SK:[ZONE]:BUCKET - - QINIU= - # option, qiniu public url - - QINIU_URL= + # option, remote storager config, s3://ENDPOINT:AK:SK:BUCKET, alioss://ENDPOINT:AK:SK:BUCKET, qiniu://[ZONE]:AK:SK:BUCKET + - REMOTE= + # option, remote storager public url, https://cdn.example.com + - REMOTE_URL= # option, metadata storage path, use random secret path to keep your metadata safer in case of remote storage - META_PATH=appList.json + # delete app enabled, true/false + - DELETE_ENABLED=false ports: - "9008:8080" volumes: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index bb2944e..f0020ca 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -11,20 +11,12 @@ if [ -n "$PUBLIC_URL" ];then ipasd_args=$ipasd_args"-public-url $PUBLIC_URL " fi -if [ -n "$QINIU" ];then - ipasd_args=$ipasd_args"-qiniu $QINIU " +if [ -n "$REMOTE" ];then + ipasd_args=$ipasd_args"-remote $REMOTE " fi -if [ -n "$QINIU_URL" ];then - ipasd_args=$ipasd_args"-qiniu-url $QINIU_URL " -fi - -if [ -n "$ALIOSS" ];then - ipasd_args=$ipasd_args"-alioss $ALIOSS " -fi - -if [ -n "$ALIOSS_URL" ];then - ipasd_args=$ipasd_args"-alioss-url $ALIOSS_URL " +if [ -n "$REMOTE_URL" ];then + ipasd_args=$ipasd_args"-remote-url $REMOTE_URL " fi if [ "$DELETE_ENABLED" = "true" -o "$DELETE_ENABLED" = "1" ];then @@ -35,6 +27,4 @@ if [ -n "$META_PATH" ];then ipasd_args=$ipasd_args"-meta-path $META_PATH " fi -echo $ipasd_args - -./ipasd $ipasd_args \ No newline at end of file +./ipasd $ipasd_args