Skip to content
This repository was archived by the owner on Sep 18, 2021. It is now read-only.

Commit 7b05790

Browse files
committed
feat(cli): add deploy command
1 parent c6e873c commit 7b05790

File tree

5 files changed

+94
-3
lines changed

5 files changed

+94
-3
lines changed

ansible/inventory.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ import (
44
"io/ioutil"
55
"os"
66
"path/filepath"
7+
"strings"
78
"text/template"
89
)
910

1011
// InventoryOptions is a configuration used during creation of the temporary inventory file
1112
type InventoryOptions struct {
12-
IPAddress string
13+
IPAddress string
14+
ProjectDefinitionFile string
15+
ProjectDefinitionFileName string
16+
TmpProjectDefinitionFolder string
1317
}
1418

1519
// IPAddress sets the corresponding inventory option
@@ -19,9 +23,28 @@ func IPAddress(ipAddress string) InventoryOption {
1923
}
2024
}
2125

26+
// ProjectDefinitionFile sets the corresponding inventory option
27+
func ProjectDefinitionFile(projectDefinitionFile string) InventoryOption {
28+
return func(args *InventoryOptions) {
29+
args.ProjectDefinitionFile = projectDefinitionFile
30+
}
31+
}
32+
2233
// InventoryOption is a single inventory setting
2334
type InventoryOption func(*InventoryOptions)
2435

36+
func copyFile(srcPath string, destPath string) error {
37+
input, err := ioutil.ReadFile(srcPath)
38+
if err != nil {
39+
return err
40+
}
41+
42+
if err = ioutil.WriteFile(destPath, input, 0644); err != nil {
43+
return err
44+
}
45+
return nil
46+
}
47+
2548
// CreateInventoryFile creates a temporary inventory file with the given settings and returns an absolute file path.
2649
// Note: make sure to remove the file when you don't need it anymore!
2750
func CreateInventoryFile(options ...InventoryOption) (string, error) {
@@ -41,15 +64,34 @@ func CreateInventoryFile(options ...InventoryOption) (string, error) {
4164
return "", err
4265
}
4366

67+
if len(opts.ProjectDefinitionFile) > 0 {
68+
opts.TmpProjectDefinitionFolder, err = ioutil.TempDir("", "project_definitions")
69+
if err != nil {
70+
return "", err
71+
}
72+
projectDefinitionFile := filepath.Base(opts.ProjectDefinitionFile)
73+
74+
// Copy project definition file
75+
err = copyFile(opts.ProjectDefinitionFile, filepath.Join(opts.TmpProjectDefinitionFolder, projectDefinitionFile))
76+
77+
opts.ProjectDefinitionFileName = projectDefinitionFile
78+
opts.ProjectDefinitionFileName = strings.TrimSuffix(opts.ProjectDefinitionFileName, ".yml")
79+
opts.ProjectDefinitionFileName = strings.TrimSuffix(opts.ProjectDefinitionFileName, ".yaml")
80+
}
81+
4482
t, err := template.New("ansible_inventory").Parse(`# This file was generated by StackHead.
4583
---
4684
all:
4785
vars:
4886
ansible_user: root
4987
ansible_connection: ssh
88+
stackhead__config_folder: "{{ .TmpProjectDefinitionFolder }}"
5089
hosts:
5190
mackerel:
5291
ansible_host: {{ .IPAddress }}
92+
stackhead:
93+
applications:
94+
- {{ .ProjectDefinitionFileName }}
5395
`)
5496

5597
if err = t.Execute(tmpFile, opts); err != nil {

commands/deploy.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package commands
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"sync"
7+
8+
"github.com/spf13/cobra"
9+
10+
"github.com/getstackhead/stackhead/cli/ansible"
11+
"github.com/getstackhead/stackhead/cli/routines"
12+
)
13+
14+
// DeployApplication is a command object for Cobra that provides the deploy command
15+
var DeployApplication = &cobra.Command{
16+
Use: "deploy [path to project definition] [ipv4 address]",
17+
Example: "deploy ./my_project_definition.yml 192.168.178.14",
18+
Short: "Deploy a project onto the target server",
19+
Long: `deploy will deploy the given project onto the server`,
20+
Args: cobra.ExactArgs(2),
21+
Run: func(cmd *cobra.Command, args []string) {
22+
routines.RunTask(
23+
routines.Text(fmt.Sprintf("Deploying project \"%s\" onto server with IP \"%s\"", args[0], args[1])),
24+
routines.Execute(func(wg *sync.WaitGroup, result chan routines.TaskResult) {
25+
defer wg.Done()
26+
27+
// Generate Inventory file
28+
inventoryFile, err := ansible.CreateInventoryFile(
29+
ansible.IPAddress(args[1]),
30+
ansible.ProjectDefinitionFile(args[0]),
31+
)
32+
if err == nil {
33+
defer os.Remove(inventoryFile)
34+
err = routines.ExecAnsiblePlaybook("application-deploy", inventoryFile)
35+
}
36+
37+
taskResult := routines.TaskResult{
38+
Error: err != nil,
39+
}
40+
if err != nil {
41+
taskResult.Message = err.Error()
42+
}
43+
44+
result <- taskResult
45+
}),
46+
)
47+
},
48+
}

commands/setup.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var SetupServer = &cobra.Command{
2020
Args: cobra.ExactArgs(1),
2121
Run: func(cmd *cobra.Command, args []string) {
2222
routines.RunTask(
23-
routines.Text(fmt.Sprintf("Deploying to server at IP \"%s\"", args[0])),
23+
routines.Text(fmt.Sprintf("Setting up server at IP \"%s\"", args[0])),
2424
routines.Execute(func(wg *sync.WaitGroup, result chan routines.TaskResult) {
2525
defer wg.Done()
2626

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func init() {
4545
rootCmd.AddCommand(commands.Validate)
4646
rootCmd.AddCommand(commands.Init())
4747
rootCmd.AddCommand(commands.SetupServer)
48+
rootCmd.AddCommand(commands.DeployApplication)
4849
}
4950

5051
// initConfig reads in config file and ENV variables if set.

stackhead/modules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func SplitModuleName(moduleName string) (string, string, string) {
2121
func GetModuleBaseName(moduleName string) string {
2222
moduleName = RemoveVendor(moduleName)
2323
moduleType := GetModuleType(moduleName)
24-
return strings.TrimPrefix(moduleName, moduleType + "_")
24+
return strings.TrimPrefix(moduleName, moduleType+"_")
2525
}
2626

2727
// ExtractVendor returns the vendor name of a given module name (e.g. getstackhead in getstackhead.stackhead_webserver_nginx)

0 commit comments

Comments
 (0)