Giter Site home page Giter Site logo

beyondstorage / go-storage Goto Github PK

View Code? Open in Web Editor NEW
521.0 10.0 50.0 4.97 MB

A vendor-neutral storage library for Golang: Write once, run on every storage service.

Home Page: https://beyondstorage.io

License: Apache License 2.0

Makefile 3.43% Go 96.57%
storage golang qingstor fs s3 gcs azblob cloud-storage files dropbox

go-storage's People

Contributors

abyss-w avatar aeinrw avatar beyondrobot avatar burntcarrot avatar ccamel avatar dependabot-preview[bot] avatar dependabot[bot] avatar hqc19907228 avatar jinnyyi avatar joey-1445601153 avatar joey2132 avatar junaire avatar juneezee avatar kondanta avatar prnyself avatar renovate[bot] avatar rhnsharma avatar xuanwo avatar xxchan avatar zooltd avatar zu1k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-storage's Issues

proposal: Go version policy

Start from go 1.13, we will test target the latest two major version.

  • At go1.13, we will test on go1.13
  • After go1.14, we will test on go1.13 and go1.14
  • After go1.15, we will test on go1.14 and go1.15

Any install/setup/build error report on not tested version will be marked as wontfix

Proposal: Support service init via config string

Background

This project intents to be a unified storage layer for Golang, but different storage layers' configuration are so different we can't unify them well.

For posixfs: we only need to specify the workdir.
For object storage: we need to specify host, port, protocol, access key id and others.

We used to support them by type and options, like we did in qscamel:

Every service(endpoint in qscamel) should handle their own options:

type Client struct {
	BucketName          string `yaml:"bucket_name"`
	Endpoint            string `yaml:"endpoint"`
	Region              string `yaml:"region"`
	AccessKeyID         string `yaml:"access_key_id"`
	SecretAccessKey     string `yaml:"secret_access_key"`
	DisableSSL          bool   `yaml:"disable_ssl"`
	UseAccelerate       bool   `yaml:"use_accelerate"`
	PathStyle           bool   `yaml:"path_style"`
	EnableListObjectsV2 bool   `yaml:"enable_list_objects_v2"`
	EnableSignatureV2   bool   `yaml:"enable_signature_v2"`
	DisableURICleaning  bool   `yaml:"disable_uri_cleaning"`

	Path string

	client *s3.S3
}

func New(ctx context.Context, et uint8, hc *http.Client) (c *Client, err error) {
	...
	content, err := yaml.Marshal(e.Options)
	if err != nil {
		return
	}
	err = yaml.Unmarshal(content, c)
	if err != nil {
		return
	}
    ...
}

Developer who want to use this service should handle the type:

switch t.Src.Type {
...
case constants.EndpointS3:
    src, err = s3.New(ctx, constants.SourceEndpoint, contexts.Client)
    if err != nil {
        return
    }
...
default:
    logrus.Errorf("Type %s is not supported.", t.Src.Type)
    err = constants.ErrEndpointNotSupported
    return
}

User should set them in config directly:

source:
  type: s3
  path: "/path/to/source"
  options:
    bucket_name: example_bucket
    endpoint: example_endpoint
    region: example_region
    access_key_id: example_access_key_id
    secret_access_key: example_secret_access_key
    disable_ssl: false
    use_accelerate: false
    path_style: false
    enable_list_objects_v2: false
    enable_signature_v2: false
    disable_uri_cleaning: false

It works, but it doesn't meet our goal. To address this problem, we split endpoint and credential in PR services: Split endpoint and credential into different pair. In this PR, we can init an object service like:

srv := qingstor.New()
err = srv.Init(
    pairs.WithCredential(credential.NewStatic(accessKey, secretKey)),
    pairs.WithEndpoint(endpoint.NewStaticFromParsedURL(protocol, host, port)),
)
if err != nil {
    log.Printf("service init failed: %v", err)
}

It's better, but not enough. We need a general way to init all service like:

srv := storage.SomeCall("<type>", something)

Proposal

So I propose following changes:

Introduce the concept of "config string"

config string is widely used in db connections:

mysql: user:password@/dbname?charset=utf8&parseTime=True&loc=Local
postgres: host=myhost port=myport user=gorm dbname=gorm password=mypassword
sqlserver: sqlserver://username:password@localhost:1433?database=dbname

Like we did in URL, we can use different part in a formatted string to represent different meaning.

Config string in storage would be like:

<type>://<config>
             +
             |
             v
<credential>@<endpoint>/<name>?<options>
     +            +                 +
     |            +------------+    +----------------------+
     v                         v                           v
<protocol>:<data>   <protocol>:<host>:<port>   <key>:<value>[&<key>:<value>]
  • credential: <protocol>:<data>, static credential could be static://<access_key>:<secret_key>.
  • endpoint: <protocol>:<host>:<port>, qingstor's valid endpoint could be https://qingstor.com:443, 80 and 443 can be emitted with matched protocol.
  • name: a valid storager name for this services
  • options: multiple <key>=<value> connected with &

So a valid config string could be:

  • qos://static:<access_key_id>:<secret_access_key>@https:qingstor.com:443/<bucket_name>?zone=pek3b&work_dir=/storage
  • posixfs:///<path>

services/fs: Size and Offset in Read handled incorrectly

if opt.HasSize && opt.HasOffset {
	return iowrap.SectionReadCloser(f, opt.Offset, opt.Size), nil
}
if opt.HasSize {
	return iowrap.LimitReadCloser(f, opt.Size), nil
}
if opt.HasOffset {
	_, err = f.Seek(opt.Offset, 0)
	if err != nil {
		return nil, fmt.Errorf(errorMessage, s, path, handleOsError(err))
	}
}
if opt.HasReadCallbackFunc {
	return iowrap.CallbackReadCloser(f, opt.ReadCallbackFunc), nil
}

should be like

if opt.HasSize {
	r = iowrap.LimitReadCloser(f, opt.Size), nil
}

tests: Some errors in standard library doesn't implement xerrors.Wrapper

strconv.NumError as an exmaple: we need to write following code for unittest:

e := &strconv.NumError{}
ok := errors.As(err, &e)
if ok {
	assert.True(t, errors.Is(e.Err, tt.err))
} else {
	assert.True(t, errors.Is(err, tt.err))
}

After go 1.14 released, we can change them into:

assert.True(t, errors.Is(err, tt.err))

Proposal: Move id to object type instead of metadata

PR #53 adds a new metadata Id.

This inspires me that we need an Id across all services:

For local file system: Id should be whole path towords root.
For object storage: Id should be the whole key.
For dropbox alike SaaS: Id should be their Id in business.

So let's move Id to object type instead of in metadata.

services/dropbox: meta.Name used incorrectly

o := &types.Object{
	ID:         meta.Id,
	Type:       types.ObjectTypeFile,
	Name:       filepath.Join(path, meta.Name),
	Size:       int64(meta.Size),
	UpdatedAt:  meta.ServerModified,
	ObjectMeta: metadata.NewObjectMeta(),
}

filepath.Join(path, meta.Name) is not the valid name for this file, use path directly?

Roadmap to v1.0.0

Roadmap

  • After 2020-03-13, all new proposals that could lead to breaking changes will be postponed to next major release (v2.0.0)
  • After 2020-03-20, all proposals that not implemented will be postponed to next minor release (v1.1.0)

Proposals

Following proposals are sure to be included in v1.0.0 (a.k.a v0.9.0)

Services

There are no ensurement for any new service to be included in v1.0.0

Steps

There will be two minor release before v1.0.0: v0.8.0 and v0.9.0

v0.8.0 will be released shortly after 2020-03-06, and v0.9.0 expected to be released in 2020-03-20.

After v0.9.0, no new proposals will be implemented until v1.0.0 released, and I will focus on bug fix and code cleanup.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.