safelock

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2022 License: MIT Imports: 17 Imported by: 0

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) *FileLock

NewFileLock creates a new instance of FileLock

func (*FileLock) ForceUnlock added in v0.4.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 RedisLock added in v0.6.0

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

RedisLock will create a lock for a specific file using redis as the lock storage As an example, if the URI is file:///filename.txt then the lock will be a file named safelock-<FILE PATH SHA3-256> and the contents will be the lock's UUID.

func NewRedisLock added in v0.6.0

func NewRedisLock(node uint16, filename string, rdb redis.UniversalClient) *RedisLock

NewRedisLock creates a new instance of RedisLock

func (*RedisLock) ForceUnlock added in v0.6.0

func (l *RedisLock) ForceUnlock() error

ForceUnlock will unlock despite ownership

func (*RedisLock) GetFilename added in v0.6.0

func (l *RedisLock) GetFilename() string

GetFilename will return the filename for the lock

func (*RedisLock) GetLockFilename added in v0.6.0

func (l *RedisLock) GetLockFilename() string

GetLockFilename will return the filename for the lock object

func (*RedisLock) GetLockState added in v0.6.0

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

GetLockState returns the lock's state

func (*RedisLock) Lock added in v0.6.0

func (l *RedisLock) Lock() error

Lock will lock

func (*RedisLock) Unlock added in v0.6.0

func (l *RedisLock) Unlock() error

Unlock will unlock

func (*RedisLock) WaitForLock added in v0.6.0

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

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

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.4.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.4.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

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

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

func (*SafeLock) GetLockBody

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

func (l *SafeLock) GetNode() int

GetNode returns the lock's node number

func (*SafeLock) GetNodeBytes

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

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

func (l *SafeLock) SetNode(node uint16)

SetNode sets the lock's node number

func (*SafeLock) SetNodeBytes

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