forked from TrueCloudLab/distribution
add endpoint support
This commit is contained in:
parent
38b23c8dff
commit
3d30cb38f6
11 changed files with 295 additions and 49 deletions
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
|
@ -46,11 +46,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/denverdino/aliyungo/oss",
|
"ImportPath": "github.com/denverdino/aliyungo/oss",
|
||||||
"Rev": "17d1e888c907ffdbd875f37500f3d130ce2ee6eb"
|
"Rev": "56047189188d6558b6a1456d647970032343b511"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/denverdino/aliyungo/util",
|
"ImportPath": "github.com/denverdino/aliyungo/util",
|
||||||
"Rev": "17d1e888c907ffdbd875f37500f3d130ce2ee6eb"
|
"Rev": "56047189188d6558b6a1456d647970032343b511"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/docker/docker/pkg/tarsum",
|
"ImportPath": "github.com/docker/docker/pkg/tarsum",
|
||||||
|
|
17
Godeps/_workspace/src/github.com/denverdino/aliyungo/oss/client.go
generated
vendored
17
Godeps/_workspace/src/github.com/denverdino/aliyungo/oss/client.go
generated
vendored
|
@ -35,7 +35,9 @@ type Client struct {
|
||||||
Secure bool
|
Secure bool
|
||||||
ConnectTimeout time.Duration
|
ConnectTimeout time.Duration
|
||||||
ReadTimeout time.Duration
|
ReadTimeout time.Duration
|
||||||
debug bool
|
|
||||||
|
endpoint string
|
||||||
|
debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Bucket type encapsulates operations with an bucket.
|
// The Bucket type encapsulates operations with an bucket.
|
||||||
|
@ -159,6 +161,12 @@ func (client *Client) locationConstraint() io.Reader {
|
||||||
return strings.NewReader(constraint)
|
return strings.NewReader(constraint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// override default endpoint
|
||||||
|
func (client *Client) SetEndpoint(endpoint string) {
|
||||||
|
// TODO check endpoint
|
||||||
|
client.endpoint = endpoint
|
||||||
|
}
|
||||||
|
|
||||||
// PutBucket creates a new bucket.
|
// PutBucket creates a new bucket.
|
||||||
func (b *Bucket) PutBucket(perm ACL) error {
|
func (b *Bucket) PutBucket(perm ACL) error {
|
||||||
headers := make(http.Header)
|
headers := make(http.Header)
|
||||||
|
@ -963,7 +971,12 @@ func (client *Client) query(req *request, resp interface{}) error {
|
||||||
|
|
||||||
// Sets baseurl on req from bucket name and the region endpoint
|
// Sets baseurl on req from bucket name and the region endpoint
|
||||||
func (client *Client) setBaseURL(req *request) error {
|
func (client *Client) setBaseURL(req *request) error {
|
||||||
req.baseurl = client.Region.GetEndpoint(client.Internal, req.bucket, client.Secure)
|
|
||||||
|
if client.endpoint == "" {
|
||||||
|
req.baseurl = client.Region.GetEndpoint(client.Internal, req.bucket, client.Secure)
|
||||||
|
} else {
|
||||||
|
req.baseurl = fmt.Sprintf("%s://%s", client.endpoint, getProtocol(client.Secure))
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
4
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/attempt.go
generated
vendored
4
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/attempt.go
generated
vendored
|
@ -4,9 +4,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AttemptStrategy is reused from the goamz package
|
||||||
|
|
||||||
// AttemptStrategy represents a strategy for waiting for an action
|
// AttemptStrategy represents a strategy for waiting for an action
|
||||||
// to complete successfully. This is an internal type used by the
|
// to complete successfully. This is an internal type used by the
|
||||||
// implementation of other goamz packages.
|
// implementation of other packages.
|
||||||
type AttemptStrategy struct {
|
type AttemptStrategy struct {
|
||||||
Total time.Duration // total duration of attempt.
|
Total time.Duration // total duration of attempt.
|
||||||
Delay time.Duration // interval between each try in the burst.
|
Delay time.Duration // interval between each try in the burst.
|
||||||
|
|
68
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/encoding.go
generated
vendored
68
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/encoding.go
generated
vendored
|
@ -39,49 +39,48 @@ func setQueryValues(i interface{}, values *url.Values, prefix string) {
|
||||||
}
|
}
|
||||||
if kind == reflect.Ptr {
|
if kind == reflect.Ptr {
|
||||||
field = field.Elem()
|
field = field.Elem()
|
||||||
|
kind = field.Kind()
|
||||||
}
|
}
|
||||||
var value string
|
var value string
|
||||||
switch field.Interface().(type) {
|
//switch field.Interface().(type) {
|
||||||
case int, int8, int16, int32, int64:
|
switch kind {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
i := field.Int()
|
i := field.Int()
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
value = strconv.FormatInt(i, 10)
|
value = strconv.FormatInt(i, 10)
|
||||||
}
|
}
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
i := field.Uint()
|
i := field.Uint()
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
value = strconv.FormatUint(i, 10)
|
value = strconv.FormatUint(i, 10)
|
||||||
}
|
}
|
||||||
case float32:
|
case reflect.Float32:
|
||||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
|
value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
|
||||||
case float64:
|
case reflect.Float64:
|
||||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
|
value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
|
||||||
case []byte:
|
case reflect.Bool:
|
||||||
value = string(field.Bytes())
|
|
||||||
case bool:
|
|
||||||
value = strconv.FormatBool(field.Bool())
|
value = strconv.FormatBool(field.Bool())
|
||||||
case string:
|
case reflect.String:
|
||||||
value = field.String()
|
value = field.String()
|
||||||
case []string:
|
case reflect.Slice:
|
||||||
l := field.Len()
|
switch field.Type().Elem().Kind() {
|
||||||
if l > 0 {
|
case reflect.Uint8:
|
||||||
strArray := make([]string, l)
|
value = string(field.Bytes())
|
||||||
for i := 0; i < l; i++ {
|
case reflect.String:
|
||||||
strArray[i] = field.Index(i).String()
|
l := field.Len()
|
||||||
|
if l > 0 {
|
||||||
|
strArray := make([]string, l)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
strArray[i] = field.Index(i).String()
|
||||||
|
}
|
||||||
|
bytes, err := json.Marshal(strArray)
|
||||||
|
if err == nil {
|
||||||
|
value = string(bytes)
|
||||||
|
} else {
|
||||||
|
log.Printf("Failed to convert JSON: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bytes, err := json.Marshal(strArray)
|
default:
|
||||||
if err == nil {
|
|
||||||
value = string(bytes)
|
|
||||||
} else {
|
|
||||||
log.Printf("Failed to convert JSON: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case time.Time:
|
|
||||||
t := field.Interface().(time.Time)
|
|
||||||
value = GetISO8601TimeStamp(t)
|
|
||||||
|
|
||||||
default:
|
|
||||||
if kind == reflect.Slice { //Array of structs
|
|
||||||
l := field.Len()
|
l := field.Len()
|
||||||
for j := 0; j < l; j++ {
|
for j := 0; j < l; j++ {
|
||||||
prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
|
prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
|
||||||
|
@ -91,7 +90,18 @@ func setQueryValues(i interface{}, values *url.Values, prefix string) {
|
||||||
setQueryValues(ifc, values, prefixName)
|
setQueryValues(ifc, values, prefixName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch field.Interface().(type) {
|
||||||
|
case ISO6801Time:
|
||||||
|
t := field.Interface().(ISO6801Time)
|
||||||
|
value = t.String()
|
||||||
|
case time.Time:
|
||||||
|
t := field.Interface().(time.Time)
|
||||||
|
value = GetISO8601TimeStamp(t)
|
||||||
|
default:
|
||||||
ifc := field.Interface()
|
ifc := field.Interface()
|
||||||
if ifc != nil {
|
if ifc != nil {
|
||||||
SetQueryValues(ifc, values)
|
SetQueryValues(ifc, values)
|
||||||
|
|
8
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/encoding_test.go
generated
vendored
8
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/encoding_test.go
generated
vendored
|
@ -5,6 +5,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TestString string
|
||||||
|
|
||||||
type SubStruct struct {
|
type SubStruct struct {
|
||||||
A string
|
A string
|
||||||
B int
|
B int
|
||||||
|
@ -21,6 +23,8 @@ type TestStruct struct {
|
||||||
IntPtr *int `ArgName:"int-ptr"`
|
IntPtr *int `ArgName:"int-ptr"`
|
||||||
StringArray []string `ArgName:"str-array"`
|
StringArray []string `ArgName:"str-array"`
|
||||||
StructArray []SubStruct
|
StructArray []SubStruct
|
||||||
|
test TestString
|
||||||
|
tests []TestString
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConvertToQueryValues(t *testing.T) {
|
func TestConvertToQueryValues(t *testing.T) {
|
||||||
|
@ -36,9 +40,11 @@ func TestConvertToQueryValues(t *testing.T) {
|
||||||
SubStruct{A: "a", B: 1},
|
SubStruct{A: "a", B: 1},
|
||||||
SubStruct{A: "x", B: 2},
|
SubStruct{A: "x", B: 2},
|
||||||
},
|
},
|
||||||
|
test: TestString("test"),
|
||||||
|
tests: []TestString{TestString("test1"), TestString("test2")},
|
||||||
}
|
}
|
||||||
result := ConvertToQueryValues(&request).Encode()
|
result := ConvertToQueryValues(&request).Encode()
|
||||||
const expectedResult = "Format=JSON&StructArray.1.A=a&StructArray.1.B=1&StructArray.2.A=x&StructArray.2.B=2&Timestamp=2015-05-26T01%3A02%3A03Z&Version=1.0&bool-ptr=true&int-value=10&str-array=%5B%22abc%22%2C%22xyz%22%5D"
|
const expectedResult = "Format=JSON&StructArray.1.A=a&StructArray.1.B=1&StructArray.2.A=x&StructArray.2.B=2&Timestamp=2015-05-26T01%3A02%3A03Z&Version=1.0&bool-ptr=true&int-value=10&str-array=%5B%22abc%22%2C%22xyz%22%5D&test=test&tests=%5B%22test1%22%2C%22test2%22%5D"
|
||||||
if result != expectedResult {
|
if result != expectedResult {
|
||||||
t.Error("Incorrect encoding: ", result)
|
t.Error("Incorrect encoding: ", result)
|
||||||
}
|
}
|
||||||
|
|
4
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/iso6801.go
generated
vendored
4
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/iso6801.go
generated
vendored
|
@ -21,7 +21,7 @@ type ISO6801Time time.Time
|
||||||
// time.Time instance. This causes the nanosecond field to be set to
|
// time.Time instance. This causes the nanosecond field to be set to
|
||||||
// 0, and its time zone set to a fixed zone with no offset from UTC
|
// 0, and its time zone set to a fixed zone with no offset from UTC
|
||||||
// (but it is *not* UTC itself).
|
// (but it is *not* UTC itself).
|
||||||
func New(t time.Time) ISO6801Time {
|
func NewISO6801Time(t time.Time) ISO6801Time {
|
||||||
return ISO6801Time(time.Date(
|
return ISO6801Time(time.Date(
|
||||||
t.Year(),
|
t.Year(),
|
||||||
t.Month(),
|
t.Month(),
|
||||||
|
@ -58,5 +58,5 @@ func (it *ISO6801Time) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
// String returns the time in ISO6801Time format
|
// String returns the time in ISO6801Time format
|
||||||
func (it ISO6801Time) String() string {
|
func (it ISO6801Time) String() string {
|
||||||
return time.Time(it).String()
|
return time.Time(it).Format(formatISO8601)
|
||||||
}
|
}
|
||||||
|
|
6
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/iso6801_test.go
generated
vendored
6
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/iso6801_test.go
generated
vendored
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestISO8601Time(t *testing.T) {
|
func TestISO8601Time(t *testing.T) {
|
||||||
now := New(time.Now().UTC())
|
now := NewISO6801Time(time.Now().UTC())
|
||||||
|
|
||||||
data, err := json.Marshal(now)
|
data, err := json.Marshal(now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -26,7 +26,7 @@ func TestISO8601Time(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if now != now2 {
|
if now != now2 {
|
||||||
t.Fatalf("Time %s does not equal expected %s", now2, now)
|
t.Errorf("Time %s does not equal expected %s", now2, now)
|
||||||
}
|
}
|
||||||
|
|
||||||
if now.String() != now2.String() {
|
if now.String() != now2.String() {
|
||||||
|
@ -46,5 +46,5 @@ func TestISO8601Time(t *testing.T) {
|
||||||
if !testValue.B.IsDefault() {
|
if !testValue.B.IsDefault() {
|
||||||
t.Fatal("Invaid Unmarshal result for ISO6801Time from empty value")
|
t.Fatal("Invaid Unmarshal result for ISO6801Time from empty value")
|
||||||
}
|
}
|
||||||
|
t.Logf("ISO6801Time String(): %s", now2.String())
|
||||||
}
|
}
|
||||||
|
|
107
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/util.go
generated
vendored
107
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/util.go
generated
vendored
|
@ -2,12 +2,20 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
srand "crypto/rand"
|
||||||
|
"encoding/binary"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const (
|
||||||
|
StatusUnKnown = "NA"
|
||||||
)
|
)
|
||||||
|
|
||||||
//CreateRandomString create random string
|
//CreateRandomString create random string
|
||||||
|
@ -52,3 +60,102 @@ func Encode(v url.Values) string {
|
||||||
func GetGMTime() string {
|
func GetGMTime() string {
|
||||||
return time.Now().UTC().Format(http.TimeFormat)
|
return time.Now().UTC().Format(http.TimeFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
func randUint32() uint32 {
|
||||||
|
return randUint32Slice(1)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func randUint32Slice(c int) []uint32 {
|
||||||
|
b := make([]byte, c*4)
|
||||||
|
|
||||||
|
_, err := srand.Read(b)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// fail back to insecure rand
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
for i := range b {
|
||||||
|
b[i] = byte(rand.Int())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n := make([]uint32, c)
|
||||||
|
|
||||||
|
for i := range n {
|
||||||
|
n[i] = binary.BigEndian.Uint32(b[i*4 : i*4+4])
|
||||||
|
}
|
||||||
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func toByte(n uint32, st, ed byte) byte {
|
||||||
|
return byte(n%uint32(ed-st+1) + uint32(st))
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDigit(n uint32) byte {
|
||||||
|
return toByte(n, '0', '9')
|
||||||
|
}
|
||||||
|
|
||||||
|
func toLowerLetter(n uint32) byte {
|
||||||
|
return toByte(n, 'a', 'z')
|
||||||
|
}
|
||||||
|
|
||||||
|
func toUpperLetter(n uint32) byte {
|
||||||
|
return toByte(n, 'A', 'Z')
|
||||||
|
}
|
||||||
|
|
||||||
|
type convFunc func(uint32) byte
|
||||||
|
|
||||||
|
var convFuncs = []convFunc{toDigit, toLowerLetter, toUpperLetter}
|
||||||
|
|
||||||
|
// tools for generating a random ECS instance password
|
||||||
|
// from 8 to 30 char MUST contain digit upper, case letter and upper case letter
|
||||||
|
// http://docs.aliyun.com/#/pub/ecs/open-api/instance&createinstance
|
||||||
|
func GenerateRandomECSPassword() string {
|
||||||
|
|
||||||
|
// [8, 30]
|
||||||
|
l := int(randUint32()%23 + 8)
|
||||||
|
|
||||||
|
n := randUint32Slice(l)
|
||||||
|
|
||||||
|
b := make([]byte, l)
|
||||||
|
|
||||||
|
b[0] = toDigit(n[0])
|
||||||
|
b[1] = toLowerLetter(n[1])
|
||||||
|
b[2] = toUpperLetter(n[2])
|
||||||
|
|
||||||
|
for i := 3; i < l; i++ {
|
||||||
|
b[i] = convFuncs[n[i]%3](n[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
s := make([]byte, l)
|
||||||
|
perm := rand.Perm(l)
|
||||||
|
for i, v := range perm {
|
||||||
|
s[v] = b[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(s)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func LoopCall(attempts AttemptStrategy,api func() (bool,interface{},error))(interface{}, error){
|
||||||
|
|
||||||
|
for attempt := attempts.Start(); attempt.Next(); {
|
||||||
|
needStop,status,err := api()
|
||||||
|
|
||||||
|
if(err != nil) {
|
||||||
|
return nil, errors.New("execution failed")
|
||||||
|
}
|
||||||
|
if(needStop){
|
||||||
|
return status,nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if attempt.HasNext() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return nil,errors.New("timeout execution ")
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
98
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/util_test.go
generated
vendored
Normal file
98
Godeps/_workspace/src/github.com/denverdino/aliyungo/util/util_test.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateRandomECSPassword(t *testing.T) {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
s := GenerateRandomECSPassword()
|
||||||
|
|
||||||
|
if len(s) < 8 || len(s) > 30 {
|
||||||
|
t.Errorf("Generated ECS password [%v]: bad len", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
hasDigit := false
|
||||||
|
hasLower := false
|
||||||
|
hasUpper := false
|
||||||
|
|
||||||
|
for j := range s {
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case '0' <= s[j] && s[j] <= '9':
|
||||||
|
hasDigit = true
|
||||||
|
case 'a' <= s[j] && s[j] <= 'z':
|
||||||
|
hasLower = true
|
||||||
|
case 'A' <= s[j] && s[j] <= 'Z':
|
||||||
|
hasUpper = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasDigit {
|
||||||
|
t.Errorf("Generated ECS password [%v]: no digit", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasLower {
|
||||||
|
t.Errorf("Generated ECS password [%v]: no lower letter ", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasUpper {
|
||||||
|
t.Errorf("Generated ECS password [%v]: no upper letter", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaitForSignalWithTimeout(t *testing.T) {
|
||||||
|
|
||||||
|
attempts := AttemptStrategy{
|
||||||
|
Min: 5,
|
||||||
|
Total: 5 * time.Second,
|
||||||
|
Delay: 200 * time.Millisecond,
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutFunc := func() (bool,interface{},error) {
|
||||||
|
return false,"-1",nil
|
||||||
|
}
|
||||||
|
|
||||||
|
begin := time.Now()
|
||||||
|
|
||||||
|
_, timeoutError := LoopCall(attempts, timeoutFunc);
|
||||||
|
if(timeoutError != nil) {
|
||||||
|
t.Logf("timeout func complete successful")
|
||||||
|
} else {
|
||||||
|
t.Error("Expect timeout result")
|
||||||
|
}
|
||||||
|
|
||||||
|
end := time.Now()
|
||||||
|
duration := end.Sub(begin).Seconds()
|
||||||
|
if( duration > (float64(attempts.Min) -1)) {
|
||||||
|
t.Logf("timeout func duration is enough")
|
||||||
|
} else {
|
||||||
|
t.Error("timeout func duration is not enough")
|
||||||
|
}
|
||||||
|
|
||||||
|
errorFunc := func() (bool, interface{}, error) {
|
||||||
|
err := errors.New("execution failed");
|
||||||
|
return false,"-1",err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, failedError := LoopCall(attempts, errorFunc);
|
||||||
|
if(failedError != nil) {
|
||||||
|
t.Logf("error func complete successful: " + failedError.Error())
|
||||||
|
} else {
|
||||||
|
t.Error("Expect error result")
|
||||||
|
}
|
||||||
|
|
||||||
|
successFunc := func() (bool,interface{}, error) {
|
||||||
|
return true,nil,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_, successError := LoopCall(attempts, successFunc);
|
||||||
|
if(successError != nil) {
|
||||||
|
t.Error("Expect success result")
|
||||||
|
} else {
|
||||||
|
t.Logf("success func complete successful")
|
||||||
|
}
|
||||||
|
}
|
8
registry/storage/driver/oss/oss.go
Executable file → Normal file
8
registry/storage/driver/oss/oss.go
Executable file → Normal file
|
@ -56,6 +56,7 @@ type DriverParameters struct {
|
||||||
Secure bool
|
Secure bool
|
||||||
ChunkSize int64
|
ChunkSize int64
|
||||||
RootDirectory string
|
RootDirectory string
|
||||||
|
Endpoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -175,6 +176,11 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
rootDirectory = ""
|
rootDirectory = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
endpoint, ok := parameters["endpoint"]
|
||||||
|
if !ok {
|
||||||
|
endpoint = ""
|
||||||
|
}
|
||||||
|
|
||||||
params := DriverParameters{
|
params := DriverParameters{
|
||||||
AccessKeyID: fmt.Sprint(accessKey),
|
AccessKeyID: fmt.Sprint(accessKey),
|
||||||
AccessKeySecret: fmt.Sprint(secretKey),
|
AccessKeySecret: fmt.Sprint(secretKey),
|
||||||
|
@ -185,6 +191,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
Encrypt: encryptBool,
|
Encrypt: encryptBool,
|
||||||
Secure: secureBool,
|
Secure: secureBool,
|
||||||
Internal: internalBool,
|
Internal: internalBool,
|
||||||
|
Endpoint: fmt.Sprint(endpoint),
|
||||||
}
|
}
|
||||||
|
|
||||||
return New(params)
|
return New(params)
|
||||||
|
@ -195,6 +202,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
|
||||||
func New(params DriverParameters) (*Driver, error) {
|
func New(params DriverParameters) (*Driver, error) {
|
||||||
|
|
||||||
client := oss.NewOSSClient(params.Region, params.Internal, params.AccessKeyID, params.AccessKeySecret, params.Secure)
|
client := oss.NewOSSClient(params.Region, params.Internal, params.AccessKeyID, params.AccessKeySecret, params.Secure)
|
||||||
|
client.SetEndpoint(params.Endpoint)
|
||||||
bucket := client.Bucket(params.Bucket)
|
bucket := client.Bucket(params.Bucket)
|
||||||
|
|
||||||
// Validate that the given credentials have at least read permissions in the
|
// Validate that the given credentials have at least read permissions in the
|
||||||
|
|
20
registry/storage/driver/oss/oss_test.go
Executable file → Normal file
20
registry/storage/driver/oss/oss_test.go
Executable file → Normal file
|
@ -27,6 +27,7 @@ func init() {
|
||||||
internal := os.Getenv("OSS_INTERNAL")
|
internal := os.Getenv("OSS_INTERNAL")
|
||||||
encrypt := os.Getenv("OSS_ENCRYPT")
|
encrypt := os.Getenv("OSS_ENCRYPT")
|
||||||
secure := os.Getenv("OSS_SECURE")
|
secure := os.Getenv("OSS_SECURE")
|
||||||
|
endpoint := os.Getenv("OSS_ENDPOINT")
|
||||||
root, err := ioutil.TempDir("", "driver-")
|
root, err := ioutil.TempDir("", "driver-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -59,15 +60,16 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters := DriverParameters{
|
parameters := DriverParameters{
|
||||||
accessKey,
|
AccessKeyID: accessKey,
|
||||||
secretKey,
|
AccessKeySecret: secretKey,
|
||||||
bucket,
|
Bucket: bucket,
|
||||||
alioss.Region(region),
|
Region: alioss.Region(region),
|
||||||
internalBool,
|
Internal: internalBool,
|
||||||
encryptBool,
|
ChunkSize: minChunkSize,
|
||||||
secureBool,
|
RootDirectory: rootDirectory,
|
||||||
minChunkSize,
|
Encrypt: encryptBool,
|
||||||
rootDirectory,
|
Secure: secureBool,
|
||||||
|
Endpoint: endpoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
return New(parameters)
|
return New(parameters)
|
||||||
|
|
Loading…
Add table
Reference in a new issue