README

Bits Service

Please note: the Bits-Service is not actively maintained anymore. More information.

The bits-service is an extraction from existing functionality of the cloud controller. It encapsulates all "bits operations" into its own, separately scalable service. All bits operations comprise buildpacks, droplets, app_stashes, packages and the buildpack_cache.

The API is a work in progress and will most likely change.

Supported Backends

Bits currently supports WebDAV and the following Fog connectors:

  • AWS S3
  • Azure
  • Google
  • Local (NFS)
  • Openstack

Development

The CI config is in the bits-service-ci repo.

Additional Notes

It can be used standalone or through its BOSH-release.

Getting Started

Make sure you have a working Go environment and the Go vendoring tool glide is properly installed.

To install bitsgo:

mkdir -p $GOPATH/src/github.com/cloudfoundry-incubator
cd $GOPATH/src/github.com/cloudfoundry-incubator

git clone https://github.com/cloudfoundry-incubator/bits-service.git
cd bits-service

glide install

cd cmd/bitsgo
go install

Then run it:

bitsgo --config my/path/to/config.yml

To run tests:

  1. Install ginkgo

  2. Configure $PATH:

    export PATH=$GOPATH/bin:$PATH
    
  3. Run tests with

    scripts/run-unit-tests
    
    
    

Contributing to Bits-Service

The Bits-Service team is happy to receive feedback, suggestions, improvements and Pull Requests.

If you want to create a Pull Request against Bits-Service please make sure that the Unit Tests are passing successfully (as described in the Getting Started section)

If you would like to discuss about possible changes or improvements feel free to reach out to us via Bits-Service Cloud Foundry Slack

Expand ▾ Collapse ▴

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateTempFileWithContent

func CreateTempFileWithContent(reader io.Reader) (string, error)

func CreateTempZipFileFrom

func CreateTempZipFileFrom(bundlesPayload []Fingerprint,
	zipReader *zip.Reader,
	minimumSize, maximumSize uint64,
	blobstore Blobstore,
	metricsService MetricsService,
	logger *zap.SugaredLogger,
) (tempFilename string, err error)

func HandleBodySizeLimits

func HandleBodySizeLimits(responseWriter http.ResponseWriter, request *http.Request, maxBodySizeLimit uint64) (shouldContinue bool)

Note: this changes the request under certain conditions

func IsNotFoundError

func IsNotFoundError(e error) bool

func ShaSums

func ShaSums(filename string) (sha1Sum []byte, sha256Sum []byte, e error)

Types

type AppStashHandler

type AppStashHandler struct {
	// contains filtered or unexported fields
}

func NewAppStashHandlerWithSizeThresholds

func NewAppStashHandlerWithSizeThresholds(blobstore Blobstore, maxBodySizeLimit uint64, minimumSize uint64, maximumSize uint64, metricsService MetricsService) *AppStashHandler

func (*AppStashHandler) PostBundles

func (handler *AppStashHandler) PostBundles(responseWriter http.ResponseWriter, request *http.Request)

func (*AppStashHandler) PostEntries

func (handler *AppStashHandler) PostEntries(responseWriter http.ResponseWriter, request *http.Request)

func (*AppStashHandler) PostMatches

func (handler *AppStashHandler) PostMatches(responseWriter http.ResponseWriter, request *http.Request)

type Blobstore

type Blobstore interface {
	Exists(path string) (bool, error)

	// Implementers must return *NotFoundError when the resource cannot be found
	GetOrRedirect(path string) (body io.ReadCloser, redirectLocation string, err error)
	// Implementers must return *NotFoundError when the resource cannot be found
	Get(path string) (body io.ReadCloser, err error)

	// Implementers must return *NoSpaceLeftError when there's no space left on device.
	Put(path string, src io.ReadSeeker) error
	Copy(src, dest string) error
	Delete(path string) error
	DeleteDir(prefix string) error
}

go:generate pegomock generate --use-experimental-model-gen --package bitsgo_test Blobstore

type BuildpackMetadata

type BuildpackMetadata struct {
	Filename string `json:"filename"`
	Sha1     string `json:"sha1"`
	Sha256   string `json:"sha256"`
	Stack    string `json:"stack"`
	Key      string `json:"key"`
}

type DropletArtifactDeleter

type DropletArtifactDeleter interface {
	DeleteArtifacts(dropletGUID, dropletHash string) error
}

type Fingerprint

type Fingerprint struct {
	Fn   string `json:"fn"`
	Sha1 string `json:"sha1"`
	Size uint64 `json:"size"`
	Mode string `json:"mode"`
}

type MetricsService

type MetricsService interface {
	SendTimingMetric(name string, duration time.Duration)
	SendGaugeMetric(name string, value int64)
	SendCounterMetric(name string, value int64)
}

type NoSpaceLeftError

type NoSpaceLeftError struct {
	// contains filtered or unexported fields
}

func NewNoSpaceLeftError

func NewNoSpaceLeftError() *NoSpaceLeftError

type NotFoundError

type NotFoundError struct {
	MissingKey string
	// contains filtered or unexported fields
}

func NewNotFoundError

func NewNotFoundError() *NotFoundError

Deprecated. Use NewNotFoundErrorWithKey

func NewNotFoundErrorWithKey

func NewNotFoundErrorWithKey(key string) *NotFoundError

func NewNotFoundErrorWithMessage

func NewNotFoundErrorWithMessage(message string) *NotFoundError

Deprecated. Use NewNotFoundErrorWithKey

type NullUpdater

type NullUpdater struct{}

func (*NullUpdater) NotifyProcessingUpload

func (u *NullUpdater) NotifyProcessingUpload(guid string) error

func (*NullUpdater) NotifyUploadFailed

func (u *NullUpdater) NotifyUploadFailed(guid string, e error) error

func (*NullUpdater) NotifyUploadSucceeded

func (u *NullUpdater) NotifyUploadSucceeded(guid string, sha1 string, sha2 string) error

type ResourceHandler

type ResourceHandler struct {
	// contains filtered or unexported fields
}

func NewResourceHandler

func NewResourceHandler(blobstore Blobstore, appStashBlobstore Blobstore, resourceType string, metricsService MetricsService, maxBodySizeLimit uint64, shouldProxyGetRequests bool) *ResourceHandler

func NewResourceHandlerWithArtifactDeleter

func NewResourceHandlerWithArtifactDeleter(blobstore Blobstore, appStashBlobstore Blobstore, resourceType string, metricsService MetricsService, maxBodySizeLimit uint64, shouldProxyGetRequests bool, dropletArtifactDeleter DropletArtifactDeleter) *ResourceHandler

func NewResourceHandlerWithUpdater

func NewResourceHandlerWithUpdater(blobstore Blobstore, appStashBlobstore Blobstore, updater Updater, resourceType string, metricsService MetricsService, maxBodySizeLimit uint64, shouldProxyGetRequests bool, dropletArtifactDeleter DropletArtifactDeleter) *ResourceHandler

func NewResourceHandlerWithUpdaterAndSizeThresholds

func NewResourceHandlerWithUpdaterAndSizeThresholds(blobstore Blobstore, appStashBlobstore Blobstore, updater Updater, resourceType string, metricsService MetricsService, maxBodySizeLimit uint64, minimumSize, maximumSize uint64, shouldProxyGetRequests bool, dropletArtifactDeleter DropletArtifactDeleter) *ResourceHandler

func (*ResourceHandler) AddBuildpack

func (handler *ResourceHandler) AddBuildpack(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

func (*ResourceHandler) AddOrReplace

func (handler *ResourceHandler) AddOrReplace(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

TODO: instead of params, we could use `identifier string` to make the interface more type-safe.

Here and in the other methods.

func (*ResourceHandler) AddOrReplaceWithDigestInHeader

func (handler *ResourceHandler) AddOrReplaceWithDigestInHeader(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

TODO: instead of params, we could use `identifier string` to make the interface more type-safe.

Here and in the other methods.

func (*ResourceHandler) BuildpackMetadata

func (handler *ResourceHandler) BuildpackMetadata(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

func (*ResourceHandler) CopySourceGuid

func (handler *ResourceHandler) CopySourceGuid(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

func (*ResourceHandler) Delete

func (handler *ResourceHandler) Delete(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

func (*ResourceHandler) DeleteDir

func (handler *ResourceHandler) DeleteDir(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

func (*ResourceHandler) Get

func (handler *ResourceHandler) Get(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

func (*ResourceHandler) Head

func (handler *ResourceHandler) Head(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

type ResourceSigner

type ResourceSigner interface {
	Sign(resource string, method string, expirationTime time.Time) (signedURL string)
}

type ResponseBody

type ResponseBody struct {
	Guid      string    `json:"guid"`
	State     string    `json:"state"`
	Type      string    `json:"type"`
	CreatedAt time.Time `json:"created_at"`
	Sha1      string    `json:"sha1"`
	Sha256    string    `json:"sha256"`
}

type SignResourceHandler

type SignResourceHandler struct {
	// contains filtered or unexported fields
}

func NewSignResourceHandler

func NewSignResourceHandler(getResourceSigner, putResourceSigner ResourceSigner) *SignResourceHandler

func (*SignResourceHandler) Sign

func (handler *SignResourceHandler) Sign(responseWriter http.ResponseWriter, request *http.Request, params map[string]string)

type StateForbiddenError

type StateForbiddenError struct {
	// contains filtered or unexported fields
}

func NewStateForbiddenError

func NewStateForbiddenError() *StateForbiddenError

type Updater

type Updater interface {
	NotifyProcessingUpload(guid string) error
	NotifyUploadSucceeded(guid string, sha1 string, sha2 string) error
	NotifyUploadFailed(guid string, e error) error
}