mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-08-04 00:38:42 +00:00
* fix: add path to WorkingDir methods `WorkingDirLocker` and `WorkingDir` are closely related -- the former acquires a lock, which ensures that the latter can safely operate on a given file path. In #2131 we added `path` to the `WorkingDirLocker` lock key, but neglected to add the same to `WorkingDir`. This commit adds `path` as an argument to certain `WorkingDir` methods, and includes `path` in the directory that we use to clone the repository for a given project. Since `path` can include certain special characters such as `/`, we encode `path` as base32 when using it as part of a file path. This should ensure no special characters are used in the filesystem, and that the value can be decoded if desired (unlike hashes such as md5). Additional changes: - All calls to changed methods have been updated, including unit tests - Mocks have been regenerated for `WorkingDir` and `WorkingDirLocker` - `working_dir_test.go` - Commands that operate on filesystem paths have been updated to include the base32 encoded `path` value - When running `git init`, we include `-b master` as additional arguments, to ensure that `master` is our default branch (expected by the unit tests) * Try fixing E2E tests * Fix DefaultPendingPlanFinder In addition to iterating over `workspaceDirs`, also iterate over `pathDirs`, and use both `workspace` and `path` to build `repoDir`. * Fix DefaultPendingPlanFinder unit tests * Fix DefaultProjectCommandBuilder unit tests Co-authored-by: Kevin Snyder <kevinsnyder@KevinSnydersMBP.lan> Co-authored-by: Kevin Snyder <kevinsnyder@ip-192-168-1-188.ec2.internal>
83 lines
2.7 KiB
Go
83 lines
2.7 KiB
Go
package events
|
|
|
|
import (
|
|
"github.com/runatlantis/atlantis/server/core/db"
|
|
"github.com/runatlantis/atlantis/server/core/locking"
|
|
"github.com/runatlantis/atlantis/server/events/models"
|
|
"github.com/runatlantis/atlantis/server/logging"
|
|
)
|
|
|
|
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_delete_lock_command.go DeleteLockCommand
|
|
|
|
// DeleteLockCommand is the first step after a command request has been parsed.
|
|
type DeleteLockCommand interface {
|
|
DeleteLock(id string) (*models.ProjectLock, error)
|
|
DeleteLocksByPull(repoFullName string, pullNum int) (int, error)
|
|
}
|
|
|
|
// DefaultDeleteLockCommand deletes a specific lock after a request from the LocksController.
|
|
type DefaultDeleteLockCommand struct {
|
|
Locker locking.Locker
|
|
Logger logging.SimpleLogging
|
|
WorkingDir WorkingDir
|
|
WorkingDirLocker WorkingDirLocker
|
|
DB *db.BoltDB
|
|
}
|
|
|
|
// DeleteLock handles deleting the lock at id
|
|
func (l *DefaultDeleteLockCommand) DeleteLock(id string) (*models.ProjectLock, error) {
|
|
lock, err := l.Locker.Unlock(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if lock == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
l.deleteWorkingDir(*lock)
|
|
return lock, nil
|
|
}
|
|
|
|
// DeleteLocksByPull handles deleting all locks for the pull request
|
|
func (l *DefaultDeleteLockCommand) DeleteLocksByPull(repoFullName string, pullNum int) (int, error) {
|
|
locks, err := l.Locker.UnlockByPull(repoFullName, pullNum)
|
|
numLocks := len(locks)
|
|
if err != nil {
|
|
return numLocks, err
|
|
}
|
|
if numLocks == 0 {
|
|
l.Logger.Debug("No locks found for pull")
|
|
return numLocks, nil
|
|
}
|
|
|
|
for i := 0; i < numLocks; i++ {
|
|
lock := locks[i]
|
|
l.deleteWorkingDir(lock)
|
|
}
|
|
|
|
return numLocks, nil
|
|
}
|
|
|
|
func (l *DefaultDeleteLockCommand) deleteWorkingDir(lock models.ProjectLock) {
|
|
// NOTE: Because BaseRepo was added to the PullRequest model later, previous
|
|
// installations of Atlantis will have locks in their DB that do not have
|
|
// this field on PullRequest. We skip deleting the working dir in this case.
|
|
if lock.Pull.BaseRepo == (models.Repo{}) {
|
|
l.Logger.Debug("Not deleting the working dir.")
|
|
return
|
|
}
|
|
unlock, err := l.WorkingDirLocker.TryLock(lock.Pull.BaseRepo.FullName, lock.Pull.Num, lock.Workspace, lock.Project.Path)
|
|
if err != nil {
|
|
l.Logger.Err("unable to obtain working dir lock when trying to delete old plans: %s", err)
|
|
} else {
|
|
defer unlock()
|
|
// nolint: vetshadow
|
|
if err := l.WorkingDir.DeleteForWorkspace(lock.Pull.BaseRepo, lock.Pull, lock.Workspace, lock.Project.Path); err != nil {
|
|
l.Logger.Err("unable to delete workspace: %s", err)
|
|
}
|
|
}
|
|
if err := l.DB.UpdateProjectStatus(lock.Pull, lock.Workspace, lock.Project.Path, models.DiscardedPlanStatus); err != nil {
|
|
l.Logger.Err("unable to delete project status: %s", err)
|
|
}
|
|
}
|