Skip to content
6 changes: 6 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const (
APISecretFlag = "api-secret"
HidePrevPlanComments = "hide-prev-plan-comments"
QuietPolicyChecks = "quiet-policy-checks"
LockAcquireTimeoutSeconds = "lock-acquire-timeout"
LockingDBType = "locking-db-type"
LogLevelFlag = "log-level"
MarkdownTemplateOverridesDirFlag = "markdown-template-overrides-dir"
Expand Down Expand Up @@ -178,6 +179,7 @@ const (
DefaultGiteaBaseURL = "https://gitea.com"
DefaultGiteaPageSize = 30
DefaultGitlabHostname = "gitlab.com"
DefaultLockAcquireTimeoutSeconds = 0
DefaultLockingDBType = "boltdb"
DefaultLogLevel = "info"
DefaultIgnoreVCSStatusNames = ""
Expand Down Expand Up @@ -643,6 +645,10 @@ var intFlags = map[string]intFlag{
" If merge base is further behind than this number of commits from any of branches heads, full fetch will be performed.",
defaultValue: DefaultCheckoutDepth,
},
LockAcquireTimeoutSeconds: {
description: fmt.Sprintf("The number of seconds to wait for a lock to be acquired before timing out. The default value is %d", DefaultLockAcquireTimeoutSeconds),
defaultValue: DefaultLockAcquireTimeoutSeconds,
},
MaxCommentsPerCommand: {
description: "If non-zero, the maximum number of comments to split command output into before truncating.",
defaultValue: DefaultMaxCommentsPerCommand,
Expand Down
2 changes: 1 addition & 1 deletion server/controllers/events/events_controller_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,7 @@ func setupE2E(t *testing.T, repoDir string, opt setupOption) (events_controllers

defaultTFDistribution := terraformClient.DefaultDistribution()
defaultTFVersion := terraformClient.DefaultVersion()
locker := events.NewDefaultWorkingDirLocker()
locker := events.NewDefaultWorkingDirLocker(1)
parser := &config.ParserValidator{}

globalCfgArgs := valid.GlobalCfgArgs{
Expand Down
6 changes: 3 additions & 3 deletions server/controllers/locks_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ func TestDeleteLock_UpdateProjectStatus(t *testing.T) {
cp := vcsmocks.NewMockClient()
l := mocks2.NewMockDeleteLockCommand()
workingDir := mocks2.NewMockWorkingDir()
workingDirLocker := events.NewDefaultWorkingDirLocker()
workingDirLocker := events.NewDefaultWorkingDirLocker(1)
pull := models.PullRequest{
BaseRepo: models.Repo{FullName: repoName},
}
Expand Down Expand Up @@ -345,7 +345,7 @@ func TestDeleteLock_CommentFailed(t *testing.T) {
}, nil)
cp := vcsmocks.NewMockClient()
workingDir := mocks2.NewMockWorkingDir()
workingDirLocker := events.NewDefaultWorkingDirLocker()
workingDirLocker := events.NewDefaultWorkingDirLocker(1)
var backend locking.Backend
tmp := t.TempDir()
backend, err := db.New(tmp)
Expand All @@ -372,7 +372,7 @@ func TestDeleteLock_CommentSuccess(t *testing.T) {
cp := vcsmocks.NewMockClient()
dlc := mocks2.NewMockDeleteLockCommand()
workingDir := mocks2.NewMockWorkingDir()
workingDirLocker := events.NewDefaultWorkingDirLocker()
workingDirLocker := events.NewDefaultWorkingDirLocker(1)
var backend locking.Backend
tmp := t.TempDir()
backend, err := db.New(tmp)
Expand Down
2 changes: 1 addition & 1 deletion server/events/delete_lock_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestDeleteLock_Success(t *testing.T) {
l := lockmocks.NewMockLocker()
When(l.Unlock("id")).ThenReturn(&models.ProjectLock{}, nil)
workingDir := events.NewMockWorkingDir()
workingDirLocker := events.NewDefaultWorkingDirLocker()
workingDirLocker := events.NewDefaultWorkingDirLocker(1)
workspace := "workspace"
path := "path"
projectName := ""
Expand Down
2 changes: 1 addition & 1 deletion server/events/post_workflow_hooks_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (w *DefaultPostWorkflowHooksCommandRunner) RunPostHooks(ctx *command.Contex

ctx.Log.Info("Post-workflow hooks configured, running...")

unlockFn, err := w.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, DefaultWorkspace, DefaultRepoRelDir)
unlockFn, err := w.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, DefaultWorkspace, DefaultRepoRelDir, false, false)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion server/events/pre_workflow_hooks_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (w *DefaultPreWorkflowHooksCommandRunner) RunPreHooks(ctx *command.Context,

ctx.Log.Info("Pre-workflow hooks configured, running...")

unlockFn, err := w.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, DefaultWorkspace, DefaultRepoRelDir)
unlockFn, err := w.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, DefaultWorkspace, DefaultRepoRelDir, false, false)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions server/events/project_command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ func (p *DefaultProjectCommandBuilder) buildAllCommandsByCfg(ctx *command.Contex
// Need to lock the workspace we're about to clone to.
workspace := DefaultWorkspace

unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, workspace, DefaultRepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, workspace, DefaultRepoRelDir, false, false)
if err != nil {
ctx.Log.Warn("workspace was locked")
return nil, err
Expand Down Expand Up @@ -597,7 +597,7 @@ func (p *DefaultProjectCommandBuilder) buildProjectPlanCommand(ctx *command.Cont
var pcc []command.ProjectContext

ctx.Log.Debug("building plan command")
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, workspace, DefaultRepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, workspace, DefaultRepoRelDir, false, false)
if err != nil {
return pcc, err
}
Expand Down Expand Up @@ -816,7 +816,7 @@ func (p *DefaultProjectCommandBuilder) buildProjectCommand(ctx *command.Context,
}

var projCtx []command.ProjectContext
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, workspace, DefaultRepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, workspace, DefaultRepoRelDir, false, false)
if err != nil {
return projCtx, err
}
Expand Down
10 changes: 5 additions & 5 deletions server/events/project_command_builder_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ projects:
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
NewDefaultWorkingDirLocker(1),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -873,7 +873,7 @@ projects:
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
NewDefaultWorkingDirLocker(1),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1120,7 +1120,7 @@ workflows:
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
NewDefaultWorkingDirLocker(1),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1272,7 +1272,7 @@ projects:
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
NewDefaultWorkingDirLocker(1),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1414,7 +1414,7 @@ projects:
&DefaultProjectFinder{},
vcsClient,
workingDir,
NewDefaultWorkingDirLocker(),
NewDefaultWorkingDirLocker(1),
globalCfg,
&DefaultPendingPlanFinder{},
&CommentParser{ExecutableName: "atlantis"},
Expand Down
26 changes: 13 additions & 13 deletions server/events/project_command_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ terraform {
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -624,7 +624,7 @@ projects:
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -812,7 +812,7 @@ projects:
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1213,7 +1213,7 @@ projects:
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1311,7 +1311,7 @@ func TestDefaultProjectCommandBuilder_BuildMultiApply(t *testing.T) {
&events.DefaultProjectFinder{},
nil,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1397,7 +1397,7 @@ projects:
&events.DefaultProjectFinder{},
nil,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1485,7 +1485,7 @@ func TestDefaultProjectCommandBuilder_EscapeArgs(t *testing.T) {
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1647,7 +1647,7 @@ projects:
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1771,7 +1771,7 @@ projects:
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1840,7 +1840,7 @@ func TestDefaultProjectCommandBuilder_WithPolicyCheckEnabled_BuildAutoplanComman
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
globalCfg,
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -1928,7 +1928,7 @@ func TestDefaultProjectCommandBuilder_BuildVersionCommand(t *testing.T) {
&events.DefaultProjectFinder{},
nil,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -2058,7 +2058,7 @@ func TestDefaultProjectCommandBuilder_BuildPlanCommands_Single_With_RestrictFile
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down Expand Up @@ -2169,7 +2169,7 @@ func TestDefaultProjectCommandBuilder_BuildPlanCommands_with_IncludeGitUntracked
&events.DefaultProjectFinder{},
vcsClient,
workingDir,
events.NewDefaultWorkingDirLocker(),
events.NewDefaultWorkingDirLocker(1),
valid.NewGlobalCfgFromArgs(globalCfgArgs),
&events.DefaultPendingPlanFinder{},
&events.CommentParser{ExecutableName: "atlantis"},
Expand Down
14 changes: 7 additions & 7 deletions server/events/project_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func (p *DefaultProjectCommandRunner) doApprovePolicies(ctx command.ProjectConte
ctx.Log.Debug("acquired lock for project")

// Acquire internal lock for the directory we're going to operate in.
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir, false, false)
if err != nil {
return nil, "", err
}
Expand Down Expand Up @@ -458,7 +458,7 @@ func (p *DefaultProjectCommandRunner) doPolicyCheck(ctx command.ProjectContext)
// Acquire internal lock for the directory we're going to operate in.
// We should refactor this to keep the lock for the duration of plan and policy check since as of now
// there is a small gap where we don't have the lock and if we can't get this here, we should just unlock the PR.
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir, false, false)
if err != nil {
return nil, "", err
}
Expand Down Expand Up @@ -574,7 +574,7 @@ func (p *DefaultProjectCommandRunner) doPlan(ctx command.ProjectContext) (*model
ctx.Log.Debug("acquired lock for project")

// Acquire internal lock for the directory we're going to operate in.
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir, false, false)
if err != nil {
return nil, "", err
}
Expand Down Expand Up @@ -651,7 +651,7 @@ func (p *DefaultProjectCommandRunner) doApply(ctx command.ProjectContext) (apply
ctx.Log.Debug("acquired lock for project")

// Acquire internal lock for the directory we're going to operate in.
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir, false, false)
if err != nil {
return "", "", err
}
Expand Down Expand Up @@ -690,7 +690,7 @@ func (p *DefaultProjectCommandRunner) doVersion(ctx command.ProjectContext) (ver
}

// Acquire internal lock for the directory we're going to operate in.
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir, false, false)
if err != nil {
return "", "", err
}
Expand Down Expand Up @@ -731,7 +731,7 @@ func (p *DefaultProjectCommandRunner) doImport(ctx command.ProjectContext) (out
ctx.Log.Debug("acquired lock for project")

// Acquire internal lock for the directory we're going to operate in.
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir, false, false)
if err != nil {
return nil, "", err
}
Expand Down Expand Up @@ -772,7 +772,7 @@ func (p *DefaultProjectCommandRunner) doStateRm(ctx command.ProjectContext) (out
ctx.Log.Debug("acquired lock for project")

// Acquire internal lock for the directory we're going to operate in.
unlockFn, err := p.WorkingDirLocker.TryLock(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir)
unlockFn, err := p.WorkingDirLocker.TryLockWithRetry(ctx.Pull.BaseRepo.FullName, ctx.Pull.Num, ctx.Workspace, ctx.RepoRelDir, false, false)
if err != nil {
return nil, "", err
}
Expand Down
Loading
Loading