Skip to content

Commit e892c8f

Browse files
committed
wip, run-role
1 parent 6b1c4a4 commit e892c8f

File tree

12 files changed

+170
-7
lines changed

12 files changed

+170
-7
lines changed

.kiss.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,28 @@ hosts:
1919
shell:
2020
command: echo "Foo"
2121

22+
# Role specific tasks
23+
roles:
24+
common:
25+
tasks:
26+
- task: Common task
27+
shell:
28+
command: whoami
29+
docker:
30+
with: [common]
31+
tasks:
32+
- task: install docker
33+
description: Install docker
34+
apt-get:
35+
update: yes
36+
packages: [docker.io]
37+
db:
38+
with: [common]
39+
tasks:
40+
- task: Install MySQL
41+
apt-get:
42+
update: yes
43+
packages: [mysql-server]
2244

2345
# Global tasks
2446
tasks:

commands/commands.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@ package commands
22

33
import "github.com/tobscher/kiss/logging"
44

5-
var logger = logging.GetLogger("kiss")
5+
var (
6+
logger = logging.GetLogger("kiss")
7+
configFile string
8+
verbose bool
9+
)

commands/run-role.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package commands
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/spf13/cobra"
8+
"github.com/tobscher/kiss/configuration"
9+
"github.com/tobscher/kiss/core"
10+
"github.com/tobscher/kiss/logging"
11+
)
12+
13+
// NewRunRoleCommand creates a new command to run a task.
14+
func NewRunRoleCommand() *cobra.Command {
15+
command := &cobra.Command{
16+
Use: "run-role",
17+
Short: "Run a role",
18+
Long: "Run a role on all remote systems with that role.",
19+
Run: runRoleRun,
20+
}
21+
command.Flags().StringVar(&configFile, "config", ".kiss.yml", "path to config file")
22+
command.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
23+
24+
return command
25+
}
26+
27+
func runRoleRun(cmd *cobra.Command, args []string) {
28+
if verbose {
29+
logger.SetLevel(logging.DEBUG)
30+
core.SetLogLevel(logging.DEBUG)
31+
}
32+
33+
config := configuration.Load(configFile)
34+
35+
if len(args) < 1 {
36+
fmt.Printf("Error: Expected role-name: kiss run-role <role-name>\n")
37+
os.Exit(1)
38+
}
39+
40+
// Try to find task in global list
41+
roleName := args[0]
42+
role, ok := config.Roles[roleName]
43+
if !ok {
44+
fmt.Printf("Error: Role not found: %v\n", roleName)
45+
os.Exit(1)
46+
}
47+
48+
logger.Infof("Running role `%v`", roleName)
49+
for _, host := range config.Hosts.WithRole(roleName) {
50+
logger.Infof("Selecting host `%v`", host.Host)
51+
52+
for _, task := range role.Tasks {
53+
runWithRunner(&task, &host)
54+
}
55+
}
56+
}

commands/run.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ import (
1111
"github.com/tobscher/kiss/logging"
1212
)
1313

14-
var (
15-
configFile string
16-
verbose bool
17-
)
18-
1914
// NewRunCommand creates a new command to run a task.
2015
func NewRunCommand() *cobra.Command {
2116
command := &cobra.Command{

configuration/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Configuration struct {
1515
Vars map[string]string
1616
Hosts HostCollection
1717
Tasks TaskCollection
18+
Roles RoleCollection
1819
}
1920

2021
// Load loads configuration from the given path.

configuration/config_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,20 @@ func TestTasks(t *testing.T) {
119119
t.Error("Expected command to be go version.")
120120
}
121121
}
122+
123+
func TestRoles(t *testing.T) {
124+
config := Load("./fixtures/example.yml")
125+
126+
if len(config.Roles) != 4 {
127+
t.Errorf("Expected 3 roles got %v.", len(config.Roles))
128+
}
129+
130+
docker := config.Roles["docker"]
131+
if !arrayIncludes(docker.With, "common") {
132+
t.Error("Expected role docker to be based of common.")
133+
}
134+
135+
if len(docker.Tasks) != 2 {
136+
t.Errorf("Expected role docker to have 2 tasks got %v.", len(docker.Tasks))
137+
}
138+
}

configuration/fixtures/example.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,39 @@ hosts:
2929
- docker
3030
- db
3131

32+
# Role specific tasks
33+
roles:
34+
common:
35+
tasks:
36+
- task: Common task
37+
shell:
38+
command: whoami
39+
docker:
40+
with: [common]
41+
tasks:
42+
- task: install_docker
43+
description: Install docker
44+
apt-get:
45+
update: yes
46+
packages: [docker.io]
47+
- task: run_docker
48+
description: run docker daemon
49+
shell:
50+
command: docker -d &
51+
db:
52+
with: [common]
53+
tasks:
54+
- task: Install MySQL
55+
apt-get:
56+
update: yes
57+
packages: [mysql-server]
58+
web:
59+
with: [common]
60+
tasks:
61+
- task: Install ruby
62+
shell:
63+
command: echo "Install ruby..."
64+
3265
# Global tasks
3366
tasks:
3467
- task: Environment

configuration/helpers_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package configuration
2+
3+
func arrayIncludes(haystack []string, needle string) bool {
4+
for _, v := range haystack {
5+
if v == needle {
6+
return true
7+
}
8+
}
9+
10+
return false
11+
}

configuration/hosts.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,18 @@ func (h HostCollection) Get(name string) *Host {
2929

3030
return nil
3131
}
32+
33+
// WithRole returns all hosts with the given role name.
34+
func (h HostCollection) WithRole(roleName string) HostCollection {
35+
var hosts HostCollection
36+
37+
for _, host := range h {
38+
for _, role := range host.Roles {
39+
if role == roleName {
40+
hosts = append(hosts, host)
41+
}
42+
}
43+
}
44+
45+
return hosts
46+
}

configuration/roles.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package configuration
2+
3+
type RoleCollection map[string]Role
4+
5+
type Role struct {
6+
With []string
7+
Tasks TaskCollection
8+
}

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ func main() {
66
rootCmd := commands.NewRootCommand()
77
rootCmd.AddCommand(commands.NewVersionCommand(name, version))
88
rootCmd.AddCommand(commands.NewRunCommand())
9+
rootCmd.AddCommand(commands.NewRunRoleCommand())
910
rootCmd.AddCommand(commands.NewTasksCommand())
1011
rootCmd.AddCommand(commands.NewHostsCommand())
1112

plugins/core/plugin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func Serve() {
4141
for {
4242
conn, err := l.Accept()
4343
if err != nil {
44-
log.Fatal(err)
44+
logger.Fatal(err.Error())
4545
}
4646

4747
go server.ServeCodec(jsonrpc.NewServerCodec(conn))

0 commit comments

Comments
 (0)