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

Commit

Permalink
installer,cli,dashboard: Add installer web app
Browse files Browse the repository at this point in the history
Makes `flynn install` run web app interface for installer and removes
all other options.

The install cert view is shared between the installer and dashboard.

Signed-off-by: Jesse Stuart <jesse@jessestuart.ca>
  • Loading branch information
jvatic committed Mar 10, 2015
1 parent 495a930 commit ce1fd92
Show file tree
Hide file tree
Showing 65 changed files with 22,032 additions and 323 deletions.
119 changes: 4 additions & 115 deletions cli/install.go
@@ -1,135 +1,24 @@
package main

import (
"errors"
"fmt"
"os"
"strconv"

"github.com/flynn/flynn/Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws"
"github.com/flynn/flynn/Godeps/_workspace/src/github.com/flynn/go-docopt"
"github.com/flynn/flynn/installer"
)

func init() {
register("install", runInstaller, fmt.Sprintf(`
usage: flynn install <target> [-n <instances>] [-t <instance-type>] [--aws-access-key-id=<key-id>] [--aws-secret-access-key=<secret>] [--aws-region=<region>] [--vpc-cidr=<cidr>] [--subnet-cidr=<cidr>]
usage: flynn install
Targets:
aws creates a flynn cluster on EC2
Options:
-n <instances>, --instances=<instances> Number of instances to launch [default: 1]
-t <instance-type>, --type=<instance-type> Type of instances to launch [default: %s]
--aws-access-key-id=<key-id> AWS access key ID. Defaults to $AWS_ACCESS_KEY_ID
--aws-secret-access-key=<secret> AWS access key secret. Defaults to $AWS_SECRET_ACCESS_KEY
--aws-region=<region> AWS region [default: us-east-1]
--vpc-cidr=<cidr> CIDR block to assign to the VPC. [default: 10.0.0.0/16]
--subnet-cidr=<cidr> CIDR block to assign to the subnet. [default: 10.0.0.0/21]
Starts server for installer web interface.
Examples:
$ flynn install aws --aws-access-key-id=asdf --aws-secret-access-key=fdsa
$ flynn install
`, installer.DefaultInstanceType))
}

func runInstaller(args *docopt.Args) error {
if args.String["<target>"] != "aws" {
return errors.New("Invalid install target")
}
var creds aws.CredentialsProvider
key := args.String["--aws-access-key-id"]
secret := args.String["--aws-secret-access-key"]
if key != "" && secret != "" {
creds = aws.Creds(key, secret, "")
} else {
var err error
creds, err = aws.EnvCreds()
if err != nil {
return err
}
}

instanceType := args.String["--type"]

region := args.String["--aws-region"]
if region == "" {
region = "us-east-1"
}

instances := 1
if args.String["--instances"] != "" {
var err error
instances, err = strconv.Atoi(args.String["--instances"])
if err != nil {
return err
}
}

vpcCidr := args.String["--vpc-cidr"]
if vpcCidr == "" {
vpcCidr = "10.0.0.0/21"
}

subnetCidr := args.String["--subnet-cidr"]
if subnetCidr == "" {
subnetCidr = "10.0.0.0/21"
}

stack := &installer.Stack{
NumInstances: instances,
InstanceType: instanceType,
Region: region,
VpcCidr: vpcCidr,
SubnetCidr: subnetCidr,
Creds: creds,
YesNoPrompt: promptYesNo,
PromptInput: promptInput,
}
if err := stack.RunAWS(); err != nil {
return err
}

exitCode := 0
outer:
for {
select {
case event := <-stack.EventChan:
fmt.Println(event.Description)
case err := <-stack.ErrChan:
fmt.Printf("Oops, something went wrong: %s\n", err.Error())
exitCode = 1
case <-stack.Done:
if exitCode != 0 {
os.Exit(exitCode)
}
break outer
}
}

if err := readConfig(); err != nil {
return err
}
if err := config.Add(stack.ClusterConfig(), true); err != nil {
return err
}
config.SetDefault(stack.StackName)
if err := config.SaveTo(configPath()); err != nil {
return err
}

msg, _ := stack.DashboardLoginMsg()
fmt.Printf("\n\nThe cluster has been successfully deployed to AWS and configured locally.\n\n%s\n\n", msg)

return nil
}

func promptInput(msg string) (result string) {
fmt.Print(msg)
fmt.Print(": ")
for {
var answer string
fmt.Scanln(&answer)
return answer
}
return installer.ServeHTTP()
}
1 change: 1 addition & 0 deletions dashboard/app/.gitignore
@@ -1,3 +1,4 @@
build
.sass-cache
dashboard.tar
lib/installer
5 changes: 5 additions & 0 deletions dashboard/app/Rakefile
@@ -1,8 +1,13 @@
require 'bundler/setup'

lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)

require './config'
require 'static-sprockets/tasks/assets'
require 'static-sprockets/tasks/layout'
require 'dashboard/installer_import'
require 'fileutils'

namespace :assets do
task :clean do
Expand Down
5 changes: 4 additions & 1 deletion dashboard/app/Tupfile
@@ -1,4 +1,7 @@
include_rules

: $(ROOT)/util/cedarish/<docker> |> ^ docker build dashboard-builder^ cat $(ROOT)/log/docker-cedarish.log > /dev/null && ./build.sh image | tee %o |> $(ROOT)/log/docker-dashboard-builder.log <docker>
: $(ROOT)/log/docker-dashboard-builder.log |> ./build.sh app |> dashboard.tar
: foreach $(ROOT)/installer/app/src/images/*.png |> !cp |> ./lib/installer/images/%g.png
: foreach $(ROOT)/installer/app/src/views/*.js.jsx |> !cp |> ./lib/installer/views/%g.js.jsx
: foreach $(ROOT)/installer/app/src/views/css/*.js |> !cp |> ./lib/installer/views/css/%g.js
: ./lib/installer/images/* ./lib/installer/views/* ./lib/installer/views/css/* $(ROOT)/log/docker-dashboard-builder.log |> ./build.sh app |> dashboard.tar
2 changes: 2 additions & 0 deletions dashboard/app/config.rb
Expand Up @@ -3,10 +3,12 @@
require 'marbles-js'
require 'flynn-dashboard-web-icons'
require 'yajl'
require 'dashboard/installer_import'

StaticSprockets.sprockets_config do |environment|
MarblesJS::Sprockets.setup(environment)
FlynnDashboardWebIcons::Sprockets.setup(environment)
environment.append_path(File.join(Dashboard::InstallerImport::BASE_PATH, 'images'))
end

StaticSprockets.configure(
Expand Down
25 changes: 25 additions & 0 deletions dashboard/app/lib/dashboard/installer_import.rb
@@ -0,0 +1,25 @@
module Dashboard
module InstallerImport
BASE_PATH = ENV['INSTALLER_SRC_DIR'] || File.expand_path('../../installer', __FILE__)

extend self

def javascript(path)
if path[0] != '/'
path = File.join(BASE_PATH, path)
end
unless File.exists?(path)
if ext = %w[ .js .js.jsx ].find { |i| File.exists?(path + i) }
path = path + ext
else
throw "Asset not found: #{path}"
end
end
data = File.read(path)

data.gsub!(/^(?:import|export) .*$/, '')

data
end
end
end
16 changes: 6 additions & 10 deletions dashboard/app/lib/javascripts/dashboard/routers/main.js
Expand Up @@ -52,16 +52,12 @@ Dashboard.routers.main = new (Marbles.Router.createClass({
Marbles.history.navigate("");
return;
}
var browserName = navigator.userAgent.match(/((?:Firefox|Chrome|Safari))\/\d+/);
browserName = browserName ? (browserName[1] || "").toLowerCase() : "unknown";
var osName = navigator.userAgent.match(/(?:OS X|Windows|Linux)/);
osName = osName ? osName[0].toLowerCase().replace(/\s+/g, '') : "unknown";
React.render(React.createElement(
Dashboard.Views.InstallCert, {
certURL: Dashboard.config.API_SERVER.replace("https", "http") + "/cert",
browserName: browserName,
osName: osName
}), Dashboard.el);
React.render(React.createElement("form", { onSubmit: function () { Marbles.history.navigate("/"); } },
React.createElement("section", { className: "panel" },
React.createElement(
Dashboard.Views.InstallCert, {
certURL: Dashboard.config.API_SERVER.replace("https", "http") + "/cert"
}))), Dashboard.el);
}

}))();
Expand Down

0 comments on commit ce1fd92

Please sign in to comment.