safelock

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2022 License: MIT Imports: 15 Imported by: 1

README

SafeLock

SafeLock is a golang package for locking files used by distributed services.

Use SafeLock when distributed processes act on the same file on a local or remote filesystem and require exclusive access to that file. SafeLock should not be used to protect access in non-distributed systems as better mechanisms exist.

To use this module add import "github.com/deptofdefense/safelock" to your package.

Example

To use the lock in AWS S3 you could use this code:

svcS3 := s3.NewFromConfig(cfg)
bucket := "bucket"
key := "key"
kmsKeyArn := "kmsKeyArn"
l := safelock.NewS3ObjectLock(bucket, key, kmsKeyArn, &svcS3)

// Wait for the lock to become available
l.WaitForLock()

// Lock the object and defer unlocking
l.Lock()
defer l.Unlock()

// Do work on the object that was locked

This can also be accomplished with a local filesystem:

fs := afero.NewOsFs()
filename := "file.txt"
l := safelock.NewFileLock(filename, fs)

SafeLock also provides a primitive to build your own lock named SafeLock.

Testing

Testing can be done using the Makefile targets make test and make test_coverage.

Development

Development for this has been geared towards MacOS users. Install dependencies to get started:

brew install circleci go golangci-lint pre-commit shellcheck

Install the pre-commit hooks and run them before making pull requests:

pre-commit install
pre-commit run -a

License

This project constitutes a work of the United States Government and is not subject to domestic copyright protection under 17 USC § 105. However, because the project utilizes code licensed from contributors and other third parties, it therefore is licensed under the MIT License. See LICENSE file for more information.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FileLock

type FileLock struct {
	*SafeLock
	// contains filtered or unexported fields
}

FileLock will create a lock for a specific file As an example, if the URI is file:///filename.txt then the lock will be a file named file:///filename.txt.lock and the contents will be the lock's UUID.

func NewFileLock

func NewFileLock(node uint16, filename string, fs afero.Fs) *FileLock

NewFileLock creates a new instance of FileLock

func (*FileLock) ForceUnlock added in v0.2.0

func (l *FileLock) ForceUnlock() error

ForceUnlock will unlock despite ownership

func (*FileLock) GetFilename

func (l *FileLock) GetFilename() string

GetFilename will return the filename for the lock

func (*FileLock) GetLockFilename

func (l *FileLock) GetLockFilename() string

GetLockFilename will return the filename for the lock object

func (*FileLock) GetLockState

func (l *FileLock) GetLockState() (LockState, error)

GetLockState returns the lock's state

func (*FileLock) Lock

func (l *FileLock) Lock() error

Lock will lock

func (*FileLock) Unlock

func (l *FileLock) Unlock() error

Unlock will unlock

func (*FileLock) WaitForLock

func (l *FileLock) WaitForLock(timeout time.Duration) error

WaitForLock waits until an object is no longer locked or cancels based on a timeout

type LockS3Client

type LockS3Client interface {
	DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error)
	GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error)
	HeadObject(ctx context.Context, params *s3.HeadObjectInput, optFns ...func(*s3.Options)) (*s3.HeadObjectOutput, error)
	PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error)
}

LockS3Client implements the interface required by S3 for the lock functions

type LockState

type LockState string
const (
	// LockStateLocked is the locked state
	LockStateLocked LockState = "locked"
	// LockStateUnlocked is the unlocked state
	LockStateUnlocked LockState = "unlocked"
	// LockStateUnknown is the unknown lock state
	LockStateUnknown LockState = "unknown"

	// DefaultTimeout is the default timeout used for locks
	DefaultTimeout time.Duration = 30 * time.Second

	// DefaultSuffix is the default lock suffix used for locks
	DefaultSuffix = ".lock"
)

type S3ObjectLock

type S3ObjectLock struct {
	*SafeLock
	// contains filtered or unexported fields
}

S3ObjectLock will create a lock for a specific bucket/key combination As an example, if the URI is s3://s3Bucket/s3Key then the lock will be a file named s3://s3Bucket/s3Key.lock and the contents will be the lock's UUID.

func NewS3ObjectLock

func NewS3ObjectLock(node uint16, s3bucket, s3key, s3KMSKeyArn string, svcS3 LockS3Client) *S3ObjectLock

NewS3ObjectLock creates a new instance of S3ObjectLock

func (*S3ObjectLock) ForceUnlock added in v0.2.0

func (l *S3ObjectLock) ForceUnlock() error

ForceUnlock will unlock despite ownership

func (*S3ObjectLock) GetLockPath

func (l *S3ObjectLock) GetLockPath() string

GetLockPath will return the s3 key for the lock object

func (*S3ObjectLock) GetLockState

func (l *S3ObjectLock) GetLockState() (LockState, error)

GetLockState returns the lock's state

func (*S3ObjectLock) GetLockURI

func (l *S3ObjectLock) GetLockURI() string

GetLockURI will return the s3 object URI for the lock object

func (*S3ObjectLock) GetObjectURI

func (l *S3ObjectLock) GetObjectURI() string

GetS3ObjectURI will return the s3 object URI for the file being locked

func (*S3ObjectLock) GetS3Bucket

func (l *S3ObjectLock) GetS3Bucket() string

GetS3Bucket will return the s3 bucket for the lock

func (*S3ObjectLock) GetS3KMSKeyArn

func (l *S3ObjectLock) GetS3KMSKeyArn() string

GetS3KMSKeyArn will return the s3 KMS key Arn for the lock

func (*S3ObjectLock) GetS3Key

func (l *S3ObjectLock) GetS3Key() string

GetS3Key will return the s3 key for the lock

func (*S3ObjectLock) Lock

func (l *S3ObjectLock) Lock() error

Lock will lock

func (*S3ObjectLock) Unlock

func (l *S3ObjectLock) Unlock() error

Unlock will unlock

func (*S3ObjectLock) WaitForLock

func (l *S3ObjectLock) WaitForLock(timeout time.Duration) error

WaitForLock waits until an object is no longer locked or cancels based on a timeout

type SafeLock

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

SafeLock manages the internal locking and metadata for locks

func NewSafeLock

func NewSafeLock(node uint16) *SafeLock

NewSafeLock creates a new instance of SafeLock

func (*SafeLock) ForceUnlock added in v0.2.0

func (l *SafeLock) ForceUnlock() error

ForceUnlock will unlock despite a lack of ownership

func (*SafeLock) GetID

func (l *SafeLock) GetID() uint64

GetID returns the lock's id

func (*SafeLock) GetIDBytes added in v0.2.0

func (l *SafeLock) GetIDBytes() []byte

GetIDBytes returns the lock's id in the form of a byte slice

func (*SafeLock) GetLockBody added in v0.2.0

func (l *SafeLock) GetLockBody() []byte

GetLockBody returns the byte slice representation of the lock for the lock file

func (*SafeLock) GetLockState

func (l *SafeLock) GetLockState() (LockState, error)

GetLockState returns the lock's state

func (*SafeLock) GetLockSuffix

func (l *SafeLock) GetLockSuffix() string

GetLockSuffix returns the lock suffix being used

func (*SafeLock) GetLockURI

func (l *SafeLock) GetLockURI() string

GetLockURI will return the URI for the lock object

func (*SafeLock) GetNode added in v0.2.0

func (l *SafeLock) GetNode() int

GetNode returns the lock's node number

func (*SafeLock) GetNodeBytes added in v0.2.0

func (l *SafeLock) GetNodeBytes() []byte

GetNodeBytes returns the lock's node number in the form of a byte slice

func (*SafeLock) GetTimeout

func (l *SafeLock) GetTimeout() time.Duration

GetTimeout returns the timeout being used

func (*SafeLock) Lock

func (l *SafeLock) Lock() error

Lock will lock

func (*SafeLock) SetID

func (l *SafeLock) SetID(id uint64)

SetID sets the lock's id

func (*SafeLock) SetIDBytes added in v0.2.0

func (l *SafeLock) SetIDBytes(buf []byte) error

SetIDBytes sets the lock's id using a little-endian encoded uint32

func (*SafeLock) SetLockSuffix

func (l *SafeLock) SetLockSuffix(lockSuffix string)

SetLockSuffix sets the lock suffix to use

func (*SafeLock) SetNode added in v0.2.0

func (l *SafeLock) SetNode(node uint16)

SetNode sets the lock's node number

func (*SafeLock) SetNodeBytes added in v0.2.0

func (l *SafeLock) SetNodeBytes(buf []byte) error

SetNodeBytes sets the lock's node number using a little endian encoded uint16

func (*SafeLock) SetTimeout

func (l *SafeLock) SetTimeout(timeout time.Duration)

SetTimeout sets the timeout to use

func (*SafeLock) Unlock

func (l *SafeLock) Unlock() error

Unlock will unlock

func (*SafeLock) WaitForLock

func (l *SafeLock) WaitForLock(time.Duration) error

WaitForLock waits until an object is no longer locked or cancels based on a timeout

type SafeLockiface

type SafeLockiface interface {
	Lock() error
	Unlock() error
	ForceUnlock() error
	GetID() uint64
	GetNode() uint16
	GetIDBytes() []byte
	GetNodeBytes() []byte
	SetID(uint64)
	SetNode(uint16)
	SetIDBytes([]byte) error
	SetNodeBytes([]byte) error
	GetLockBody() []byte
	GetLockState() (LockState, error)
	GetLockURI() string
	GetLockSuffix() string
	SetLockSuffix(string)
	GetTimeout() time.Duration
	SetTimeout(time.Duration)
	WaitForLock(time.Duration) error
}

SafeLockiface is an interface for all implementations of locks

Directories

Path Synopsis
cmd
internal

Jump to

Keyboard shortcuts

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