Files
atlantis/server/core/locking/apply_locking.go
Sarvar Muminov 90e92e3a13 chore: move CommandContext and CommandResult to models (#193) (#2093)
* Moved CommandContext and CommandResult to models (#193)

* Moved CommandContext and CommandResult to models

* move from models to command

rename CommandContext -> Context
rename CommandResult -> Result

* moved command related helpers into command package

* move ProjectCommandContext and ProjectResult to command/project package

* move project command context and project result

* revert unrelated code

* move tests

* fix left over

* fix linting

* fix tests

* remove unused import

* fix project context dependencies

* fix depenedecies

* fix typo
2022-03-21 10:36:13 -07:00

114 lines
3.1 KiB
Go

package locking
import (
"errors"
"time"
"github.com/runatlantis/atlantis/server/events/command"
)
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_apply_lock_checker.go ApplyLockChecker
// ApplyLockChecker is an implementation of the global apply lock retrieval.
// It returns an object that contains information about apply locks status.
type ApplyLockChecker interface {
CheckApplyLock() (ApplyCommandLock, error)
}
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_apply_locker.go ApplyLocker
// ApplyLocker interface that manages locks for apply command runner
type ApplyLocker interface {
// LockApply creates a lock for ApplyCommand if lock already exists it will
// return existing lock without any changes
LockApply() (ApplyCommandLock, error)
// UnlockApply deletes apply lock created by LockApply if present, otherwise
// it is a no-op
UnlockApply() error
ApplyLockChecker
}
// ApplyCommandLock contains information about apply command lock status.
type ApplyCommandLock struct {
// Locked is true is when apply commands are locked
// Either by using DisableApply flag or creating a global ApplyCommandLock
// DisableApply lock take precedence when set
Locked bool
Time time.Time
Failure string
}
type ApplyClient struct {
backend Backend
disableApplyFlag bool
}
func NewApplyClient(backend Backend, disableApplyFlag bool) ApplyLocker {
return &ApplyClient{
backend: backend,
disableApplyFlag: disableApplyFlag,
}
}
// LockApply acquires global apply lock.
// DisableApplyFlag takes presedence to any existing locks, if it is set to true
// this function returns an error
func (c *ApplyClient) LockApply() (ApplyCommandLock, error) {
response := ApplyCommandLock{}
if c.disableApplyFlag {
return response, errors.New("DisableApplyFlag is set; Apply commands are locked globally until flag is unset")
}
applyCmdLock, err := c.backend.LockCommand(command.Apply, time.Now())
if err != nil {
return response, err
}
if applyCmdLock != nil {
response.Locked = true
response.Time = applyCmdLock.LockTime()
}
return response, nil
}
// UnlockApply releases a global apply lock.
// DisableApplyFlag takes presedence to any existing locks, if it is set to true
// this function returns an error
func (c *ApplyClient) UnlockApply() error {
if c.disableApplyFlag {
return errors.New("apply commands are disabled until DisableApply flag is unset")
}
err := c.backend.UnlockCommand(command.Apply)
if err != nil {
return err
}
return nil
}
// CheckApplyLock retrieves an apply command lock if present.
// If DisableApplyFlag is set it will always return a lock.
func (c *ApplyClient) CheckApplyLock() (ApplyCommandLock, error) {
response := ApplyCommandLock{}
if c.disableApplyFlag {
return ApplyCommandLock{
Locked: true,
}, nil
}
applyCmdLock, err := c.backend.CheckCommandLock(command.Apply)
if err != nil {
return response, err
}
if applyCmdLock != nil {
response.Locked = true
response.Time = applyCmdLock.LockTime()
}
return response, nil
}