2021-05-13 00:56:31 +02:00
|
|
|
package bolt
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/ansible-semaphore/semaphore/db"
|
2021-05-13 15:49:32 +02:00
|
|
|
"go.etcd.io/bbolt"
|
|
|
|
"time"
|
2021-05-13 00:56:31 +02:00
|
|
|
)
|
|
|
|
|
2024-06-17 20:37:45 +02:00
|
|
|
func (d *BoltDb) CreateTaskStage(stage db.TaskStage) (db.TaskStage, error) {
|
|
|
|
newOutput, err := d.createObject(stage.TaskID, db.TaskStageProps, stage)
|
|
|
|
if err != nil {
|
|
|
|
return db.TaskStage{}, err
|
|
|
|
}
|
|
|
|
return newOutput.(db.TaskStage), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *BoltDb) GetTaskStages(projectID int, taskID int) (res []db.TaskStage, err error) {
|
|
|
|
// check if task exists in the project
|
|
|
|
_, err = d.GetTask(projectID, taskID)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
err = d.getObjects(taskID, db.TaskStageProps, db.RetrieveQueryParams{}, nil, &res)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-06-30 09:48:36 +02:00
|
|
|
func (d *BoltDb) clearTasks(projectID int, templateID int, maxTasks int) {
|
2024-06-30 15:48:59 +02:00
|
|
|
tpl, err := d.GetTemplate(projectID, templateID)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
nTasks := tpl.Tasks
|
|
|
|
|
|
|
|
if nTasks == 0 { // recalculate number of tasks for the template
|
|
|
|
|
|
|
|
n, err := d.count(projectID, db.TaskProps, db.RetrieveQueryParams{}, func(item interface{}) bool {
|
|
|
|
task := item.(db.Task)
|
|
|
|
|
|
|
|
return task.TemplateID == templateID
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if n != nTasks {
|
|
|
|
tpl.Tasks = n
|
|
|
|
err = d.UpdateTemplate(tpl)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nTasks = n
|
|
|
|
}
|
|
|
|
|
|
|
|
if nTasks < maxTasks {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-06-30 09:48:36 +02:00
|
|
|
i := 0
|
|
|
|
|
|
|
|
_ = d.db.Update(func(tx *bbolt.Tx) error {
|
|
|
|
b := tx.Bucket(makeBucketId(db.TaskProps, projectID))
|
|
|
|
if b == nil {
|
|
|
|
return db.ErrNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
c := b.Cursor()
|
|
|
|
|
|
|
|
return apply(c, db.TaskProps, db.RetrieveQueryParams{}, func(item interface{}) bool {
|
|
|
|
task := item.(db.Task)
|
|
|
|
|
|
|
|
if task.TemplateID != templateID {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
i++
|
|
|
|
return i > maxTasks
|
|
|
|
}, func(i interface{}) error {
|
|
|
|
task := i.(db.Task)
|
|
|
|
return d.deleteTaskWithOutputs(projectID, task.ID, false, tx)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *BoltDb) CreateTask(task db.Task, maxTasks int) (newTask db.Task, err error) {
|
2021-05-13 15:49:32 +02:00
|
|
|
task.Created = time.Now()
|
2021-06-24 19:45:28 +02:00
|
|
|
res, err := d.createObject(0, db.TaskProps, task)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
newTask = res.(db.Task)
|
2024-06-30 09:48:36 +02:00
|
|
|
|
|
|
|
if maxTasks > 0 {
|
|
|
|
d.clearTasks(task.ProjectID, task.TemplateID, maxTasks)
|
|
|
|
}
|
|
|
|
|
2021-05-13 15:49:32 +02:00
|
|
|
return
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *BoltDb) UpdateTask(task db.Task) error {
|
2021-05-13 21:45:54 +02:00
|
|
|
return d.updateObject(0, db.TaskProps, task)
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *BoltDb) CreateTaskOutput(output db.TaskOutput) (db.TaskOutput, error) {
|
2021-05-13 21:45:54 +02:00
|
|
|
newOutput, err := d.createObject(output.TaskID, db.TaskOutputProps, output)
|
2021-05-13 15:49:32 +02:00
|
|
|
if err != nil {
|
|
|
|
return db.TaskOutput{}, err
|
|
|
|
}
|
|
|
|
return newOutput.(db.TaskOutput), nil
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
|
|
|
|
2024-07-19 21:44:56 +02:00
|
|
|
func (d *BoltDb) getTasks(projectID int, templateID *int, params db.RetrieveQueryParams) (tasksWithTpl []db.TaskWithTpl, err error) {
|
2021-06-24 19:45:28 +02:00
|
|
|
var tasks []db.Task
|
|
|
|
|
|
|
|
err = d.getObjects(0, db.TaskProps, params, func(tsk interface{}) bool {
|
|
|
|
task := tsk.(db.Task)
|
2021-05-13 15:49:32 +02:00
|
|
|
|
|
|
|
if task.ProjectID != projectID {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-07-19 21:44:56 +02:00
|
|
|
if templateID != nil && task.TemplateID != *templateID {
|
2021-05-13 15:49:32 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}, &tasks)
|
|
|
|
|
2021-10-13 19:14:03 +02:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-05-13 15:49:32 +02:00
|
|
|
var templates = make(map[int]db.Template)
|
|
|
|
var users = make(map[int]db.User)
|
|
|
|
|
2021-06-24 19:45:28 +02:00
|
|
|
tasksWithTpl = make([]db.TaskWithTpl, len(tasks))
|
|
|
|
for i, task := range tasks {
|
2021-05-13 15:49:32 +02:00
|
|
|
tpl, ok := templates[task.TemplateID]
|
|
|
|
if !ok {
|
2024-07-19 21:44:56 +02:00
|
|
|
if templateID == nil {
|
|
|
|
tpl, _ = d.getRawTemplate(task.ProjectID, task.TemplateID)
|
|
|
|
} else {
|
|
|
|
tpl, _ = d.getRawTemplate(task.ProjectID, *templateID)
|
|
|
|
}
|
2021-05-13 15:49:32 +02:00
|
|
|
templates[task.TemplateID] = tpl
|
|
|
|
}
|
2021-06-24 19:45:28 +02:00
|
|
|
tasksWithTpl[i] = db.TaskWithTpl{Task: task}
|
|
|
|
tasksWithTpl[i].TemplatePlaybook = tpl.Playbook
|
2022-02-03 08:05:13 +01:00
|
|
|
tasksWithTpl[i].TemplateAlias = tpl.Name
|
2021-10-13 21:26:19 +02:00
|
|
|
tasksWithTpl[i].TemplateType = tpl.Type
|
2024-07-10 15:09:13 +02:00
|
|
|
tasksWithTpl[i].TemplateApp = tpl.App
|
2021-05-13 15:49:32 +02:00
|
|
|
if task.UserID != nil {
|
|
|
|
usr, ok := users[*task.UserID]
|
|
|
|
if !ok {
|
2022-10-21 22:56:32 +02:00
|
|
|
// trying to get user , but ignore error, because
|
|
|
|
// user can be deleted, and it is ok
|
|
|
|
usr, _ = d.GetUser(*task.UserID)
|
2021-05-13 15:49:32 +02:00
|
|
|
users[*task.UserID] = usr
|
|
|
|
}
|
2021-06-24 19:45:28 +02:00
|
|
|
tasksWithTpl[i].UserName = &usr.Name
|
2021-05-13 15:49:32 +02:00
|
|
|
}
|
2021-10-20 13:56:29 +02:00
|
|
|
|
|
|
|
err = tasksWithTpl[i].Fill(d)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *BoltDb) GetTask(projectID int, taskID int) (task db.Task, err error) {
|
2021-05-13 21:45:54 +02:00
|
|
|
err = d.getObject(0, db.TaskProps, intObjectID(taskID), &task)
|
2021-05-13 00:56:31 +02:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2021-10-20 13:56:29 +02:00
|
|
|
|
2021-05-13 15:49:32 +02:00
|
|
|
if task.ProjectID != projectID {
|
|
|
|
task = db.Task{}
|
2021-05-13 00:56:31 +02:00
|
|
|
err = db.ErrNotFound
|
2021-10-20 13:56:29 +02:00
|
|
|
return
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
2021-10-20 13:56:29 +02:00
|
|
|
|
2021-05-13 00:56:31 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-07-19 21:44:56 +02:00
|
|
|
func (d *BoltDb) GetTemplateTasks(projectID int, templateID int, params db.RetrieveQueryParams) ([]db.TaskWithTpl, error) {
|
|
|
|
return d.getTasks(projectID, &templateID, params)
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *BoltDb) GetProjectTasks(projectID int, params db.RetrieveQueryParams) ([]db.TaskWithTpl, error) {
|
|
|
|
return d.getTasks(projectID, nil, params)
|
|
|
|
}
|
|
|
|
|
2024-06-30 09:48:36 +02:00
|
|
|
func (d *BoltDb) deleteTaskWithOutputs(projectID int, taskID int, checkTaskExisting bool, tx *bbolt.Tx) (err error) {
|
|
|
|
|
|
|
|
if checkTaskExisting {
|
|
|
|
_, err = d.GetTask(projectID, taskID)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
|
|
|
|
2022-01-31 23:16:00 +01:00
|
|
|
err = d.deleteObject(0, db.TaskProps, intObjectID(taskID), tx)
|
2021-05-13 00:56:31 +02:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-11-09 18:49:53 +01:00
|
|
|
err = tx.DeleteBucket(makeBucketId(db.TaskOutputProps, taskID))
|
|
|
|
if err == bbolt.ErrBucketNotFound {
|
|
|
|
err = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2022-01-31 23:16:00 +01:00
|
|
|
}
|
2021-05-13 15:49:32 +02:00
|
|
|
|
2022-01-31 23:16:00 +01:00
|
|
|
func (d *BoltDb) DeleteTaskWithOutputs(projectID int, taskID int) error {
|
|
|
|
return d.db.Update(func(tx *bbolt.Tx) error {
|
2024-06-30 09:48:36 +02:00
|
|
|
return d.deleteTaskWithOutputs(projectID, taskID, true, tx)
|
2022-01-31 23:16:00 +01:00
|
|
|
})
|
2021-05-13 00:56:31 +02:00
|
|
|
}
|
|
|
|
|
2021-05-13 15:49:32 +02:00
|
|
|
func (d *BoltDb) GetTaskOutputs(projectID int, taskID int) (outputs []db.TaskOutput, err error) {
|
2021-05-13 00:56:31 +02:00
|
|
|
// check if task exists in the project
|
|
|
|
_, err = d.GetTask(projectID, taskID)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-05-13 21:45:54 +02:00
|
|
|
err = d.getObjects(taskID, db.TaskOutputProps, db.RetrieveQueryParams{}, nil, &outputs)
|
2021-05-13 15:49:32 +02:00
|
|
|
|
2021-05-13 00:56:31 +02:00
|
|
|
return
|
|
|
|
}
|