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

go-storage

Website | Documentation | Community

Go dev License

Matrix Slack Telegram

Build Test Cross Build Unit Test

A vendor-neutral storage library for Golang.

Vision

Write once, run on every storage service.

Goal

  • Vendor agnostic
  • Production ready
  • High performance

Examples

package main

import (
    "log"

    "go.beyondstorage.io/v5/services"
    "go.beyondstorage.io/v5/types"

    // Add fs support
    _ "go.beyondstorage.io/services/fs/v4"
    // Add s3 support
    _ "go.beyondstorage.io/services/s3/v3"
    // Add gcs support
    _ "go.beyondstorage.io/services/gcs/v3"
    // Add azblob support
    _ "go.beyondstorage.io/services/azblob/v3"
    // More support could be found under BeyondStorage.
    _ "go.beyondstorage.io/services/xxx" 
)

func main() {
    // Init a Storager from connection string. 
    store, err := services.NewStoragerFromString("s3://bucket_name/path/to/workdir")
    if err != nil {
        log.Fatalf("service init failed: %v", err)
    }

    // Write data from io.Reader into hello.txt
    n, err := store.Write("hello.txt", r, length)

    // Read data from hello.txt to io.Writer
    n, err := store.Read("hello.txt", w)

    // Stat hello.txt to check existence or get its metadata
    o, err := store.Stat("hello.txt")

    // Use object's functions to get metadata
    length, ok := o.GetContentLength()
    
    // List will create an iterator of object under path.
    it, err := store.List("path")
    
    for {
    	// Use iterator.Next to retrieve next object until we meet IteratorDone.
    	o, err := it.Next()
    	if errors.Is(err, types.IteraoorDone) {
    		break
        }
    }

    // Delete hello.txt
    err = store.Delete("hello.txt")
}

More examples could be found at go-storage-example.

Features

Widely native services support

16 stable services that have passed all integration tests.

3 beta services that implemented required functions, but not passed integration tests.

4 alpha services that still under development.

More service ideas could be found at Service Integration Tracking.

Complete and easily extensible interface

Basic operations

  • Metadata: get Storager metadata
meta := store.Metadata()
_ := meta.GetWorkDir() // Get object WorkDir
_, ok := meta.GetWriteSizeMaximum() // Get the maximum size for write operation
  • Read: read Object content
// Read 2048 byte at the offset 1024 into the io.Writer.
n, err := store.Read("path", w, pairs.WithOffset(1024), pairs.WithSize(2048))
  • Write: write content into Object
// Write 2048 byte from io.Reader
n, err := store.Write("path", r, 2048)
  • Stat: get Object metadata or check existences
o, err := store.Stat("path")
if errors.Is(err, services.ErrObjectNotExist) {
	// object is not exist
}
length, ok := o.GetContentLength() // get the object content length.
  • Delete: delete an Object
err := store.Delete("path") // Delete the object "path"
  • List: list Object in given prefix or dir
it, err := store.List("path")
for {
	o, err := it.Next()
	if err != nil && errors.Is(err, types.IteratorDone) {
        // the list is over 
    }
    length, ok := o.GetContentLength() // get the object content length.
}

Extended operations

  • Copy: copy a Object inside storager
err := store.(Copier).Copy(src, dst) // Copy an object from src to dst.
  • Move: move a Object inside storager
err := store.(Mover).Move(src, dst) // Move an object from src to dst.
  • Reach: generate a public accessible url to an Object
url, err := store.(Reacher).Reach("path") // Generate an url to the object.
  • Dir: Dir Object support
o, err := store.(Direr).CreateDir("path") // Create a dir object.

Large file manipulation

  • Multipart: allow doing multipart uploads
ms := store.(Multiparter)

// Create a multipart object.
o, err := ms.CreateMultipart("path")
// Write 1024 bytes from io.Reader into a multipart at index 1
n, part, err := ms.WriteMultipart(o, r, 1024, 1)
// Complete a multipart object.
err := ms.CompleteMultipart(o, []*Part{part})
  • Append: allow appending to an object
as := store.(Appender)

// Create an appendable object.
o, err := as.CreateAppend("path")
// Write 1024 bytes from io.Reader.
n, err := as.WriteAppend(o, r, 1024)
// Commit an append object.
err = as.CommitAppend(o)
  • Block: allow combining an object with block ids
bs := store.(Blocker)

// Create a block object.
o, err := bs.CreateBlock("path")
// Write 1024 bytes from io.Reader with block id "id-abc"
n, err := bs.WriteBlock(o, r, 1024, "id-abc")
// Combine block via block ids.
err := bs.CombineBlock(o, []string{"id-abc"})
  • Page: allow doing random writes
ps := store.(Pager)

// Create a page object.
o, err := ps.CreatePage("path")
// Write 1024 bytes from io.Reader at offset 2048
n, err := ps.WritePage(o, r, 1024, 2048)

Comprehensive metadata

Global object metadata

  • id: unique key in service
  • name: relative path towards service's work dir
  • mode: object mode can be a combination of read, dir, part and more
  • etag: entity tag as defined in rfc2616
  • content-length: object's content size.
  • content-md5: md5 digest as defined in rfc2616
  • content-type: media type as defined in rfc2616
  • last-modified: object's last updated time.

System object metadata

Service system object metadata like storage-class and so on.

o, err := store.Stat("path")

// Get service system metadata via API provides by go-service-s3.
om := s3.GetObjectSystemMetadata(o)
_ = om.StorageClass // this object's storage class
_ = om.ServerSideEncryptionCustomerAlgorithm // this object's sse algorithm

Strong Typing Everywhere

Self maintained codegen definitions helps to generate all our APIs, pairs and metadata.

Generated pairs which can be used as API optional arguments.

func WithContentMd5(v string) Pair {
    return Pair{
        Key:   "content_md5",
        Value: v,
    }
}

Generated object metadata which can be used to get content md5 from object.

func (o *Object) GetContentMd5() (string, bool) {
    o.stat()
    
    if o.bit&objectIndexContentMd5 != 0 {
        return o.contentMd5, true
    }
    
    return "", false
}

Server-Side Encrypt

Server-Side Encrypt supports via system pair and system metadata, and we can use Default Pairs to simplify the job.

func NewS3SseC(key []byte) (types.Storager, error) {
    defaultPairs := s3.DefaultStoragePairs{
        Write: []types.Pair{
            // Required, must be AES256
            s3.WithServerSideEncryptionCustomerAlgorithm(s3.ServerSideEncryptionAes256),
            // Required, your AES-256 key, a 32-byte binary value
            s3.WithServerSideEncryptionCustomerKey(key),
        },
        // Now you have to provide customer key to read encrypted data
        Read: []types.Pair{
            // Required, must be AES256
            s3.WithServerSideEncryptionCustomerAlgorithm(s3.ServerSideEncryptionAes256),
            // Required, your AES-256 key, a 32-byte binary value
            s3.WithServerSideEncryptionCustomerKey(key),
        }}
    
    return s3.NewStorager(..., s3.WithDefaultStoragePairs(defaultPairs))
}

Sponsor

Owner
BeyondStorage
Focus on providing cross-cloud data services
BeyondStorage
Comments
  • Idea: Notification (CDC) Support

    Idea: Notification (CDC) Support

    Our Storage Service may support sending notifications to let users get the changes of storage.

    This feature likes CDC(Change Data Capture) for DBMS.

    We may need to:

    • Define Change/Event struct that fit all storage services need
      • S3 Notification
        • https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html
      • Filesystem
        • inotify
        • use eBPF to capture changes.
          • https://github.com/cilium/ebpf ?
    • Support different event receiver
      • Work as a webhook?
      • Message Queue?
  • Tracking issues of go-storage 2021Q3 Roadmap

    Tracking issues of go-storage 2021Q3 Roadmap

    This issue will track tasks that split from BeyondStorage 2021Q3 Roadmap

    Make implemented services stable

    Steps

    • Implement features required by Storager
    • Passed integration tests.
    • Add docs and examples.
    • Update docs in go-storage and site.

    Services

    • [x] ftp: FTP
    • [x] gdrive: Google Drive
    • [x] hdfs: Hadoop Distributed File System
    • [x] ipfs: InterPlanetary File System
    • [x] memory: data that only in memory
    • [x] minio: MinIO
    • [ ] onedrive: Microsoft OneDrive
    • [ ] storj: StorJ
    • [ ] webdav: WebDAV

    Implement more services

    We expect to implement 9 of them in 2021Q3.

    • [ ] ocios: https://github.com/beyondstorage/go-storage/issues/692
    • [ ] glusterfs
    • [x] cephfs: https://github.com/beyondstorage/go-service-cephfs
    • [x] azfile: https://github.com/beyondstorage/go-service-azfile
    • [ ] LeanFile
    • [ ] rados
    • [x] us3: https://github.com/beyondstorage/go-service-us3
    • [x] bos: https://github.com/beyondstorage/go-service-bos
    • [x] Huawei Object Storage Service: https://github.com/beyondstorage/go-service-obs
    • [ ] LeanObject
    • [ ] Swift

    Usability and stability improve

    • [x] https://github.com/beyondstorage/go-storage/issues/680
    • [x] https://github.com/beyondstorage/go-storage/issues/646
    • [ ] New connection string layout
    • [ ] go-endpoint support default protocol?

    Related Sprints

    • https://github.com/beyondstorage/community/issues/48
  • ci(*): Upgrade minimum version to Go 1.16

    ci(*): Upgrade minimum version to Go 1.16

    1. Drop Go 1.15 and add Go 1.17 to GitHub Actions workflows. ~2. Remove tidy as the dependency of build target and add another make tidy-all step to build-test.yml. This is required otherwise make build-all will report an error when the current go.mod file indicates a higher Go version than the current installed version.~
    2. The io/ioutil package has been deprecated in Go 1.16 (See https://golang.org/doc/go1.16#ioutil). This PR replaces the existing io/ioutil functions with their new definitions in io and os packages.

    EDIT: Revert Makefile changes

  • feat: Use gg to generate code for pairs

    feat: Use gg to generate code for pairs

    This is a demo PR for evaluations.

    Related to https://github.com/beyondstorage/go-storage/issues/607.

    • Is go-codegen more friendly than go template?
    • Is go-codegen easier to learn/use/understanding?
  • Tracking issue of GSP-970: Service Factory

    Tracking issue of GSP-970: Service Factory

    • GSP: https://github.com/beyondstorage/go-storage/pull/970

    Steps

    • [x] https://github.com/beyondstorage/go-storage/pull/976
    • [ ] Generate factory in serivces
  • Error uploading path with special characters

    Error uploading path with special characters

    s, err := s3.NewStorager(
    	pairs.WithEndpoint("http:127.0.0.1:9000"),
    	pairs.WithCredential("hmac:minio:minio123456"),
    	pairs.WithLocation("us-east-1"),
    	pairs.WithName("/default"),
    	pairs.WithWorkDir("/"),
    )
    
    if err != nil {
    	fmt.Println(err)
    }
    
    f, _ := os.Open("IMG@@@_0960.JPG")
    fi, _ := f.Stat()
    
    fmt.Println(s.WriteWithContext(context.Background(), "IMG@@@¥&_0960.JPG", f, fi.Size())) // error
    fmt.Println(s.WriteWithContext(context.Background(), "IMG_0960.JPG", f, fi.Size()))      // success
    
  • GCS如何配置config string?

    GCS如何配置config string?

    懵逼中,尝试了很多次都失败,貌似是仓库地址和 x-goog-project-id 的问题,能否帮我看下,我该怎么配置连接字符串, 例如:

    access_key: abc
    secret_key: qwe project-id: 123456 url: https://console.cloud.google.com/storage/browser/bucket123 怎么配是对的? gcs://static:abc:qwe@https:console.cloud.google.com:443/bucket123 gcs://static:abc:qwe@https:console.cloud.google.com:443/bucket123/?x-goog-project-id=123456

    都是错的,我该怎么配置?谢谢!

  • services: Unify error handling

    services: Unify error handling

    Proposal: https://github.com/Xuanwo/storage/blob/master/docs/design/11-error-handling.md Spec: https://github.com/Xuanwo/storage/blob/master/docs/spec/1-error-handling.md

    • [x] azblob
    • [x] cos
    • [x] dropbox
    • [x] fs
    • [x] gcs
    • [x] kodo
    • [x] oss
    • [x] qingstor
    • [x] s3
    • [x] uss
  • When migrate to Factory init, make build failed

    When migrate to Factory init, make build failed

    When migrate to Factory init, make build failed with err:

    2021/11/19 10:56:25 not handled type &ast.FuncType{Func:1884, Params:(*ast.FieldList)(0xc0002be0f0), Results:(*ast.FieldList)(0xc0002be120)}
    

    And I just don't know what happend.

  • services/s3: Integration test fails when using the latest MinIO

    services/s3: Integration test fails when using the latest MinIO

    Excepted Behavior

    go-service-s3 should compatible with MinIO and pass integration test with MinIO.

    Current Behavior

    • Integration test passed when using minio RELEASE.2021-06-17T00-10-46Z
    • Decode REST XML response failed when using MinIO Console
      When Read a file     storager.go:55: write: Storager s3 {Name: xxxxx, WorkDir: /dc2c38b3-2de2-413c-8399-92cb1ba879e8/}, [3dd549ed-b614-45b7-9848-d33fdac98238]: unexpected: SerializationError: failed to decode REST XML response
                    status code: 200, request id:
            caused by: XML syntax error on line 1: element <link> closed by </head>
      

    Steps to Reproduce

    Run integration test for go-service-s3 with the following config:

    STORAGE_S3_INTEGRATION_TEST=on
    STORAGE_S3_CREDENTIAL=hmac:minioadmin:minioadmin
    STORAGE_S3_ENDPOINT=https:play.min.io:9443
    STORAGE_S3_NAME=<bucketname>
    STORAGE_S3_LOCATION=local
    

    Also we need to set endpoint for initialization:

    pairs.WithEndpoint("https:play.min.io:9443")
    

    Environment

    • MinIO Console
  • NewStoragerFromString doesn't register service while initiating a new storager

    NewStoragerFromString doesn't register service while initiating a new storager

    Calling NewStoragerFromString using a connection string with the value fs:///tmp, returns ErrServiceNotRegistered.

    I'm using go-service-fs/v3 as the go-storage service.

    I found out that ok's value is returned as false: https://github.com/beyondstorage/go-storage/blob/d1451868532fd29cf90633f65b607eb9ef6e472b/services/new.go#L64-L68

    Although ty is logged as fs in the error below, I think fs is not getting registered as a key in storagerFnMap, due to some issue in RegisterStorager().

    Error Returned:

    2021/07/25 21:08:35 service init failed: fs new_storager: []: service not registered
    exit status 1
    

    Code for reproducing the same error:

    package main
    
    import (
        "bytes"
        "log"
    
        "github.com/beyondstorage/go-storage/v4/pairs"
        "github.com/beyondstorage/go-service-fs/v3"
    )
    
    func main() {
        // Init a service. Fails to the register the service here.
        store, err := services.NewStoragerFromString("fs:///tmp")
        if err != nil {
            log.Fatalf("service init failed: %v", err)
        }
    
        content := []byte("Hello, world!")
        length := int64(len(content))
        r := bytes.NewReader(content)
    
        _, err = store.Write("hello", r, length)
        if err != nil {
            log.Fatalf("write failed: %v", err)
        }
    
        var buf bytes.Buffer
    
        _, err = store.Read("hello", &buf)
        if err != nil {
            log.Fatalf("storager read: %v", err)
        }
    
        log.Printf("%s", buf.String())
    }
    
  • beyondstorage.io website is down causing dependabot to break

    beyondstorage.io website is down causing dependabot to break

    The documentation website and go.beyondstorage.io are both down which causes gitlab-dependabot to throw this error:

    go.beyondstorage.io/services/fs/[email protected]: unrecognized import path "go.beyondstorage.io/services/fs/v4": https fetch: Get "https://go.beyondstorage.io/services/fs/v4?go-get=1": dial tcp: i/o timeout
    

    Dependabot has no way to skip this dependency as ignored dependencies are only skipped after the go mod package manager fetches all new versions. This error also causes dependabot to exit so I have no automated dependency updates for any packages. Can someone please fix the website or not self host it? Great library by the way!

  • fix(services/gcs): Load more then 200 objects from GCS bucket

    fix(services/gcs): Load more then 200 objects from GCS bucket

    When listing bucket that contains > 200 objects, Iterator gets stuck (returns same first 200 objects). Fixed by adding object offset supported by official gcs library.

  • services/obs: Obs does not support read with size and offset

    services/obs: Obs does not support read with size and offset

    Currently obs does not support read with size and offset. When I migrate to Factory init, the integration test requires that TestReadWithOffset item status should be pass. Before I migrate issue #1022, which I should choose?

    1. Ignore read operation
    2. Hang up the migration of obs
TurtleDex is a decentralized cloud storage platform that radically alters the landscape of cloud storage.

TurtleDex is a decentralized cloud storage platform that radically alters the landscape of cloud storage. By leveraging smart contracts, client-side e

Feb 17, 2021
Run the same Docker images in AWS Lambda and AWS ECS
Run the same Docker images in AWS Lambda and AWS ECS

serverlessish tl;dr Run the exact same image for websites in Lambda as you do in ECS, Kubernetes, etc. Just add this to your Dockerfile, listen on por

Dec 22, 2022
Go language interface to Swift / Openstack Object Storage / Rackspace cloud files (golang)

Swift This package provides an easy to use library for interfacing with Swift / Openstack Object Storage / Rackspace cloud files from the Go Language

Nov 9, 2022
High quality cloud service emulators for local development stacks

emulators High quality Google Cloud service emulators for local development stacks Why? At FullStory, our entire product and backend software stack ru

Dec 14, 2022
cloud-native local storage management system
cloud-native local storage management system

Open-Local是由多个组件构成的本地磁盘管理系统,目标是解决当前 Kubernetes 本地存储能力缺失问题。通过Open-Local,使用本地存储会像集中式存储一样简单。

Dec 30, 2022
Container Storage Interface driver for Synology NAS

Synology CSI Driver for Kubernetes The official Container Storage Interface driver for Synology NAS. Container Images & Kubernetes Compatibility Drive

Jan 5, 2023
GoDrive: A cloud storage system similar to Dropbox or Google Drive, with resilient
GoDrive: A cloud storage system similar to Dropbox or Google Drive, with resilient

Cloud Storage Service Author: Marisa Tania, Ryan Tjakrakartadinata Professor: Matthew Malensek See project spec here: https://www.cs.usfca.edu/~mmalen

Dec 7, 2021
Cloudpods is a cloud-native open source unified multi/hybrid-cloud platform developed with Golang
Cloudpods is a cloud-native open source unified multi/hybrid-cloud platform developed with Golang

Cloudpods is a cloud-native open source unified multi/hybrid-cloud platform developed with Golang, i.e. Cloudpods is a cloud on clouds. Cloudpods is able to manage not only on-premise KVM/baremetals, but also resources from many cloud accounts across many cloud providers. It hides the differences of underlying cloud providers and exposes one set of APIs that allow programatically interacting with these many clouds.

Jan 11, 2022
Simple Golang CloudNative App
 Simple Golang CloudNative App

This is a sample sample repo will explain how you build simple Golang app locally , containerise it and deploy into a Kubernetes cluster.

Nov 6, 2021
A simple Cron library for go that can execute closures or functions at varying intervals, from once a second to once a year on a specific date and time. Primarily for web applications and long running daemons.

Cron.go This is a simple library to handle scheduled tasks. Tasks can be run in a minimum delay of once a second--for which Cron isn't actually design

Dec 17, 2022
A simple Cron library for go that can execute closures or functions at varying intervals, from once a second to once a year on a specific date and time. Primarily for web applications and long running daemons.

Cron.go This is a simple library to handle scheduled tasks. Tasks can be run in a minimum delay of once a second--for which Cron isn't actually design

Dec 17, 2022
A pure Golang implementation of Rockchip rknand vendor storage interface.

go-rkvendorstorage A pure Golang implementation of Rockchip rknand vendor storage interface. Usage package main import ( "fmt" "github.com/jamesits

Nov 8, 2022
Krateo Platformops: Run your Resources on Every Cloud
Krateo Platformops: Run your Resources on Every Cloud

Krateo Platformops is an open source tool, based on CNCF projects such as Kubern

Dec 26, 2022
Vendor Go dependencies

nut Gophers love nuts. nut is a tool that allows Go projects to declare dependencies, download dependencies, rewrite import paths and ensure that depe

Sep 27, 2022
go mod vendor lets you check in your dependencies to git, but that's both bloaty (for developers) and tedious (remembering to update it).

go-mod-archiver Afraid of being unable to build historical versions of your Go program? go mod vendor lets you check in your dependencies to git, but

Dec 1, 2022
Every 10 minutes, memory, cpu and storage usage is checked and if they over 80%, sending alert via email.

linux-alert Every 10 minutes, memory, cpu and storage usage is checked and if they over 80%, sending alert via email. Usage Create .env file from .env

Feb 6, 2022
DepCharge is a tool designed to help orchestrate the execution of commands across many directories at once.

DepCharge DepCharge is a tool that helps orchestrate the execution of commands across the many dependencies and directories in larger projects. It als

Sep 27, 2022
Automatically updates the firmware of all your Shelly devices at once.

shelly-bulk-update Automatically updates the firmware of all your Shelly devices at once. Installation Download the binary for your platform: macOS cu

Nov 2, 2022
Gowl is a process management and process monitoring tool at once. An infinite worker pool gives you the ability to control the pool and processes and monitor their status.
Gowl is a process management and process monitoring tool at once. An infinite worker pool gives you the ability to control the pool and processes and monitor their status.

Gowl is a process management and process monitoring tool at once. An infinite worker pool gives you the ability to control the pool and processes and monitor their status.

Nov 10, 2022