summaryrefslogtreecommitdiffstats
path: root/genome-bootstrap/bin/genome-bootstrap
blob: 54e590f2ac6b67713965fa1c89484a50d1bef9d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/env ruby
require 'ostruct'
require 'genome-bootstrap'
require 'main'
require 'net/http'
require 'uri'
require "highline/import"
#http://www.mail-archive.com/capistrano@googlegroups.com/msg01822.html
HighLine.track_eof = false

include GenomeBootstrap

Main {

  def handle_exception e
    puts e.message
  end unless $DEBUG

  def say_red(text)
    say("<%= color(\"#{text}\", :red) %>") 
  end

  def get_input
    @facts = Hash.new

    say_red("\nYour genome repo server is the system that serves as the")
    say_red("puppet master, git server, and cobbler server all in one.")
    @repo = ask("Enter your Genome repo machine name (leave off the '-repo'):  ")

    say_red("\nYour cloud master is the server that determines where the")
    say_red("machine you're trying to create will be provisioned.  Typically")
    say_red("cloud masters control several machines in a cloud.  However,")
    say_red("cloud masters can be configured to simply manage their own disk space.")
    @cloudmaster = ask("Enter your cloud master:  ")
    @email = ask("Enter your email address for cloud notifications:  ")

    say_red("\nYour cobbler system name consists of two parts")
    say_red("\t* a system prefix")
    say_red("\t* a machine type")
    say_red("The system prefix can be used to help group common systems")
    say_red("together using some canonical name.  For instance, this can be")
    say_red("helpful when configuring clustered JBoss servers") 
    @system_prefix = ask("Enter your system prefix:  ")

    # Once we know the repo we can fetch the supported machines
    @genome_repo = GenomeRepo.new(@repo)
    say_red("\nNow, you can select your machine type.")
    say_red("To see a description of these machine types visit: " +
        "#{@genome_repo.machine_types_url}")

    @machine_type = choose do |menu|
      menu.prompt = "Select your machine type:  "
      menu.choices(*@genome_repo.machines.map{|m| m.name})
    end

    # This might be useful is we stop using DDNS
    @facts["genome_machine_type"] = @machine_type

    say_red("\nYour cobbler profile determines the OS, the disk space, and")
    say_red("the amount of memory that should be allocated to the system")
    say_red("that you are provisioning.")
    @facts["cobbler_profile"] = choose do |menu|
      menu.prompt = "Select your cobbler profile (This determines the OS):  "
      menu.choices(*@genome_repo.cobbler_profiles)
    end

    say_red("\nNow you need to enter some parameters what will be used to configure this machine.")
    say_red("Most of the defaults will work out fine for development.")

    @genome_repo.facts_for(@machine_type, @machine_name).each do |f|
      say_red("Description: #{f.desc}") unless f.desc.empty?
      @facts[f.name] = ask("Enter value for #{f.name}: ") do |q|
        q.default = f.default
      end
    end

    if agree("\nEnter addition facts? (y/n)", true)
      begin
        name = ask("Enter fact name: ")
        value = ask("Enter fact value: ") 
        @facts[name] = value
      end while agree("Enter another? ", true)
    end
  end

  def _run(config_only=false)
    # Ask all the silly questions
    get_input
    
    classes = @genome_repo.classes_for(@machine_type)
    config = {"classes" => classes, "parameters" => @facts}

    @genome_repo.register_machine(@fqdn, config)
    unless config_only
      cloud_master = CloudController.new(@cloudmaster, @genome_repo)
      cloud_master.create_machine(@fqdn, @email)
      if @genome_repo.cobbler_dns?
        @genome_repo.register_dns_entry
      end
    end
  end

  def run
    _run
  end

  # Allow user to simply create the cobbler system
  # but not actually create the VM
  mode 'config-only' do
    def run
      _run(true)
    end
  end

  # Allow user to supply a yaml file with the machine
  # configuration instead of answering all the questions
  mode 'advanced' do
    option('fqdn', 'f'){
      description "Fully qualified domain name of machine to be provisioned"
      argument_required
    }

    option('system', 's'){
      description "Cobbler system name of the machine to be provisioned"
      argument_required
    }

    option('repo', '-r'){
      required
      description "Fully qualified domain name for the Genome repo machine to use for provisioning"
      argument_required
    }

    option('cloudmaster', 'c'){
      required
      description "Fully qualified domain name for the machine controlling the cloud"
      argument_required
    }
    
    option('email', 'e'){
      required
      description "Your email address to use to help identify the instance owner"
      argument_required
    }

    option('yaml', 'y'){
      description "YAML configuration for this machine"
      argument_required
      validate {|f| File.exist?(f)}
    }

    def run 
      unless params['fqdn'].given? || params['system'].given?
        say("You must provide either an 'fqdn' parameter or a 'system' parameter")
        exit(1)
      end

      # FQDN beats system parameter
      if params['fqdn'].given?
        name = params['fqdn'].value
      else
        name = params['system'].value
      end

      config = if params['yaml'].given? 
        YAML.load(File.read(params['yaml'].value))
      else
        YAML.load($stdin.read)
      end

      genome_repo = GenomeRepo.new(params['repo'].value)
      genome_repo.register_machine(name, config)
      cloud_master = CloudController.new(params['cloudmaster'].value, genome_repo)
      host = cloud_master.create_machine(name, params['email'].value)

      installed_system = genome_repo.get_installed_system(name)
      if not installed_system.empty?
        if genome_repo.cobbler_dns? and params['fqdn'].given?
          # register the new system with cobbler dns using the name,
          # the installed_system's IP, and the given fqdn
        else
          fqdn = installed_system["hostname"]
        end
        say("Your new system is being provisioned on #{host}.")
        say("The FQDN of new system is #{fqdn}.")
        say("The IP address of the new system is #{installed_system["ip"]}.")
      else
        say("Your new system is being provisioned on #{host}.")
        say("You can visit #{cloud_master.cloud} to see the status of the new system.")
      end
    end
  end
}