summaryrefslogtreecommitdiffstats
path: root/genome-bootstrap/lib/genome-bootstrap
diff options
context:
space:
mode:
authorChris Alfonso <calfonso@redhat.com>2008-07-07 17:20:43 -0400
committerChris Alfonso <calfonso@redhat.com>2008-07-08 10:43:59 -0400
commit40598cb7bfeb6b1042482fe91701770b179c1803 (patch)
tree57d9b019a845fbcf4a7fcb8ccbce836bfc45174c /genome-bootstrap/lib/genome-bootstrap
parent9b9d481f6684777e90bb144193251244d14926ae (diff)
downloadtools-40598cb7bfeb6b1042482fe91701770b179c1803.tar.gz
tools-40598cb7bfeb6b1042482fe91701770b179c1803.tar.xz
tools-40598cb7bfeb6b1042482fe91701770b179c1803.zip
Renaming everying everest to genome
Diffstat (limited to 'genome-bootstrap/lib/genome-bootstrap')
-rw-r--r--genome-bootstrap/lib/genome-bootstrap/core.rb188
-rw-r--r--genome-bootstrap/lib/genome-bootstrap/ddns.rb75
2 files changed, 263 insertions, 0 deletions
diff --git a/genome-bootstrap/lib/genome-bootstrap/core.rb b/genome-bootstrap/lib/genome-bootstrap/core.rb
new file mode 100644
index 0000000..4b9ac94
--- /dev/null
+++ b/genome-bootstrap/lib/genome-bootstrap/core.rb
@@ -0,0 +1,188 @@
+# Copyright (C) 2008 Red Hat, Inc
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# a long with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require 'erb'
+require 'yaml'
+require 'restr'
+require 'xmlrpc/client'
+require 'rubygems'
+
+module GenomeBootstrap
+ class GenomeRepo
+ attr_reader :machines, :machine_types_url, :cobbler_profiles, :fqdn, :repo
+
+ def initialize(repo)
+ @repo = repo
+ # Allow users to pass in just the machine-name or the fqdn
+ @fqdn = @repo.split(".").size > 1 ? @repo : "#{@repo}-repo.usersys.redhat.com"
+ @genomed = "http://#{@fqdn}/genome"
+ @machine_types_url = @genomed + "/machine_types.html"
+
+ @cobblerd = XMLRPC::Client.new2("http://#{@fqdn}:25152")
+
+ # TODO: figure out a way to pass these values in
+ @token = @cobblerd.call2("login", "cobbler", "password")[1]
+ @cobbler_profiles = @cobblerd.call2("get_profiles", @token)[1].map {|p| p["name"]}
+ end
+
+ def machines
+ @machines ||= fetch_data
+ end
+
+ def facts_for(type, machine_name)
+ # Don't want to pull in the genome lib. See below fore more detail.
+ facts = restr_get("#{@genomed}/machine_types/#{type}.xml", "fact")
+ return facts.map do |f|
+ def f.name
+ self["name"]
+ end
+
+ def f.desc
+ self["description"]
+ end
+
+ # Here's where we make use of the DSL's simple templating
+ f.instance_variable_set(:@repo, @repo)
+ f.instance_variable_set(:@machine_name, machine_name)
+ def f.default
+ # handle there case where there is no default
+ self["default"].gsub("%repo%", @repo).gsub("%machine_name%", @machine_name) rescue ""
+ end
+
+ f
+ end
+ end
+
+ def classes_for(type)
+ restr_get("#{@genomed}/machine_types/#{type}.xml", "class")
+ end
+
+ def fetch_data
+ # Build out some mock objects so we don't have to couple to the genome
+ # lib. That lib has lots of funky metaprogramming stuff in it and it
+ # might need to be changed in the future. The fewer tools relying on it
+ # the better.
+ machine_types = restr_get("#{@genomed}/machine_types.xml", "machine_type")
+
+ return machine_types.map do |m|
+ def m.name
+ self["name"]
+ end
+
+ def m.desc
+ self["description"]
+ end
+
+ m
+ end
+ end
+
+ def post_yaml(node_name, machine_type, yaml)
+ Restr.post("#{@genomed}/nodes", :node_name => node_name, :yaml => yaml)
+ end
+
+ def add_system_to_cobbler(name, params, email)
+ system_id = @cobblerd.call2("new_system", @token)[1]
+ @cobblerd.call2('modify_system', system_id, 'name', name, @token)
+ @cobblerd.call2('modify_system', system_id, 'profile', params["cobbler_profile"], @token)
+
+ # These values ultimately get used by genome-firstboot
+ ksmeta = "fqdn=#{name} " +
+ "genome_repo=#{@fqdn}"
+
+ ksmeta << " email=#{email}" if email
+
+ @cobblerd.call2('modify_system', system_id, 'ksmeta', ksmeta, @token)
+ @cobblerd.call2('save_system', system_id, @token)
+ end
+
+ def register_machine(machine_fqdn, config, email="")
+ machine_type = config["parameters"]["genome_machine_type"]
+ post_yaml(machine_fqdn, machine_type, YAML.dump(config))
+ add_system_to_cobbler(machine_fqdn, config["parameters"], email)
+ end
+
+ # Retrive information form the /var/log/cobbler/install.log
+ def get_installed_systems
+ systems = restr_get("#{@genomed}/systems.xml")
+ return systems["system"].map do |system|
+ def system.name
+ self["name"].to_s
+ end
+
+ def system.ip
+ self["ip"].to_s
+ end
+
+ def system.hostname
+ self["hostname"].to_s
+ end
+ system
+ end
+ end
+
+ def get_installed_system(system_name)
+ systems = get_installed_systems
+ systems.delete_if{|system|
+ system.name.to_s != system_name.to_s
+ }
+ end
+
+ def cobbler_dns?
+ return false
+ end
+
+ def register_dns_entry(ip, name)
+
+ end
+
+ # This is a workaround for a Restr "feature". If only one element it is
+ # returned as a Hash instead of an Array. The way we use Restr assumes that it
+ # will always return an Array.
+ def restr_get(url, xml_node=nil)
+ data = xml_node ? Restr.get(url)[xml_node] : Restr.get(url)
+
+ return case data
+ when Hash
+ Array.new << data
+ when Array
+ data
+ end
+ end
+ end
+
+ class CloudController
+ attr_reader :repo, :cloud
+
+ # Create a new CloudController with the given server name (prefix or fqdn)
+ # and repo (full GenomeRepo object)
+ def initialize(name, repo)
+ @repo = repo
+
+ # If @repo is not an GenomeRepo object, assume it's the
+ # fqdn of a repo
+ if not @repo.is_a? GenomeRepo then
+ @repo = GenomeRepo.new(@repo)
+ end
+
+ @cloud = "http://#{name}/cloud"
+ end
+
+ def create_machine(system_name, email)
+ return Restr.post("#{@cloud}/koan", :system_name => system_name, :repo => @repo.fqdn, :email => email)
+ end
+ end
+end
diff --git a/genome-bootstrap/lib/genome-bootstrap/ddns.rb b/genome-bootstrap/lib/genome-bootstrap/ddns.rb
new file mode 100644
index 0000000..e0e982a
--- /dev/null
+++ b/genome-bootstrap/lib/genome-bootstrap/ddns.rb
@@ -0,0 +1,75 @@
+# Copyright (C) 2008 Red Hat, Inc
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# a long with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require 'net/https'
+
+module RedHatDDNS
+ SERVER = 'kickstart.rdu.redhat.com'
+
+ class DDNS
+ def initialize(username, password, host)
+ @username = username
+ @password = password
+ @hostname = host
+ end
+
+ def ddns_hash
+ @ddns_hash ||= fetch_hash
+ end
+
+ def to_s
+ ddns_hash
+ end
+
+ def main_page
+ req = "wget -q -O- --no-check-certificate " +
+ "--http-user=#{@username} --http-password='#{@password}' " +
+ %["https://#{SERVER}/redhat-ddns/admin/"]
+
+ puts "Fetching DDNS hash..."
+ yield `#{req}`
+ end
+
+ def request_new_hash
+ req = "wget -q -O- --no-check-certificate " +
+ "--http-user=#{@username} --http-password='#{@password}' " +
+ %["https://#{SERVER}/redhat-ddns/admin/add.php?host=#{@hostname}&_submit=Submit+Request"]
+
+ puts "Requesting a new hash"
+ `#{req}`
+ end
+
+ def fetch_hash(options={:tries => 3})
+ options[:tries].times do
+ # In order to test the regex with mocha we can't rely on the
+ # return value from the main_page method. That's why I
+ # declare 'hash' here and store the results from inside the
+ # block
+ hash = nil
+ main_page do |html|
+ hash = /#{@hostname}<\/pre>.*?hash=(.*)\"/.match(html)[1] rescue nil
+ end
+ return hash if hash
+ puts "Hash not found for #{@hostname}"
+ request_new_hash
+ end
+
+ raise RuntimeError.new("Error fetching DDNS hash:\n" +
+ "This usually happens when a hostname is reserved under another " +
+ "user's account or you typed password incorrectly.")
+ end
+ end
+end