lobot 1.0.pre → 2.0.0pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +0 -1
  3. data/Guardfile +10 -0
  4. data/README.md +52 -72
  5. data/Rakefile +2 -6
  6. data/Vagrantfile +15 -0
  7. data/bin/lobot +7 -0
  8. data/chef/cookbooks/pivotal_ci/.gitignore +4 -0
  9. data/chef/cookbooks/pivotal_ci/Gemfile +3 -0
  10. data/chef/cookbooks/pivotal_ci/README.md +3 -0
  11. data/chef/cookbooks/pivotal_ci/attributes/git.rb +1 -1
  12. data/chef/cookbooks/pivotal_ci/attributes/jenkins.rb +2 -3
  13. data/chef/cookbooks/pivotal_ci/attributes/nginx.rb +1 -2
  14. data/chef/cookbooks/pivotal_ci/attributes/ssl.rb +1 -1
  15. data/chef/cookbooks/pivotal_ci/files/default/tests/minitest/default_test.rb +37 -0
  16. data/chef/cookbooks/pivotal_ci/metadata.rb +10 -0
  17. data/chef/cookbooks/pivotal_ci/recipes/id_rsa.rb +5 -2
  18. data/chef/cookbooks/pivotal_ci/recipes/jenkins.rb +1 -1
  19. data/chef/cookbooks/pivotal_ci/recipes/jenkins_config.rb +10 -17
  20. data/chef/cookbooks/pivotal_ci/recipes/nginx.rb +2 -0
  21. data/chef/cookbooks/pivotal_ci/templates/default/jenkins-job-config.xml.erb +11 -3
  22. data/chef/cookbooks/pivotal_ci/templates/default/nginx-htaccess.erb +3 -3
  23. data/chef/cookbooks/pivotal_ci/templates/default/org.jenkinsci.plugins.xvfb.XvfbBuildWrapper.xml.erb +11 -0
  24. data/chef/cookbooks/pivotal_ci/test/kitchen/Kitchenfile +4 -0
  25. data/chef/cookbooks/pivotal_ci/test/kitchen/cookbooks/pivotal_ci_test/attributes/default.rb +3 -0
  26. data/chef/cookbooks/pivotal_ci/test/kitchen/cookbooks/pivotal_ci_test/metadata.rb +10 -0
  27. data/chef/cookbooks/pivotal_ci/test/kitchen/cookbooks/pivotal_ci_test/recipes/default.rb +41 -0
  28. data/lib/generators/lobot/templates/soloistrc +2 -1
  29. data/lib/lobot.rb +1 -12
  30. data/lib/lobot/amazon.rb +91 -0
  31. data/lib/lobot/cli.rb +148 -0
  32. data/lib/lobot/config.rb +80 -0
  33. data/lib/lobot/jenkins.rb +17 -0
  34. data/lib/lobot/sobo.rb +35 -0
  35. data/lib/lobot/tasks/ci.rake +0 -178
  36. data/lib/lobot/version.rb +1 -1
  37. data/lobot.gemspec +19 -15
  38. data/script/bootstrap_server.sh +4 -1
  39. data/spec/lib/lobot/amazon_spec.rb +127 -0
  40. data/spec/lib/lobot/cli_spec.rb +212 -0
  41. data/spec/lib/lobot/config_spec.rb +95 -0
  42. data/spec/lib/lobot/jenkins_spec.rb +14 -0
  43. data/spec/spec_helper.rb +5 -10
  44. metadata +87 -31
  45. data/chef/cookbooks/pivotal_ci/libraries/ci_config.rb +0 -2
  46. data/spec/install_spec.rb +0 -80
data/.gitignore CHANGED
@@ -6,3 +6,6 @@ features/config/secrets.yml
6
6
  .idea
7
7
  spec/tmp
8
8
  spec/reports/
9
+ .vagrant
10
+ .kitchen
11
+ .env
data/Gemfile CHANGED
@@ -1,7 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem "builder", "~> 3.0.0" # Bundler goes into an infinite loop looking for this dep. Feel free to remove.
4
- gem "rvm-capistrano", :group => :development, :require => false
5
4
 
6
5
  # Specify your gem's dependencies in lobot.gemspec
7
6
  gemspec
@@ -0,0 +1,10 @@
1
+ guard 'rspec', cli: '--fail-fast --tag ~@slow:true' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+ guard 'bundler' do
8
+ watch('Gemfile')
9
+ watch('lobot.gemspec')
10
+ end
data/README.md CHANGED
@@ -9,108 +9,88 @@ Lando Calrissian relies on Lobot to keep Cloud City afloat, and now you can rely
9
9
 
10
10
  # What do I get?
11
11
 
12
- * Rake tasks for creating, starting, stopping, or destroying your CI server on EC2
13
- * Capistrano tasks for bootstrapping the Centos EC2 instance
14
- * Chef recipes for configuring the instance to run Jenkins and build Rails projects
12
+ * Commands for creating, starting, stopping, or destroying your CI server on EC2
13
+ * The full [Travis CI](http://travis-ci.org) environment on Ubuntu 12.04
14
+ * A Jenkins frontend for monitoring your builds
15
15
 
16
- After you add lobot to your Gemfile, all you'll need to do is run the following commands:
16
+ After you add `gem "lobot"` to your Gemfile, all you'll need to do is run the following commands:
17
17
 
18
- rails g lobot:install
19
- rails g lobot:config
20
- rake ci:create_server
21
- cap ci bootstrap
22
- cap ci chef
18
+ [lobot configure] - COMING SOON - See Setup for now.
19
+ lobot create
20
+ lobot bootstrap
21
+ lobot add_build BobTheBuild git@github.com:you/some_repo.git master script/ci_build.sh
22
+ lobot chef
23
23
 
24
24
  Read on for an explanation of what each one of these steps does.
25
25
 
26
26
  ## Install
27
27
 
28
- Add lobot to your Gemfile, in the test group:
28
+ Add lobot to your Gemfile, in the development group:
29
29
 
30
- gem "lobot", :group => :test
31
-
32
- ### To Install
33
-
34
- rails g lobot:install
30
+ gem "lobot", :group => :development
35
31
 
36
32
  ## Setup
37
- You can use a generator to interactively generate the config/ci.yml that includes some reasonable defaults and explanations.
38
-
39
- rails g lobot:config
40
33
 
41
- Alternatively, manually edit config/ci.yml
34
+ Create a config/lobot.yml file in your project:
42
35
 
43
36
  ---
44
- app_name: # a short name for your application
45
- git_location: # The location of your remote git repository which Jenkins will poll and pull from on changes.
46
- basic_auth:
47
- - username: # The username you will use to access the Jenkins web interface
48
- password: # The password you will use to access the Jenkins web interface
49
- credentials:
50
- aws_access_key_id: # The Access Key for your Amazon AWS account
51
- aws_secret_access_key: The Secret Access Key for your Amazon AWS account
52
- provider: AWS # leave this one alone
53
- server:
54
- name: run 'rake ci:create_server to populate'
55
- instance_id: run 'rake ci:create_server to populate'
56
- build_command: ./script/ci_build.sh
57
- ec2_server_access:
58
- key_pair_name: myapp_ci
59
- id_rsa_path: ~/.ssh/id_rsa
60
- github_private_ssh_key_path: ~/.ssh/id_rsa
37
+ server_ssh_key: ~/.ssh/id_rsa
38
+ github_ssh_key: ~/.ssh/id_rsa
39
+ aws_key: <your AWS Key>
40
+ aws_secret: <your AWS Secret>
41
+ node_attributes:
42
+ nginx:
43
+ basic_auth_user: ci
44
+ basic_auth_password: password
45
+
46
+ See [https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key](https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key) to generate AWS key/secret.
61
47
 
62
48
  ## Adjust Defaults (Optional)
63
- In your ci.yml, there are defaults set for values that have the recommened value. For example, the instance size used for EC2 is set to "c1.medium", which costs $118/month.
49
+
50
+ In your config/lobot.yml, there are defaults set for values that have the recommened value. For example, the instance size used for EC2 is set to "c1.medium".
51
+
64
52
  You can save on EC2 costs by using a tool like [projectmonitor](https://github.com/pivotal/projectmonitor) or ylastic to schedule when your instances are online.
65
53
 
66
54
  ## Commit and push your changes
67
55
 
68
56
  At this point you will need to create a commit of the files generated or modified and push those changes to your remote git repository so Jenkins can execute the build script when it pulls down your repo for the first time.
69
57
 
70
- ## Modify the soloistrc if necessary
58
+ If you must, you can do this on a branch. Then later you can change the branch in lobot.yml later and rechef.
59
+
60
+ ## Modify recipe list
61
+
62
+ You can modify the chef run list by setting the `recipes` key in config/lobot.yml. The default is:
63
+
64
+ ["pivotal_ci::jenkins", "pivotal_ci::limited_travis_ci_environment", "pivotal_ci"]`
71
65
 
72
- The soloistrc in root of your project is where you tell chef which recipes to run. Because we're using the cookbooks from Travis CI, you can look through [all the recipes Travis has available](https://github.com/travis-ci/travis-cookbooks/), and add any of them to your soloistrc.
66
+ Because we're using the cookbooks from Travis CI, you can look through [all the recipes Travis has available](https://github.com/travis-ci/travis-cookbooks/), and add any that you need.
73
67
 
74
68
  ## Starting your lobot instance
75
69
 
76
- 1. Launch an instance, allocate and associates an elastic IP and updates ci.yml:
70
+ 1. Launch an instance, allocate and associates an elastic IP and updates config/lobot.yml:
77
71
 
78
- rake ci:create_server
72
+ lobot create
79
73
 
80
- 2. Bootstrap the instance using the boostrap_server.sh script generated by Lobot. The script installs ruby prerequisites, creates the app_user account, and installs RVM for that user:
74
+ 2. Bootstrap the instance using the boostrap_server.sh script. The script installs ruby prerequisites and installs RVM:
81
75
 
82
- cap ci bootstrap
76
+ lobot bootstrap
83
77
 
84
- 3. Upload the contents of your chef/cookbooks/ directory, upload the soloistrc, and run chef:
78
+ 3. Upload the contents of Lobot's cookbooks, create a soloistrc, and run chef:
85
79
 
86
- cap ci chef
80
+ lobot chef
87
81
 
88
82
  Your lobot instance should now be up and running. You will be able to access your CI server at: http://&lt;your instance address&gt;/ with the username and password you chose during configuration.
89
- For more information about Jenkins CI, see http://jenkins-ci.org/
83
+ For more information about Jenkins CI, see [http://jenkins-ci.org](http://jenkins-ci.org).
90
84
 
91
85
  ## Troubleshooting
92
86
 
93
87
  Shell access for your instance
94
88
 
95
- rake ci:ssh
89
+ lobot ssh
96
90
 
97
- Terminating your instance and deallocating the elastic IP
91
+ Terminate all Lobot instances on your account and deallocate their elastic IPs
98
92
 
99
- rake ci:destroy_server
100
-
101
- Suspending your instance
102
-
103
- rake ci:stop_server
104
-
105
- Rstarting a server
106
-
107
- rake ci:start_server
108
-
109
- ## Add your new CI instance to [projectmonitor](http://github.com/pivotal/projectmonitor) and CCMenu
110
-
111
- Lobot can generate the config for you, just run:
112
-
113
- rake ci:info
93
+ lobot destroy_ec2
114
94
 
115
95
  ## Color
116
96
 
@@ -125,17 +105,17 @@ end
125
105
  ## Dependencies
126
106
 
127
107
  * fog
128
- * capistrano
129
- * capistrano-ext
130
- * rvm (the gem - it configures capistrano to use RVM on the server)
131
- * nokogiri
108
+ * ci_reporter
109
+ * thor
110
+ * hashie
111
+ * net-ssh
112
+
113
+ ## Testing
132
114
 
133
- # Tests
115
+ Lobot is tested using rspec, vagrant and test kitchen. You will need to set environment variables with your AWS credentials to run tests which rely on ec2:
134
116
 
135
- Lobot is tested using rspec, generator_spec and cucumber. Cucumber provides a full integration test which can generate a rails application, push it to github, start a server and bring up CI for the generated project.
136
- You'll need a git repository (which should not have any code you care about) and an AWS account to run the whole test suite. It costs about $0.50 and takes about half an hour.
137
- It will attempt to terminate the server however you should verify this so you do not get charged additional money.
138
- Use the secrets.yml.example to create a secrets.yml file with your account information.
117
+ export EC2_KEY=FOO
118
+ export EC2_SECRET=BAR
139
119
 
140
120
  # Contributing
141
121
 
data/Rakefile CHANGED
@@ -1,15 +1,11 @@
1
1
  require 'ci/reporter/rake/rspec'
2
- require 'ci/reporter/rake/cucumber'
3
2
  require 'rspec/core/rake_task'
4
- require 'cucumber/rake/task'
5
3
  require 'bundler'
4
+
6
5
  Bundler::GemHelper.install_tasks
7
6
 
8
- task :default => ['ci:setup:rspec', :spec, :features]
7
+ task :default => ['ci:setup:rspec', :spec]
9
8
 
10
9
  desc "Run all specs in spec directory (excluding plugin specs)"
11
10
  RSpec::Core::RakeTask.new(:spec)
12
11
 
13
- desc "Run all features in the features directory"
14
- Cucumber::Rake::Task.new(:features) do |t|
15
- end
@@ -0,0 +1,15 @@
1
+ Vagrant::Config.run do |config|
2
+ config.vm.box = "precise64"
3
+ config.vm.box_url = "http://files.vagrantup.com/#{config.vm.box}.box"
4
+ config.vm.network :hostonly, "192.168.33.10"
5
+
6
+ config.vm.provision :shell, :inline => "sudo mkdir /etc/skel/.ssh"
7
+
8
+ config.vm.provision :shell do |shell|
9
+ shell.inline = "echo $@ | sudo tee /etc/skel/.ssh/authorized_keys"
10
+ ssh_key = ENV['LOBOT_SSH_KEY'] || File.expand_path("~/.ssh/id_rsa.pub")
11
+ shell.args = File.read(ssh_key)
12
+ end
13
+
14
+ config.vm.provision :shell, :inline => "sudo useradd -m ubuntu -G sudo,admin -s /bin/bash"
15
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.expand_path('../../lib', __FILE__)
3
+
4
+ require "rubygems"
5
+ require "lobot/cli"
6
+
7
+ Lobot::CLI.start
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ .cache
3
+ .kitchen
4
+ bin
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gem "test-kitchen"
@@ -0,0 +1,3 @@
1
+ # About the Pivotal CI Cookbook
2
+
3
+ * It's what Lobot craves.
@@ -1,4 +1,4 @@
1
- node["git"] = {
1
+ default["git"] = {
2
2
  "email" => "jenkins-ci@example.com",
3
3
  "name" => "Jenkins CI Server"
4
4
  }
@@ -1,3 +1,2 @@
1
- node["jenkins"] = {
2
- "home" => "/var/lib/jenkins"
3
- }
1
+ default["jenkins"] = {}
2
+ default["jenkins"]["home"] = "/var/lib/jenkins"
@@ -1,2 +1 @@
1
- node["nginx_settings"] ||= {}
2
- node["nginx_settings"]["basic_auth_users"] = CI_CONFIG['basic_auth']
1
+ default["nginx"] ||= {}
@@ -1,4 +1,4 @@
1
- node.default["ssl_settings"]= {
1
+ default["ssl_settings"]= {
2
2
  "common_name" => "lobot",
3
3
  "cert_path" => "/etc/certificates",
4
4
  "ca_path" => "/etc/pki/demoCA"
@@ -0,0 +1,37 @@
1
+ describe_recipe "pivotal_ci::jenkins" do
2
+ include MiniTest::Chef::Assertions
3
+ include MiniTest::Chef::Context
4
+ include MiniTest::Chef::Resources
5
+
6
+ it "runs jenkins" do
7
+ service("jenkins").must_be_running
8
+ end
9
+
10
+ it "creates the jenkins user" do
11
+ user("jenkins").must_exist
12
+ end
13
+
14
+ it "configures the xvfb plugin" do
15
+ file("/var/lib/jenkins/org.jenkinsci.plugins.xvfb.XvfbBuildWrapper.xml").must_exist
16
+ end
17
+ end
18
+
19
+ describe_recipe "pivotal_ci::default" do
20
+ def wait_for(match, options="")
21
+ Timeout.timeout(10) do
22
+ sleep 1 until `curl #{options} -ks https://localhost/` =~ match
23
+ true
24
+ end
25
+ rescue Timeout::Error
26
+ false
27
+ end
28
+
29
+ it "requires basic auth" do
30
+ wait_for(/401 Authorization Required/).must_equal true
31
+ end
32
+
33
+ it "sets the right basic_auth credentials" do
34
+ credentials = "#{node['nginx']['basic_auth_user']}:#{node['nginx']['basic_auth_password']}"
35
+ wait_for(/jenkins/, "--user #{credentials}").must_equal true
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ name "pivotal_ci"
2
+ maintainer "Pivotal Labs"
3
+ maintainer_email "commoncode+lobot@pivotallabs.com"
4
+ license "MIT"
5
+ description "Sets up Lobot"
6
+ version "0.1.0"
7
+
8
+ recipe "pivotal_ci::default", "Install Lobot"
9
+
10
+ supports "ubuntu", "12.04"
@@ -8,12 +8,15 @@ directory "#{node["jenkins"]["home"]}/.ssh" do
8
8
  end
9
9
 
10
10
  execute "copy id_rsa" do
11
- files = "/home/#{username}/.ssh/id_rsa #{node["jenkins"]["home"]}/.ssh/id_rsa"
11
+ destination_path = "#{node["jenkins"]["home"]}/.ssh/id_rsa"
12
+ source_path = "/home/#{username}/.ssh/id_rsa"
13
+ files = "#{source_path} #{destination_path}"
12
14
  command "cp #{files}"
13
- not_if "diff -q #{files}"
15
+ only_if { (::File.exists?(source_path)) && !system("diff -q #{files}") }
14
16
  end
15
17
 
16
18
  file "#{node["jenkins"]["home"]}/.ssh/id_rsa" do
19
+ mode 0600
17
20
  owner "jenkins"
18
21
  end
19
22
 
@@ -8,7 +8,7 @@ end
8
8
 
9
9
  file "/etc/apt/sources.list.d/jenkins.list" do
10
10
  content "deb http://pkg.jenkins-ci.org/debian binary/"
11
- notifies :run, "execute[apt-get update]"
11
+ notifies :run, "execute[apt-get update]", :immediately
12
12
  end
13
13
 
14
14
  execute "apt-get update" do
@@ -15,38 +15,31 @@ execute "download lobot plugin" do
15
15
  jenkins_plugin.call(self, "lobot", "http://cheffiles.pivotallabs.com/lobot/lobot.hpi")
16
16
  end
17
17
 
18
- ['git', 'ansicolor'].each do |plugin|
18
+ ['git', 'ansicolor', 'xvfb'].each do |plugin|
19
19
  execute "download #{plugin} plugin" do
20
20
  jenkins_plugin.call(self, plugin, "http://mirrors.jenkins-ci.org/plugins/#{plugin}/latest/#{plugin}.hpi")
21
21
  end
22
22
  end
23
23
 
24
- directory "#{node["jenkins"]["home"]}/jobs/#{ENV['APP_NAME']}" do
25
- owner "jenkins"
26
- end
27
-
28
- template "#{node["jenkins"]["home"]}/jobs/#{ENV['APP_NAME']}/config.xml" do
29
- source "jenkins-job-config.xml.erb"
24
+ template "#{node["jenkins"]["home"]}/org.jenkinsci.plugins.xvfb.XvfbBuildWrapper.xml" do
25
+ source "org.jenkinsci.plugins.xvfb.XvfbBuildWrapper.xml.erb"
30
26
  owner "jenkins"
31
27
  notifies :restart, "service[jenkins]"
32
- variables(
33
- :git_location => CI_CONFIG['git_location'],
34
- :build_command => CI_CONFIG['build_command']
35
- )
36
28
  end
37
29
 
38
- (CI_CONFIG['additional_builds'] || []).each do |build|
39
- directory "#{node["jenkins"]["home"]}/jobs/#{build['build_name']}" do
30
+ node["jenkins"]["builds"].each do |build|
31
+ directory "#{node["jenkins"]["home"]}/jobs/#{build['name']}" do
40
32
  owner "jenkins"
41
33
  end
42
34
 
43
- template "#{node["jenkins"]["home"]}/jobs/#{build['build_name']}/config.xml" do
35
+ template "#{node["jenkins"]["home"]}/jobs/#{build['name']}/config.xml" do
44
36
  source "jenkins-job-config.xml.erb"
45
37
  owner "jenkins"
46
38
  notifies :restart, "service[jenkins]"
47
39
  variables(
48
- :git_location => build['git_location'],
49
- :build_command => build['build_script']
40
+ :branch => build['branch'],
41
+ :command => build['command'],
42
+ :repository => build['repository']
50
43
  )
51
44
  end
52
- end
45
+ end
@@ -1,3 +1,5 @@
1
+ include_recipe "pivotal_ci::ssl_certificate"
2
+
1
3
  package "nginx" do
2
4
  version "1.1.19-1"
3
5
  end
@@ -10,12 +10,12 @@
10
10
  <hudson.plugins.git.UserRemoteConfig>
11
11
  <name></name>
12
12
  <refspec></refspec>
13
- <url><%= @git_location %></url>
13
+ <url><%= @repository %></url>
14
14
  </hudson.plugins.git.UserRemoteConfig>
15
15
  </userRemoteConfigs>
16
16
  <branches>
17
17
  <hudson.plugins.git.BranchSpec>
18
- <name>master</name>
18
+ <name><%= @branch %></name>
19
19
  </hudson.plugins.git.BranchSpec>
20
20
  </branches>
21
21
  <disableSubmodules>false</disableSubmodules>
@@ -51,7 +51,7 @@
51
51
  <concurrentBuild>false</concurrentBuild>
52
52
  <builders>
53
53
  <hudson.tasks.Shell>
54
- <command><%= @build_command %></command>
54
+ <command><%= @command %></command>
55
55
  </hudson.tasks.Shell>
56
56
  </builders>
57
57
  <publishers>
@@ -65,5 +65,13 @@
65
65
  <hudson.plugins.ansicolor.AnsiColorBuildWrapper>
66
66
  <colorMapName>xterm</colorMapName>
67
67
  </hudson.plugins.ansicolor.AnsiColorBuildWrapper>
68
+ <org.jenkinsci.plugins.xvfb.XvfbBuildWrapper plugin="xvfb@1.0.4">
69
+ <installationName>system</installationName>
70
+ <screen>1024x768x24</screen>
71
+ <debug>false</debug>
72
+ <timeout>0</timeout>
73
+ <displayNameOffset>0</displayNameOffset>
74
+ <additionalOptions></additionalOptions>
75
+ </org.jenkinsci.plugins.xvfb.XvfbBuildWrapper>
68
76
  </buildWrappers>
69
77
  </project>