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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
$: << File.dirname(File.expand_path(__FILE__))
gem 'reststop', '~> 0.2'
require 'yaml'
require 'fileutils'
require 'rubygems'
require 'picnic'
require 'reststop'
require 'everest'
require 'restr'
require 'xmlrpc/client'
require 'sqlite3'
Camping.goes :Cloudmasterd
Cloudmasterd.picnic!
module Cloudmasterd::Helpers
class Cobblerd
def initialize(repo)
@repo = repo
@xmlrpc = XMLRPC::Client.new2("http://#{@repo}:25152")
@token = @xmlrpc.call2("login", "cobbler", "password")[1]
end
def _call(method, *args)
return @xmlrpc.call2(method, *args)[1]
end
def distros
_call("get_distros", @token)
end
def profiles
_call("get_profiles", @token)
end
def systems
_call("get_systems", @token)
end
def repos
_call("get_repos", @token)
end
def distro(name)
_call("get_distro", name, @token)
end
def distro_for_koan(name)
_call("get_distro_for_koan", name, @token)
end
def profile(name)
_call("get_profile", name, @token)
end
def profile_for_koan(name)
_call("get_profile_for_koan", name, @token)
end
def system(name)
_call("get_system", name, @token)
end
def system_for_koan(name)
_call("get_system_for_koan", name, @token)
end
def repo(name)
_call("get_repo", name, @token)
end
def repo_for_koan(name)
_call("get_repo_for_koan", name, @token)
end
end
end
module Cloudmasterd::Models
class Machine < Base; end
class CreateTheBasics < V 1.0
def self.up
create_table :cloudmasterd_machines do |t|
t.column :user_email, :string, :null => false
t.column :machine, :string, :limit => 255
t.column :destination, :string, :limit => 255
end
end
def self.down
drop_table :cloudmasterd_machines
end
end
end
module Cloudmasterd::Controllers
class Koan < REST 'koan'
# Retrieve the cobbler profile for the given profile name
def _get_cobbler_profile(system_name, repo)
cobblerd = Cloudmasterd::Helpers::Cobblerd.new(repo)
cobbler_system = cobblerd.system(system_name)
return cobblerd.profile(cobbler_system["profile"])
end
# Find the best host on which to create a VM that requires
# the given "disk_size" and "ram"
def _get_best_host(disk_size, ram)
return `func-find-resources -m #{ram}`.chomp()
end
# run the appropriate koan command to create the given "fqdn"
# on the given "host" and "vol_group"
def _koan(host, fqdn, repo)
# Run the koan process
func_cmd = "func \"#{host}\" call virt install #{repo} #{fqdn} True #{fqdn} /images"
`#{func_cmd}`
raise "Func installation failed for host #{host} against repo #{fqdn}" unless $?.success?
# Make the new host autostart
func_cmd = "func \"#{host}\" call command run \"ln -s /etc/xen/#{fqdn} /etc/xen/auto/\""
`#{func_cmd}`
raise "Symbolic link creation failed for host #{host} against repo #{fqdn}" unless $?.success?
end
# POST /koan
def create
machine_fqdn = input.machine_fqdn
repo = input.repo
email = input.email
cobbler_profile = _get_cobbler_profile(machine_fqdn, repo)
@host = _get_best_host(cobbler_profile["virt_file_size"], cobbler_profile["virt_ram"])
_koan(@host, machine_fqdn, repo)
Machine.create :user_email => email, :machine => machine_fqdn, :destination => @host
render :_koan
end
end
class Cloud < REST 'cloud'
def list
@machines = Machine.find :all
render :cloud
end
end
end
module Cloudmasterd::Views
def initialize(*args)
super(*args)
@x = Builder::XmlMarkup.new(:indent => 1)
end
module HTML
def layout
html do
head do
title 'Everest Cloud Master Controller'
#link :rel => 'stylesheet', :type => 'text/css',
#:href => self/'/styles.css', :media => 'screen'
end
body do
div.content do
self << yield
end
end
end
end
def cloud
@machines.each do |m|
div do
h1 m.user_email
p m.machine
p m.destination
end
end
end
def _koan
@host
end
end
default_format :HTML
module YAML
CONTENT_TYPE = 'text/plain'
def layout
yield
end
end
module XML
def layout
yield
end
end
end
def Cloudmasterd.create
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "/var/lib/cloudmaster.db"
)
Cloudmasterd::Models.create_schema :assume => (Cloudmasterd::Models::Machine.table_exists? ? 1.0 : 0.0)
end
Cloudmasterd.start_picnic
|