git

package
v0.0.16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 9, 2021 License: MIT Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewStorageClient

func NewStorageClient() types.StorageClient

NewStorageClient creates new StorageClient

Types

type CheckoutMode

type CheckoutMode uint8

CheckoutMode configures checkout behaviour

const (
	// CheckoutModeDefault is default checkout mode - no special behaviour
	CheckoutModeDefault CheckoutMode = 1 << iota
	// CheckoutModeCreate will indicate that the new local branch needs to be created at checkout
	CheckoutModeCreate
	// CheckoutModeRemote will indicate that the remote branch needs to be checked out
	CheckoutModeRemote
)

type RequestMetadataParams

type RequestMetadataParams struct {
	Repository, Ref, State string
}

RequestMetadataParams is Git storage specific parameters

func (*RequestMetadataParams) String

func (params *RequestMetadataParams) String() string

String is a human readable representation for this params set

type StorageClient

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

StorageClient implementation for Git storage type

func (*StorageClient) Connect

func (storageClient *StorageClient) Connect(p types.RequestMetadataParams) error

Connect will clone this git repository to a virtual in-memory FS (or use previosly cloned cache), and put an exclusive lock (mutex, not TF lock) on it.

This StorageClient implementation will use go-git and virtual in-memory FS as git local working tree. Each unique RequestMetadataParams.Repository will receive it's own in-memory FS instance. That FS will be shared among different requests to the same repository, and it will live in memory until backend restarts. This is to speed up various git actions and avoid fresh clone every time, which might be time consuming.

Since simple TF-level actions like update state or lock/unlock in this implementation involves complex add-commit-push routines that aren't really an atomic operations, and the local working tree is shared by multiple requests to the same git repository, parallel requests can mess up the local working tree and leave it in broken state.

Example - while one tree checked out the locking branch and preparing the lock metadata to write, another request came in for totally different state and it would checkout back to Ref and pull it from remote.

Hence we just assume that Git type of storage does not support parallel connections to the same repository, and each connection will lock this repository from usage by other threads within the same backend instance.

This is not currently implemented, but if the user values parallel connections feature over overall performance/memory requirements - we can use something else for the StorageClient.sessions map key. The locking/unlocking would still be required for thread-safety. That could be a configurable option.

func (*StorageClient) DeleteState

func (storageClient *StorageClient) DeleteState(p types.RequestMetadataParams) error

DeleteState delete the state from storage Checkout the Ref, pull the latest and attempt to delete the state file from there. Then commit and push.

func (*StorageClient) Disconnect

func (storageClient *StorageClient) Disconnect(p types.RequestMetadataParams)

Disconnect from Git storage. There's nothing to "disconnect" really. We just need to unlock the local working copy for other threads.

func (*StorageClient) ForceUnLockWorkaroundMessage

func (storageClient *StorageClient) ForceUnLockWorkaroundMessage(p types.RequestMetadataParams) string

ForceUnLockWorkaroundMessage suggest the user to delete locking branch

func (*StorageClient) GetState

func (storageClient *StorageClient) GetState(p types.RequestMetadataParams) ([]byte, error)

GetState will checkout into Ref, pull the latest from remote, and try to read the state file from there. Will return ErrStateDidNotExisted if the state file did not existed.

func (*StorageClient) LockState

func (storageClient *StorageClient) LockState(p types.RequestMetadataParams, lock []byte) error

LockState this implementation for Git storage will create and push a new branch to remote. The branch name will be the name of the state file prefixed by "locks/". Next to the state file in subject, there will be a ".lock" file added and commited, that will contain the lock metadata. If pushing that branch to remote fails (no fast-forward allowed), that would mean something else already aquired the lock before this. That approach would make a locking operation atomic.

There's obviosly more than one way to implement the locking with Git. This implementation aims to avoid complex Git scenarios that would involve Git merges and dealing with Git conflicts. In other words, we are trying to keep the local working tree fast-forwardable at all times.

And remember - git repository hosting the state is a "backend" storage and it's not meant to be used by people.

func (*StorageClient) ParseMetadataParams

func (storageClient *StorageClient) ParseMetadataParams(request *http.Request, metadata *types.RequestMetadata) error

ParseMetadataParams read request parameters specific to Git storage type

func (*StorageClient) ReadStateLock

func (storageClient *StorageClient) ReadStateLock(p types.RequestMetadataParams) ([]byte, error)

ReadStateLock read the lock metadata from storage. This will fetch locks refs and try to checkout using remote lock branch. If it can't pull ("no reference found" error), means the lock didn't exist - ErrLockMissing returned. Otherwise it will read the lock metadata from remote HEAD and return it in buffer.

func (*StorageClient) UnLockState

func (storageClient *StorageClient) UnLockState(p types.RequestMetadataParams) error

UnLockState for Git storage type, unlocking is a simple branch deleting remotely

func (*StorageClient) UpdateState

func (storageClient *StorageClient) UpdateState(p types.RequestMetadataParams, state []byte) error

UpdateState write the state to storage. It will checkout the Ref, pull the latest and try to add and commit the state in the request. The file in repository will either be created or overwritten.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL