Skip to content

Commit 7fb3af4

Browse files
Bazhin Maksim SergeevichBazhin Maksim Sergeevich
Bazhin Maksim Sergeevich
authored and
Bazhin Maksim Sergeevich
committed
Merge branch 'develop' of github.com:FactorT/semaphore into fix-PAASCOMMON-39
2 parents c82cd3d + 75ffe9c commit 7fb3af4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+919
-418
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ echo "create database semaphore;" | mysql -uroot -p
4343
5) Compile, set up & run
4444

4545
```
46-
task compile
46+
task build
4747
go run cli/main.go setup
4848
go run cli/main.go service --config ./config.json
4949
```
@@ -64,7 +64,7 @@ As Dredd and the application database config may differ it expects it's own conf
6464

6565
1) Build Dredd hooks:
6666
````bash
67-
task compile:api:hooks
67+
task e2e:hooks
6868
```
6969
2) Install Dredd globally
7070
```bash

README.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ Semaphore UI allows you to:
3333

3434
## Key Concepts
3535

36-
1. **Projects** is a collection of related resources, configurations, and tasks. Each project allows you to organize and manage your automation efforts in one place, defining the scope of tasks such as deploying applications, running scripts, or orchestrating cloud resources. Projects help group resources, inventories, task templates, and environments for streamlined automation workflows.
37-
2. **Task Templates** are reusable definitions of tasks that can be executed on demand or scheduled. A template specifies what actions should be performed, such as running Ansible playbooks, Terraform configurations, or other automation tasks. By using templates, you can standardize tasks and easily re-execute them with minimal effort, ensuring consistent results across different environments.
38-
3. **Task** is a specific instance of a job or operation executed by Semaphore. It refers to running a predefined action (like an Ansible playbook or a script) using a task template. Tasks can be initiated manually or automatically through schedules and are tracked to give you detailed feedback on the execution, including success, failure, and logs.
39-
4. **Schedules** allow you to automate task execution at specified times or intervals. This feature is useful for running periodic maintenance tasks, backups, or deployments without manual intervention. You can configure recurring schedules to ensure important automation tasks are performed regularly and on time.
40-
5. **Inventory** is a collection of target hosts (servers, virtual machines, containers, etc.) on which tasks will be executed. The inventory includes details about the managed nodes such as IP addresses, SSH credentials, and grouping information. It allows for dynamic control over which environments and hosts your automation will interact with.
41-
6. **Environment** refers to a configuration context that holds sensitive information such as environment variables and secrets used by tasks during execution. It separates sensitive data from task templates and allows you to switch between different setups while running the same task template across different environments securely.
36+
1. **Projects** is a collection of related resources, configurations, and tasks.
37+
2. **Task Templates** are reusable definitions of tasks that can be executed on demand or scheduled.
38+
3. **Task** is a specific instance of a job or operation executed by Semaphore.
39+
4. **Schedules** allow you to automate task execution at specified times or intervals.
40+
5. **Inventory** is a collection of target hosts (servers, virtual machines, containers, etc.) on which tasks will be executed.
41+
6. **Variable Group** refers to a configuration context that holds sensitive information such as environment variables and secrets used by tasks during execution.
4242

4343
## Getting Started
4444

@@ -70,14 +70,6 @@ We recommend using the [Container Configurator](https://semaphoreui.com/install/
7070

7171
We offer a SaaS solution for using Semaphore UI without installation. Check it out at [Semaphore Cloud](https://portal.semaphoreui.com).
7272

73-
### Deploy VM from Marketplace
74-
75-
Supported cloud providers:
76-
* [Semaphore Run](https://cloud.semaphore.run/servers/new/semaphore)
77-
* [AWS](https://aws.amazon.com/marketplace/pp/prodview-5noeat2jipwca)
78-
* [Yandex Cloud](https://yandex.cloud/en-ru/marketplace/products/fastlix/semaphore)
79-
* DigitalOcean (coming soon)
80-
8173
### Other Installation Methods
8274

8375
For more installation options, visit our [Installation page](https://semaphoreui.com/install).

api-docs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,8 @@ definitions:
715715
type:
716716
- string
717717
- 'null'
718+
message:
719+
type: string
718720

719721
TaskOutput:
720722
type: object
@@ -2335,6 +2337,8 @@ paths:
23352337
type: string
23362338
git_branch:
23372339
type: string
2340+
message:
2341+
type: string
23382342
responses:
23392343
201:
23402344
description: Task queued

api/projects/runners.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
func GetRunners(w http.ResponseWriter, r *http.Request) {
1414
project := context.Get(r, "project").(db.Project)
15-
runners, err := helpers.Store(r).GetRunners(project.ID, false)
15+
runners, err := helpers.Store(r).GetRunners(project.ID, false, nil)
1616

1717
if err != nil {
1818
panic(err)

api/router.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func Route() *mux.Router {
141141
adminAPI.Path("/options").HandlerFunc(getOptions).Methods("GET", "HEAD")
142142
adminAPI.Path("/options").HandlerFunc(setOption).Methods("POST")
143143

144-
adminAPI.Path("/runners").HandlerFunc(getGlobalRunners).Methods("GET", "HEAD")
144+
adminAPI.Path("/runners").HandlerFunc(getAllRunners).Methods("GET", "HEAD")
145145
adminAPI.Path("/runners").HandlerFunc(addGlobalRunner).Methods("POST", "HEAD")
146146

147147
globalRunnersAPI := adminAPI.PathPrefix("/runners").Subrouter()
@@ -221,6 +221,8 @@ func Route() *mux.Router {
221221
projectUserAPI.Path("/tasks").HandlerFunc(projects.GetAllTasks).Methods("GET", "HEAD")
222222
projectUserAPI.HandleFunc("/tasks/last", projects.GetLastTasks).Methods("GET", "HEAD")
223223

224+
projectUserAPI.Path("/stats").HandlerFunc(projects.GetTaskStats).Methods("GET", "HEAD")
225+
224226
projectUserAPI.Path("/templates").HandlerFunc(projects.GetTemplates).Methods("GET", "HEAD")
225227
projectUserAPI.Path("/templates").HandlerFunc(projects.AddTemplate).Methods("POST")
226228

api/runners.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212
"github.com/gorilla/context"
1313
)
1414

15-
func getGlobalRunners(w http.ResponseWriter, r *http.Request) {
16-
runners, err := helpers.Store(r).GetGlobalRunners(false)
15+
func getAllRunners(w http.ResponseWriter, r *http.Request) {
16+
runners, err := helpers.Store(r).GetAllRunners(false, false)
1717

1818
if err != nil {
1919
panic(err)

db/Migration.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ func GetMigrations() []Migration {
8181
{Version: "2.12.3"},
8282
{Version: "2.12.4"},
8383
{Version: "2.12.5"},
84+
{Version: "2.12.15"},
85+
{Version: "2.13.0"},
8486
}
8587
}
8688

db/Runner.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type Runner struct {
1616
MaxParallelTasks int `db:"max_parallel_tasks" json:"max_parallel_tasks"`
1717
Active bool `db:"active" json:"active"`
1818
Name string `db:"name" json:"name"`
19+
Tag string `db:"tag" json:"tag"`
1920

2021
PublicKey *string `db:"public_key" json:"-"`
2122
}

db/Store.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,11 @@ type Store interface {
348348
SetViewPositions(projectID int, viewPositions map[int]int) error
349349

350350
GetRunner(projectID int, runnerID int) (Runner, error)
351-
GetRunners(projectID int, activeOnly bool) ([]Runner, error)
351+
GetRunners(projectID int, activeOnly bool, tag *string) ([]Runner, error)
352352
DeleteRunner(projectID int, runnerID int) error
353353
GetGlobalRunnerByToken(token string) (Runner, error)
354354
GetGlobalRunner(runnerID int) (Runner, error)
355-
GetGlobalRunners(activeOnly bool) ([]Runner, error)
355+
GetAllRunners(activeOnly bool, globalOnly bool) ([]Runner, error)
356356
DeleteGlobalRunner(runnerID int) error
357357
UpdateRunner(runner Runner) error
358358
CreateRunner(runner Runner) (Runner, error)

db/Template.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ const (
6161
SurveyVarEnum TemplateType = "enum"
6262
)
6363

64+
type AnsibleTemplateParams struct {
65+
AllowDebug bool `json:"allow_debug"`
66+
AllowOverrideInventory bool `json:"allow_override_inventory"`
67+
AllowOverrideLimit bool `json:"allow_override_limit"`
68+
Limit []string `json:"limit"`
69+
Tags []string `json:"tags"`
70+
SkipTags []string `json:"skip_tags"`
71+
}
72+
6473
type TerraformTemplateParams struct {
6574
AllowDestroy bool `json:"allow_destroy"`
6675
AllowAutoApprove bool `json:"allow_auto_approve"`
@@ -135,6 +144,31 @@ type Template struct {
135144
Tasks int `db:"tasks" json:"tasks" backup:"-"`
136145

137146
TaskParams MapStringAnyField `db:"task_params" json:"task_params"`
147+
148+
RunnerTag *string `db:"runner_tag" json:"runner_tag"`
149+
}
150+
151+
func (tpl *Template) FillParams(target interface{}) error {
152+
content, err := json.Marshal(tpl.TaskParams)
153+
if err != nil {
154+
return nil
155+
}
156+
err = json.Unmarshal(content, target)
157+
return err
158+
}
159+
160+
func (tpl *Template) CanOverrideInventory() (ok bool, err error) {
161+
switch tpl.App {
162+
case AppAnsible, "":
163+
var params AnsibleTemplateParams
164+
err = tpl.FillParams(&params)
165+
if err != nil {
166+
return
167+
}
168+
ok = params.AllowOverrideInventory
169+
}
170+
171+
return
138172
}
139173

140174
func (tpl *Template) Validate() error {

db/bolt/global_runner.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,18 @@ func (d *BoltDb) GetGlobalRunner(runnerID int) (runner db.Runner, err error) {
3636
return
3737
}
3838

39-
func (d *BoltDb) GetGlobalRunners(activeOnly bool) (runners []db.Runner, err error) {
39+
func (d *BoltDb) GetAllRunners(activeOnly bool, globalOnly bool) (runners []db.Runner, err error) {
4040
err = d.getObjects(0, db.GlobalRunnerProps, db.RetrieveQueryParams{}, func(i interface{}) bool {
4141
runner := i.(db.Runner)
42+
43+
if globalOnly && runner.ProjectID != nil {
44+
return false
45+
}
46+
4247
if activeOnly {
4348
return runner.Active
4449
}
50+
4551
return true
4652
}, &runners)
4753
return

db/bolt/runner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ func (d *BoltDb) GetRunner(projectID int, runnerID int) (runner db.Runner, err e
1111
return
1212
}
1313

14-
func (d *BoltDb) GetRunners(projectID int, activeOnly bool) (runners []db.Runner, err error) {
14+
func (d *BoltDb) GetRunners(projectID int, activeOnly bool, tag *string) (runners []db.Runner, err error) {
1515
runners = make([]db.Runner, 0)
1616
return
1717
}

db/sql/SqlDb.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,10 @@ func (d *SqlDb) GetTaskStats(projectID int, templateID *int, unit db.TaskStatUni
806806
q = q.Where("template_id=?", *templateID)
807807
}
808808

809+
if filter.UserID != nil {
810+
q = q.Where("user_id=?", *filter.UserID)
811+
}
812+
809813
if filter.Start != nil {
810814
q = q.Where("start>=?", *filter.Start)
811815
}

db/sql/global_runner.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ func (d *SqlDb) GetGlobalRunner(runnerID int) (runner db.Runner, err error) {
3333
return
3434
}
3535

36-
func (d *SqlDb) GetGlobalRunners(activeOnly bool) (runners []db.Runner, err error) {
36+
func (d *SqlDb) GetAllRunners(activeOnly bool, globalOnly bool) (runners []db.Runner, err error) {
3737
err = d.getObjects(0, db.GlobalRunnerProps, db.RetrieveQueryParams{}, func(builder squirrel.SelectBuilder) squirrel.SelectBuilder {
38+
39+
if globalOnly {
40+
builder = builder.Where("project_id is null")
41+
}
42+
3843
if activeOnly {
3944
builder = builder.Where("active=?", activeOnly)
4045
}
@@ -51,11 +56,12 @@ func (d *SqlDb) DeleteGlobalRunner(runnerID int) (err error) {
5156

5257
func (d *SqlDb) UpdateRunner(runner db.Runner) (err error) {
5358
_, err = d.exec(
54-
"update runner set name=?, active=?, webhook=?, max_parallel_tasks=? where id=?",
59+
"update runner set name=?, active=?, webhook=?, max_parallel_tasks=?, tag=? where id=?",
5560
runner.Name,
5661
runner.Active,
5762
runner.Webhook,
5863
runner.MaxParallelTasks,
64+
runner.Tag,
5965
runner.ID)
6066

6167
return
@@ -66,14 +72,15 @@ func (d *SqlDb) CreateRunner(runner db.Runner) (newRunner db.Runner, err error)
6672

6773
insertID, err := d.insert(
6874
"id",
69-
"insert into runner (project_id, token, webhook, max_parallel_tasks, name, active, public_key) values (?, ?, ?, ?, ?, ?, ?)",
75+
"insert into runner (project_id, token, webhook, max_parallel_tasks, name, active, public_key, tag) values (?, ?, ?, ?, ?, ?, ?, ?)",
7076
runner.ProjectID,
7177
token,
7278
runner.Webhook,
7379
runner.MaxParallelTasks,
7480
runner.Name,
7581
runner.Active,
76-
runner.PublicKey)
82+
runner.PublicKey,
83+
runner.Tag)
7784

7885
if err != nil {
7986
return

db/sql/migrations/v2.12.15.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
alter table `project__schedule` change `last_commit_hash` `last_commit_hash` varchar(64);
2+
alter table `task` change `commit_hash` `commit_hash` varchar(64);

db/sql/migrations/v2.13.0.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
alter table `runner` add column tag varchar(200) not null default '';
2+
alter table `project__template` add column runner_tag varchar(50);

db/sql/runner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ func (d *SqlDb) GetRunner(projectID int, runnerID int) (runner db.Runner, err er
1111
return
1212
}
1313

14-
func (d *SqlDb) GetRunners(projectID int, activeOnly bool) (runners []db.Runner, err error) {
14+
func (d *SqlDb) GetRunners(projectID int, activeOnly bool, tag *string) (runners []db.Runner, err error) {
1515
runners = make([]db.Runner, 0)
1616
return
1717
}

db/sql/template.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,40 @@ func (d *SqlDb) CreateTemplate(template db.Template) (newTemplate db.Template, e
1717

1818
insertID, err := d.insert(
1919
"id",
20-
"insert into project__template (project_id, inventory_id, repository_id, environment_id, "+
21-
"name, playbook, arguments, allow_override_args_in_task, description, `type`, start_version,"+
22-
"build_template_id, view_id, autorun, survey_vars, suppress_success_alerts, app, git_branch)"+
23-
"values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
20+
"insert into project__template ("+
21+
"project_id, inventory_id, repository_id, environment_id, name, "+
22+
"playbook, arguments, allow_override_args_in_task, description, `type`, "+
23+
"start_version, build_template_id, view_id, autorun, survey_vars, "+
24+
"suppress_success_alerts, app, git_branch, runner_tag, task_params)"+
25+
"values ("+
26+
"?, ?, ?, ?, ?, "+
27+
"?, ?, ?, ?, ?, "+
28+
"?, ?, ?, ?, ?, "+
29+
"?, ?, ?, ?, ?)",
2430
template.ProjectID,
2531
template.InventoryID,
2632
template.RepositoryID,
2733
template.EnvironmentID,
2834
template.Name,
35+
2936
template.Playbook,
3037
template.Arguments,
3138
template.AllowOverrideArgsInTask,
3239
template.Description,
3340
template.Type,
41+
3442
template.StartVersion,
3543
template.BuildTemplateID,
3644
template.ViewID,
3745
template.Autorun,
3846
db.ObjectToJSON(template.SurveyVars),
47+
3948
template.SuppressSuccessAlerts,
4049
template.App,
41-
template.GitBranch)
50+
template.GitBranch,
51+
template.RunnerTag,
52+
template.TaskParams,
53+
)
4254

4355
if err != nil {
4456
return
@@ -85,7 +97,9 @@ func (d *SqlDb) UpdateTemplate(template db.Template) error {
8597
"survey_vars=?, "+
8698
"suppress_success_alerts=?, "+
8799
"app=?, "+
88-
"`git_branch`=? "+
100+
"`git_branch`=?, "+
101+
"task_params=?, "+
102+
"runner_tag=? "+
89103
"where id=? and project_id=?",
90104
template.InventoryID,
91105
template.RepositoryID,
@@ -104,6 +118,8 @@ func (d *SqlDb) UpdateTemplate(template db.Template) error {
104118
template.SuppressSuccessAlerts,
105119
template.App,
106120
template.GitBranch,
121+
template.TaskParams,
122+
template.RunnerTag,
107123
template.ID,
108124
template.ProjectID,
109125
)
@@ -149,6 +165,7 @@ func (d *SqlDb) GetTemplates(projectID int, filter db.TemplateFilter, params db.
149165
"pt.start_version",
150166
"pt.`type`",
151167
"pt.`tasks`",
168+
"pt.runner_tag",
152169
"(SELECT `id` FROM `task` WHERE template_id = pt.id ORDER BY `id` DESC LIMIT 1) last_task_id").
153170
From("project__template pt")
154171

deployment/docker/runner/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ RUN --mount=type=cache,target=/go/pkg \
2424
task build GOOS=${TARGETOS} GOARCH=${TARGETARCH}
2525

2626

27-
ENV OPENTOFU_VERSION="1.7.0"
27+
ENV OPENTOFU_VERSION="1.9.0"
2828
ENV TERRAFORM_VERSION="1.10.3"
2929
#ENV PULUMI_VERSION="3.116.1"
3030

deployment/docker/server/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ RUN --mount=type=cache,target=/go/pkg \
2424
task build GOOS=${TARGETOS} GOARCH=${TARGETARCH}
2525

2626

27-
ENV OPENTOFU_VERSION="1.7.0"
27+
ENV OPENTOFU_VERSION="1.9.0"
2828
ENV TERRAFORM_VERSION="1.10.3"
2929
#ENV PULUMI_VERSION="3.116.1"
3030
#ENV POWERSHELL_VERSION="3.116.1"
@@ -92,6 +92,7 @@ RUN apk add --no-cache -U python3-dev build-base openssl-dev libffi-dev cargo &&
9292
chown -R semaphore:0 /opt/semaphore
9393

9494
USER 1001
95+
EXPOSE 3000
9596

9697
ENV VIRTUAL_ENV="$ANSIBLE_VENV_PATH"
9798
ENV PATH="$ANSIBLE_VENV_PATH/bin:$PATH"

0 commit comments

Comments
 (0)