Skip to content

Commit

Permalink
provision/ec2: colourize and emojify ec2 provisioning (#606)
Browse files Browse the repository at this point in the history
* cmd/core: always use cyan for prompts

* cmd/core: add Forintf api

* provision/ec2: colourize output

closes #597
  • Loading branch information
bobheadxi authored Mar 17, 2019
1 parent e96e535 commit 78a1c4b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
2 changes: 1 addition & 1 deletion cmd/core/utils/input/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func ChooseFromListWalkthrough(optionName string, options []string) (string, err
for _, o := range options {
out.Println(" > " + o)
}
out.Printf("Please enter your desired %s: ", optionName)
out.Print(out.C("Please enter your desired %s: ", out.CY).With(optionName))

var response string
_, err := fmt.Fscanln(os.Stdin, &response)
Expand Down
10 changes: 10 additions & 0 deletions cmd/core/utils/out/decor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package out

import (
"fmt"
"io"
"os"

"github.com/fatih/color"
Expand Down Expand Up @@ -35,6 +36,15 @@ func Sprintf(format string, args ...interface{}) string {
return fmt.Sprintf(format, args...)
}

// Fprintf wraps formatters
func Fprintf(out io.Writer, format string, args ...interface{}) {
if WithEmoji() {
emoji.Fprintf(out, format, args...)
} else {
fmt.Fprintf(out, format, args...)
}
}

// Printf wraps formatters
func Printf(format string, args ...interface{}) {
if WithEmoji() {
Expand Down
13 changes: 8 additions & 5 deletions cmd/provision/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ This ensures that your project ports are properly exposed and externally accessi
stringProjectPorts, _ = cmd.Flags().GetStringArray(flagPorts)
)
if stringProjectPorts == nil || len(stringProjectPorts) == 0 {
out.Print("[WARNING] no project ports provided - this means that no ports" +
"will be exposed on your ec2 host. Use the '--ports' flag to set" +
"ports that you want to be accessible.\n")
out.Print(out.C("[WARNING] no project ports provided - this means that no ports"+
"will be exposed on your ec2 host. Use the '--ports' flag to set"+
"ports that you want to be accessible.\n", out.RD))
}
var highlight = out.NewColorer(out.CY)

// Load flags for credentials
var (
Expand Down Expand Up @@ -139,7 +140,7 @@ This ensures that your project ports are properly exposed and externally accessi

// Prompt for region
out.Println("See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions for a list of available regions.")
region, err := input.Prompt("Please enter a region: ")
region, err := input.Prompt(highlight.S("Please enter a region: "))
if err != nil {
out.Fatal(err)
}
Expand Down Expand Up @@ -183,6 +184,7 @@ This ensures that your project ports are properly exposed and externally accessi
if err != nil {
out.Fatal(err)
}
out.Println(highlight.Sf("Instance provisioned for remote '%s'!", args[0]))

// Save new remote to configuration
local.SaveRemote(remote)
Expand All @@ -193,7 +195,7 @@ This ensures that your project ports are properly exposed and externally accessi
})

// Bootstrap remote
out.Printf("Initializing Inertia daemon at %s...\n", inertia.Remote.IP)
out.Println(highlight.Sf("Initializing Inertia daemon at %s...", inertia.Remote.IP))
var repo = common.ExtractRepository(common.GetSSHRemoteURL(root.project.URL))
if err := bootstrap.Bootstrap(inertia, bootstrap.Options{
RepoName: repo,
Expand All @@ -203,6 +205,7 @@ This ensures that your project ports are properly exposed and externally accessi
}

// Save updated config
out.Println(highlight.S("Saving remote..."))
if err := local.SaveRemote(remote); err != nil {
out.Fatal(err.Error())
}
Expand Down
24 changes: 17 additions & 7 deletions provision/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import (
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"

"github.com/ubclaunchpad/inertia/cfg"
"github.com/ubclaunchpad/inertia/cmd/core/utils/out"
"github.com/ubclaunchpad/inertia/common"
"github.com/ubclaunchpad/inertia/local"
)
Expand Down Expand Up @@ -146,9 +148,12 @@ func (p *EC2Provisioner) CreateInstance(opts EC2CreateInstanceOptions) (*cfg.Rem
// Set requested region
p.WithRegion(opts.Region)

// set highlighter
var highlight = out.NewColorer(out.CY)

// Generate authentication
var keyName = fmt.Sprintf("%s_%s_inertia_key_%d", opts.Name, p.user, time.Now().UnixNano())
fmt.Printf("Generating key pair %s...\n", keyName)
out.Fprintf(p.out, highlight.Sf(":key: Generating key pair '%s'...\n", keyName))
keyResp, err := p.client.CreateKeyPair(&ec2.CreateKeyPairInput{
KeyName: aws.String(keyName),
})
Expand All @@ -162,17 +167,17 @@ func (p *EC2Provisioner) CreateInstance(opts EC2CreateInstanceOptions) (*cfg.Rem
}

// Save key
keyPath := filepath.Join(homeDir, ".ssh", *keyResp.KeyName)
fmt.Printf("Saving key to %s...\n", keyPath)
var keyPath = filepath.Join(homeDir, ".ssh", *keyResp.KeyName)
out.Fprintf(p.out, highlight.Sf(":inbox_tray: Saving key to '%s'...\n", keyPath))
if err = local.SaveKey(*keyResp.KeyMaterial, keyPath); err != nil {
return nil, err
}

// Create security group for network configuration
var secGroup = fmt.Sprintf("%s-%d", opts.Name, time.Now().UnixNano())
out.Fprintf(p.out, highlight.Sf(":circus_tent: Creating security group '%s'...\n", secGroup))
group, err := p.client.CreateSecurityGroup(&ec2.CreateSecurityGroupInput{
GroupName: aws.String(
fmt.Sprintf("%s-%d", opts.Name, time.Now().UnixNano()),
),
GroupName: aws.String(secGroup),
Description: aws.String(
fmt.Sprintf("Rules for project %s on %s", opts.ProjectName, opts.Name),
),
Expand All @@ -182,11 +187,13 @@ func (p *EC2Provisioner) CreateInstance(opts EC2CreateInstanceOptions) (*cfg.Rem
}

// Set rules for ports
out.Fprintf(p.out, highlight.Sf(":electric_plug: Exposing ports '%s'...\n", secGroup))
if err = p.exposePorts(*group.GroupId, opts.DaemonPort, opts.Ports); err != nil {
return nil, err
}

// Start up instance
out.Fprintf(p.out, highlight.Sf(":boat: Requesting instance '%s'...\n", secGroup))
runResp, err := p.client.RunInstances(&ec2.RunInstancesInput{
ImageId: aws.String(opts.ImageID),
InstanceType: aws.String(opts.InstanceType),
Expand All @@ -205,15 +212,16 @@ func (p *EC2Provisioner) CreateInstance(opts EC2CreateInstanceOptions) (*cfg.Rem
if runResp.Instances == nil || len(runResp.Instances) == 0 {
return nil, errors.New("Unable to start instances: " + runResp.String())
}
out.Fprintf(p.out, highlight.Sf("A %s instance has been provisioned", opts.InstanceType))

// Loop until intance is running
fmt.Fprintln(p.out, "Checking status of requested instance...")
var instance ec2.Instance
for {
// Wait briefly between checks
time.Sleep(3 * time.Second)

// Request instance status
out.Fprintf(p.out, "Checking status of the requested instance...\n")
result, err := p.client.DescribeInstances(&ec2.DescribeInstancesInput{
InstanceIds: []*string{runResp.Instances[0].InstanceId},
})
Expand Down Expand Up @@ -259,6 +267,7 @@ func (p *EC2Provisioner) CreateInstance(opts EC2CreateInstanceOptions) (*cfg.Rem
}

// Set tags
out.Fprintf(p.out, "Setting tags on instance...\n")
if _, err = p.client.CreateTags(&ec2.CreateTagsInput{
Resources: []*string{instance.InstanceId},
Tags: []*ec2.Tag{
Expand Down Expand Up @@ -288,6 +297,7 @@ func (p *EC2Provisioner) CreateInstance(opts EC2CreateInstanceOptions) (*cfg.Rem
}

// Generate webhook secret
out.Fprintf(p.out, "Generating a webhook secret...\n")
webhookSecret, err := common.GenerateRandomString()
if err != nil {
fmt.Fprintln(p.out, err.Error())
Expand Down

0 comments on commit 78a1c4b

Please sign in to comment.