kubelock

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 25, 2020 License: Apache-2.0 Imports: 8 Imported by: 3

README

GoDoc CircleCI

kubelock

Package kubelock provides functionality to create distributed locks on arbitrary kubernetes resources. It is heavily inspired by pulcy/kube-lock but uses client-go library and its dynamic client.

Usage

At Giant Swarm we run multiple instances of the same operators in different versions. Some actions performed by operators are not concurrent. Good example is IP range allocation for a newly created cluster. Each lock created by kubelock has a name and an owner. A custom name allows to create multiple locks on the same Kubernetes resource. The owner string usually contains the version of the operator acquiring the lock. That way the operator can know if the lock was acquired by itself or other operator version.

Integration Tests

You can simply create a kind cluster to run the integration tests.

kind create cluster

The tests need to figure out how to connect to the Kubernetes cluster. Therefore we need to set an environment variable pointing to your local kube config.

export E2E_KUBECONFIG=~/.kube/config

Now you can easily run the integration tests. Note that -count=1 is the idomatic way to not cache tests, which we do not want for integration tests.

go test -tags=k8srequired ./integration/test/<test-name> -count=1

Once you did your testing you may want to delete your local test cluster again.

kind delete cluster

Documentation

Index

Constants

View Source
const (
	// DefaultTTL is default time to live for the lock.
	DefaultTTL = 5 * time.Minute
)

Variables

This section is empty.

Functions

func IsAlreadyExists

func IsAlreadyExists(err error) bool

IsAlreadyExists asserts alreadyExistsError.

func IsInvalidConfig

func IsInvalidConfig(err error) bool

IsInvalidConfig asserts invalidConfigError.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound asserts notFoundError.

func IsOwnerMismatch

func IsOwnerMismatch(err error) bool

IsOwnerMismatch asserts ownerMismatchError.

Types

type AcquireOptions

type AcquireOptions struct {
	// Owner is an arbitrary string representing owner of the lock.
	Owner string
	// TTL is time to live for the lock.
	TTL time.Duration
}

type Config

type Config struct {
	DynClient dynamic.Interface

	// GVR defines a resource that the lock will be
	// created on with use of the dynamic Kubernetes client. This object
	// will be passed directly in the dynamic client API calls.
	//
	// E.g. for Namespace resource it can be instantiated like:
	//
	//	schema.GroupVersionResource{
	//		Group:    "",
	//		Version:  "v1",
	//		Resource: "namespaces",
	//	}
	//
	// E.g. for CR defined by a CRD defined in
	// https://github.com/giantswarm/apiextensions/ repository it can be
	// instantiated like:
	//
	//	schema.GroupVersionResource{
	//		Group:    v1alpha1.NewAWSConfigCRD().Spec.Group,
	//		Version:  v1alpha1.NewAWSConfigCRD().Spec.Version,
	//		Resource: v1alpha1.NewAWSConfigCRD().Spec.Names.Plural,
	//	}
	GVR schema.GroupVersionResource
}

type Interface

type Interface interface {
	// Lock creates a lock with the given name. The name will be used to
	// create annotation prefixed with "kubelock.giantswarm.io/" on the
	// Kubernetes resource. Value of this annotation stores the lock data.
	//
	// NOTE: The name parameter is not validated but it must (together with
	// the annotation prefix mentioned) be a valid annotation key.
	Lock(name string) NamespaceableLock
}

Interface is the interface of a distributed Kubernetes lock. The default implementation is KubeLock.

The typical usage for a namespace resource may look like:

kubeLock.Lock("my-lock-name").Namespace("my-namespace").Acquire(ctx, "my-configmap", kubelock.AcquireOptions{})

The typical usage for a cluster scope resource may look like:

kubeLock.Lock("my-lock-name").Acquire(ctx, "my-namespace", kubelock.ReleaseOptions{})

type KubeLock

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

func New

func New(config Config) (*KubeLock, error)

func (*KubeLock) Lock

func (k *KubeLock) Lock(name string) NamespaceableLock

type Lock

type Lock interface {
	// Acquire tries to acquire the lock on a Kubernetes resource with the
	// given name.
	//
	// This method returns an error matched by IsAlreadyExists if the lock
	// already exists on the resource, it is not expired and it has the same
	// owner (set in options).
	//
	// This method returns an error matched by IsOwnerMismatch if the lock
	// already exists on the resource and it is not expired but was acquired
	// by a different owner (set in options).
	Acquire(ctx context.Context, name string, options AcquireOptions) error
	// Release tries to release the lock on a Kubernetes resource with the
	// given name.
	//
	// This method returns an error matched by IsNotFound if the lock
	// does not exist on the resource or it is expired.
	//
	// This method returns an error matched by IsOwnerMismatch if the lock
	// already exists and it is not expired but it was acquired by
	// a different owner (set in options).
	Release(ctx context.Context, name string, options ReleaseOptions) error
}

type NamespaceableLock

type NamespaceableLock interface {
	Lock

	// Namespace creates a lock that can be acquired on Kubernetes
	// resources in the given namespace.
	Namespace(ns string) Lock
}

type ReleaseOptions

type ReleaseOptions struct {
	// Owner is an arbitrary string representing owner of the lock.
	Owner string
}

Directories

Path Synopsis
integration
env

Jump to

Keyboard shortcuts

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