Permalink
Browse files

Can spin up and configure a vagrant ci box

  • Loading branch information...
1 parent 73b4239 commit d03402d4ee6c528f0ef80dc29d29a6027810e0ab Doc Ritezel & Matthew Kocher committed Oct 4, 2012
View
@@ -4,5 +4,7 @@ gem "builder", "~> 3.0.0" # Bundler goes into an infinite loop looking for this
gem "rvm-capistrano", :group => :development, :require => false
gem "terminal-notifier-guard", :group => :development
gem "rb-fsevent", :group => :development
+gem "vagrant", "~> 1.0", :group => :development
+
# Specify your gem's dependencies in lobot.gemspec
gemspec
View
@@ -0,0 +1,15 @@
+Vagrant::Config.run do |config|
+ config.vm.box = "precise64"
+ config.vm.box_url = "http://files.vagrantup.com/#{config.vm.box}.box"
+ config.vm.network :hostonly, "192.168.33.10"
+
+ config.vm.provision :shell, :inline => "sudo mkdir /etc/skel/.ssh"
+
+ config.vm.provision :shell do |shell|
+ shell.inline = "echo $@ | sudo tee /etc/skel/.ssh/authorized_keys"
+ ssh_key = ENV['LOBOT_SSH_KEY'] || File.expand_path("~/.ssh/id_rsa.pub")
+ shell.args = File.read(ssh_key)
+ end
+
+ config.vm.provision :shell, :inline => "sudo useradd -m ubuntu -G sudo,admin -s /bin/bash"
+end
View
@@ -1,5 +1,8 @@
require "thor"
require "lobot/config"
+require "lobot/port_checker"
+require "lobot/sobo"
+require "pp"
module Lobot
class CLI < Thor
@@ -13,13 +16,55 @@ def open
exec("open https://#{lobot_config.basic_auth_user}:#{lobot_config.basic_auth_password}@#{lobot_config.master}/")
end
+ desc "create_vagrant", "Create a new Lobot server using Vagrant"
+ def create_vagrant
+ spawn_env = {"LOBOT_SSH_KEY" => File.expand_path("#{lobot_config.server_ssh_key}.pub"),
+ "VAGRANT_HOME" => File.expand_path("~")}
+ spawn_options = {chdir: lobot_root_path}
+
+ pid = Process.spawn(spawn_env, "vagrant up", spawn_options)
+ Process.wait(pid)
+
+ vagrant_ip = "192.168.33.10"
+
+ puts "Writing ip address for vagrant: #{vagrant_ip}"
+ lobot_config.master = vagrant_ip
+ lobot_config.save
+ end
+
+ desc "config", "Dumps all configuration data for Lobot"
+ def config
+ pp lobot_config.to_hash
+ end
+
+ # desc "bootstrap", "Configures Lobot's master node"
+ # def bootstrap
+ # master_server.upload(File.expand_path("script/", lobot_root_path), "script/")
+ # master_server.run! "chmod +x script/bootstrap_server.sh && script/bootstrap_server.sh"
+ # end
+
+ # desc "chef", "Uploads chef recipes and runs them"
+ # def chef
+ # master_server.upload(File.join(lobot_root_path, "chef/"), "chef/")
+ # master_server.upload(File.expand_path("lib/generators/lobot/templates/soloistrc", lobot_root_path), "soloistrc")
+ # master_server.run! "rvm use 1.9.3; gem list | grep soloist || gem install --no-ri --no-rdoc soloist; soloist"
+ # end
+
no_tasks do
+ # def master_server
+ # Sobo::Server.new(lobot_config.master, lobot_config.server_ssh_key)
+ # end
+
def lobot_config
@lobot_config ||= Lobot::Config.from_file(lobot_config_path)
end
end
private
+ def lobot_root_path
+ File.expand_path('../../..', __FILE__)
+ end
+
def lobot_config_path
File.expand_path("config/lobot.yml", Dir.pwd)
end
View
@@ -1,22 +1,64 @@
require "hashie"
module Lobot
- class Config
- attr_accessor :ssh_port, :master, :server_ssh_key, :basic_auth_user, :basic_auth_password
+ class Config < Hashie::Mash
+ def ssh_port
+ super || 22
+ end
+
+ def master
+ super || "127.0.0.1"
+ end
+
+ def server_ssh_key
+ super || File.expand_path("~/.ssh/id_rsa")
+ end
+
+ def basic_auth_user
+ super || "ci"
+ end
+
+ def recipes
+ super || ["pivotal_ci::jenkins", "pivotal_ci::limited_travis_ci_environment", "pivotal_ci"]
+ end
+
+ def soloistrc
+ {
+ 'recipes' => recipes,
+ 'node_attributes' => {
+ 'basic_auth_user' => basic_auth_user
+ }.merge(node_attributes)
+ }
+ end
+
+ def save
+ return self unless path
+ File.open(path, "w+") { |file| file.write(YAML::dump(to_hash)) }
+ self
+ end
+
+ def to_hash
+ hash = super
+ hash.delete("path")
+ {
+ "ssh_port" => ssh_port,
+ "master" => master,
+ "server_ssh_key" => server_ssh_key,
+ "basic_auth_user" => basic_auth_user,
+ "basic_auth_password" => basic_auth_password,
+ "recipes" => recipes
+ }.merge(hash)
+ end
- def initialize(config_hash = {})
- config = Hashie::Mash.new(config_hash)
- @ssh_port = config.ssh_port || 22
- @master = config.master || "127.0.0.1"
- @server_ssh_key = config.server_ssh_key || File.expand_path("~/.ssh/lobot_id_rsa")
- @basic_auth_user = config.basic_auth_user || "ci"
- @basic_auth_password = config.basic_auth_password
+ def self.from_file(yaml_file)
+ config = read_config(yaml_file)
+ self.new(config.merge(path: yaml_file))
end
- def self.from_file(yaml)
+ def self.read_config(yaml_file)
config = nil
- File.open(yaml, "r") { |file| config = YAML::load(file) }
- self.new(config)
+ File.open(yaml_file, "r") { |file| config = YAML.load(file.read) }
+ config
end
end
end
View
@@ -0,0 +1,24 @@
+require 'timeout'
+require 'socket'
+
+module Lobot
+ module PortChecker
+ def self.is_listening?(host, port, timeout = 180)
+ socket = nil
+ Timeout.timeout(timeout) do
+ until socket
+ begin
+ Timeout.timeout(5) do
+ socket = TCPSocket.open(host, port)
+ end
+ rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, Timeout::Error, Errno::EHOSTUNREACH
+ end
+ end
+ end
+
+ true
+ rescue Timeout::Error
+ false
+ end
+ end
+end
View
@@ -0,0 +1,58 @@
+# require 'net/ssh/telnet'
+
+# module Lobot
+# module Sobo
+# class Server
+# PROMPT_REGEX = /[$%#>] (\z|\e)/n
+
+# attr_reader :ip, :key
+
+# def initialize(ip, key)
+# @ip = ip
+# @key = key
+# end
+
+# def ssh_session
+# @ssh_session ||= Net::SSH.start(ip, "ubuntu", :keys => [key])
+# end
+
+# def shell
+# @shell ||= Net::SSH::Telnet.new('Session' => ssh_session, 'Prompt' => PROMPT_REGEX)
+# end
+
+
+# def upload(from, to, opts = "--exclude .git")
+# system("rsync -avz --delete #{from} ubuntu@#{ip}:#{to} #{opts}")
+# end
+
+# def run(*command_fragments)
+# command = command_fragments.join(' ')
+# result = run_command(command)
+# raise "Command failed: #{command}" unless run_command('echo $?', true) == '0'
+# result
+# end
+
+# def run!(*command_fragments)
+# run_command(command_fragments.join(' '))
+# end
+
+# def run?(*command_fragments)
+# run_command(command_fragments.join(' '))
+# run_command("echo $?") == '0'
+# end
+
+# def run_silently(*command_fragments)
+# command = command_fragments.join(' ')
+# result = run_command(command, true)
+# raise "Command failed: <silenced>" unless run_command('echo $?', true) == '0'
+# result
+# end
+
+# def run_command(command, silent=false)
+# output = shell.cmd(command) {|data| print data.gsub(/(\r|\r\n|\n\r)+/, "\n") unless silent }
+# command_regex = /#{Regexp.escape(command)}/
+# output.split("\n").reject {|l| l.match(command_regex) || l.match(PROMPT_REGEX)}.join("\n")
+# end
+# end
+# end
+# end
View
@@ -170,24 +170,24 @@ namespace :ci do
aws_connection.associate_address(server_config['instance_id'], server_config['elastic_ip']) if server_config['elastic_ip']
end
- desc "open the CI interface in a browser"
- task :open do
- aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
- aws_conf = YAML.load_file(aws_conf_location)
- server_config = aws_conf['server']
- exec "open https://#{server_config['elastic_ip']}"
- end
-
- desc "ssh to CI"
- task :ssh do
- aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
- aws_conf = YAML.load_file(aws_conf_location)
- server_config = aws_conf['server']
- ssh_port = server_config['ssh_port'] || 22
- cmd = "ssh -i #{aws_conf['ec2_server_access']['id_rsa_path']} ubuntu@#{server_config['elastic_ip']} -p #{ssh_port}"
- puts cmd
- exec cmd
- end
+ # desc "open the CI interface in a browser"
+ # task :open do
+ # aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
+ # aws_conf = YAML.load_file(aws_conf_location)
+ # server_config = aws_conf['server']
+ # exec "open https://#{server_config['elastic_ip']}"
+ # end
+ #
+ # desc "ssh to CI"
+ # task :ssh do
+ # aws_conf_location = File.join(Dir.pwd, 'config', 'ci.yml')
+ # aws_conf = YAML.load_file(aws_conf_location)
+ # server_config = aws_conf['server']
+ # ssh_port = server_config['ssh_port'] || 22
+ # cmd = "ssh -i #{aws_conf['ec2_server_access']['id_rsa_path']} ubuntu@#{server_config['elastic_ip']} -p #{ssh_port}"
+ # puts cmd
+ # exec cmd
+ # end
desc "Get build status"
task :status do
@@ -236,31 +236,31 @@ namespace :ci do
end
end
- desc "Run a command with a virtual frame buffer"
- task :headlessly, :command do |task, args|
- # headless is your friend on linux - http://www.aentos.com/blog/easy-setup-your-cucumber-scenarios-using-headless-gem-run-selenium-your-ci-server
- begin
- Headless
- rescue NameError
- puts "Headless not available, did you add it to your Gemfile?"
- exit 1
- end
- unless args[:command]
- puts "Usage: rake ci:headlessly[command] <additional options>"
- exit 1
- end
- exit_code = 1
- Headless.ly(:display => 42) do |headless|
- begin
- command = args[:command].gsub(/^['"](.*)['"]$/, "\\1")
- system(command)
- exit_code = $?.exitstatus
- ensure
- headless.destroy
- end
- end
- exit exit_code
- end
+ # desc "Run a command with a virtual frame buffer"
+ # task :headlessly, :command do |task, args|
+ # # headless is your friend on linux - http://www.aentos.com/blog/easy-setup-your-cucumber-scenarios-using-headless-gem-run-selenium-your-ci-server
+ # begin
+ # Headless
+ # rescue NameError
+ # puts "Headless not available, did you add it to your Gemfile?"
+ # exit 1
+ # end
+ # unless args[:command]
+ # puts "Usage: rake ci:headlessly[command] <additional options>"
+ # exit 1
+ # end
+ # exit_code = 1
+ # Headless.ly(:display => 42) do |headless|
+ # begin
+ # command = args[:command].gsub(/^['"](.*)['"]$/, "\\1")
+ # system(command)
+ # exit_code = $?.exitstatus
+ # ensure
+ # headless.destroy
+ # end
+ # end
+ # exit exit_code
+ # end
#aliases
desc "maybe"
View
@@ -19,22 +19,23 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
- s.add_dependency('fog', '>=0.9.0')
- s.add_dependency('capistrano')
- s.add_dependency('capistrano-ext')
- s.add_dependency('rvm')
- s.add_dependency('rvm-capistrano')
- s.add_dependency('nokogiri', '>=1.4.4')
- s.add_dependency('ci_reporter', '>=1.7.0')
- s.add_dependency('headless')
- s.add_dependency('thor')
- s.add_dependency('hashie')
+ s.add_dependency 'fog', '>=0.9.0'
+ s.add_dependency 'capistrano'
+ s.add_dependency 'capistrano-ext'
+ s.add_dependency 'rvm'
+ s.add_dependency 'rvm-capistrano'
+ s.add_dependency 'nokogiri', '>=1.4.4'
+ s.add_dependency 'ci_reporter', '>=1.7.0'
+ s.add_dependency 'headless'
+ s.add_dependency 'thor'
+ s.add_dependency 'hashie'
+ s.add_dependency 'net-ssh-telnet'
- s.add_development_dependency('cucumber')
- s.add_development_dependency('rspec')
- s.add_development_dependency('generator_spec')
- s.add_development_dependency('rails')
- s.add_development_dependency('jasmine')
- s.add_development_dependency('guard-rspec')
- s.add_development_dependency('guard-bundler')
+ s.add_development_dependency 'cucumber'
+ s.add_development_dependency 'rspec'
+ s.add_development_dependency 'generator_spec'
+ s.add_development_dependency 'rails'
+ s.add_development_dependency 'jasmine'
+ s.add_development_dependency 'guard-rspec'
+ s.add_development_dependency 'guard-bundler'
end
Oops, something went wrong.

0 comments on commit d03402d

Please sign in to comment.