lobot 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. data/.gitignore +7 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +78 -0
  6. data/Rakefile +2 -0
  7. data/features/ci.feature +18 -0
  8. data/features/config/secrets.yml.example +6 -0
  9. data/features/step_definitions/ci_steps.rb +98 -0
  10. data/features/support/env.rb +3 -0
  11. data/lib/generators/lobot/USAGE +8 -0
  12. data/lib/generators/lobot/install_generator.rb +24 -0
  13. data/lib/generators/lobot/templates/Capfile +6 -0
  14. data/lib/generators/lobot/templates/bootstrap_server.sh +57 -0
  15. data/lib/generators/lobot/templates/capistrano-ci.rb +68 -0
  16. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/attributes/nginx.rb +2 -0
  17. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/libraries/ci_config.rb +2 -0
  18. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/recipes/default.rb +7 -0
  19. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/recipes/git_config.rb +11 -0
  20. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/recipes/id_rsa.rb +14 -0
  21. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/recipes/jenkins.rb +45 -0
  22. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/recipes/xvfb.rb +24 -0
  23. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_ci/templates/default/jenkins-job-config.xml.erb +62 -0
  24. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/libraries/marker.rb +42 -0
  25. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/daemontools.rb +15 -0
  26. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/imagemagick.rb +37 -0
  27. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/libxml_prereqs.rb +14 -0
  28. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/mysql_5_1.rb +90 -0
  29. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/mysql_5_5.rb +86 -0
  30. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/nginx.rb +65 -0
  31. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/postgres.rb +80 -0
  32. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/sqlite.rb +20 -0
  33. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/recipes/swap.rb +17 -0
  34. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/templates/default/nginx-conf.erb +42 -0
  35. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/templates/default/nginx-htaccess.erb +3 -0
  36. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/templates/default/nginx-mime-types.erb +75 -0
  37. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/templates/default/nginx-run-script.erb +2 -0
  38. data/lib/generators/lobot/templates/chef/cookbooks/pivotal_server/templates/default/postgres-run-script.erb +2 -0
  39. data/lib/generators/lobot/templates/ci.rake +111 -0
  40. data/lib/generators/lobot/templates/ci.yml +24 -0
  41. data/lib/generators/lobot/templates/deploy-ci.rb +5 -0
  42. data/lib/generators/lobot/templates/soloistrc +11 -0
  43. data/lib/lobot.rb +8 -0
  44. data/lib/lobot/version.rb +3 -0
  45. data/lobot.gemspec +27 -0
  46. data/spec/install_spec.rb +68 -0
  47. data/spec/spec_helper.rb +11 -0
  48. metadata +161 -0
@@ -0,0 +1,65 @@
1
+ src_dir = "/usr/local/src/nginx"
2
+ install_dir = "/usr/local/nginx"
3
+
4
+ user "nginx"
5
+
6
+ {
7
+ "pcre" => "6.6-6.el5_6.1",
8
+ "pcre-devel" => "6.6-6.el5_6.1"
9
+ }.each do |package_name, version_string|
10
+ ['x86_64'].each do |arch_string|
11
+ package package_name do
12
+ action :install
13
+ version "#{version_string}"
14
+ end
15
+ end
16
+ end
17
+
18
+ run_unless_marker_file_exists("nginx_1_0_1") do
19
+ execute "download nginx src" do
20
+ command "mkdir -p #{src_dir} && curl -Lsf http://nginx.org/download/nginx-1.0.1.tar.gz | tar xvz -C#{src_dir} --strip 1"
21
+ end
22
+
23
+ execute "configure nginx" do
24
+ command "cd #{src_dir} && ./configure"
25
+ end
26
+
27
+ execute "make nginx" do
28
+ command "cd #{src_dir} && make"
29
+ end
30
+
31
+ execute "install nginx" do
32
+ command "cd #{src_dir} && make install"
33
+ end
34
+ end
35
+
36
+ execute "nginx owns nginx dirs" do
37
+ command "chown -R nginx /usr/local/nginx"
38
+ end
39
+
40
+ directory "/etc/nginx"
41
+
42
+ template "/etc/nginx/nginx.conf" do
43
+ source "nginx-conf.erb"
44
+ mode 0744
45
+ end
46
+
47
+ template "/etc/nginx/mime.types" do
48
+ source "nginx-mime-types.erb"
49
+ mode 0744
50
+ end
51
+
52
+ template "/etc/nginx/htpasswd" do
53
+ source "nginx-htaccess.erb"
54
+ mode 0644
55
+ end
56
+
57
+ execute "create daemontools directory" do
58
+ command "mkdir -p /service/nginx"
59
+ end
60
+
61
+ template "/service/nginx/run" do
62
+ source "nginx-run-script.erb"
63
+ mode 0755
64
+ end
65
+
@@ -0,0 +1,80 @@
1
+ include_recipe "pivotal_server::daemontools"
2
+ include_recipe "pivotal_server::libxml_prereqs"
3
+
4
+ src_dir = "/usr/local/src/postgres"
5
+ install_dir = "/usr/local/pgsql"
6
+
7
+ # mysql_root_password = "password"
8
+ # mysql_user_name = "app_user"
9
+ # mysql_user_password = "password"
10
+
11
+ # {
12
+ # "cmake" => "2.6.4-5.el5.2",
13
+ # "bison" => "2.3-2.1",
14
+ # "ncurses-devel" => "5.5-24.20060715"
15
+ # }.each do |package_name, version_string|
16
+ # package package_name do
17
+ # action :install
18
+ # version version_string
19
+ # end
20
+ # end
21
+
22
+ user "postgres"
23
+
24
+ run_unless_marker_file_exists("postgres_9_0_4") do
25
+ execute "download postgres src" do
26
+ command "mkdir -p #{src_dir} && curl -Lsf http://ftp9.us.postgresql.org/pub/mirrors/postgresql/source/v9.0.4/postgresql-9.0.4.tar.bz2 | tar xvj -C#{src_dir} --strip 1"
27
+ end
28
+
29
+ execute "config" do
30
+ command "./configure --disable-debug --enable-thread-safety --with-gssapi --with-krb5 --with-openssl --with-libxml --with-libxslt --with-perl --bindir=/usr/local/bin"
31
+ cwd src_dir
32
+ end
33
+
34
+ execute "make" do
35
+ command "make"
36
+ cwd src_dir
37
+ end
38
+
39
+ execute "make install" do
40
+ command "make install"
41
+ cwd src_dir
42
+ end
43
+
44
+ directory "#{install_dir}/data/" do
45
+ owner "postgres"
46
+ end
47
+
48
+ execute "init db" do
49
+ command "initdb -E UTF8 #{install_dir}/data/"
50
+ user "postgres"
51
+ end
52
+ end
53
+
54
+
55
+ execute "create daemontools directory" do
56
+ command "mkdir -p /service/postgres"
57
+ end
58
+
59
+ template "/service/postgres/run" do
60
+ source "postgres-run-script.erb"
61
+ mode 0755
62
+ end
63
+
64
+ file "/etc/ld.so.conf.d/postgres-64.conf" do
65
+ content "/usr/local/pgsql/lib"
66
+ end
67
+
68
+ execute "add postgres to ldconf" do
69
+ command "/sbin/ldconfig"
70
+ end
71
+
72
+ ruby_block "wait for postgres to come up" do
73
+ block do
74
+ Timeout::timeout(60) do
75
+ until system("ls /tmp/.s.PGSQL.5432")
76
+ sleep 1
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,20 @@
1
+ src_dir = "/usr/local/src/sqlite"
2
+ install_dir = "/usr/local/sqlite"
3
+
4
+ run_unless_marker_file_exists("sqlite_0") do
5
+ execute "download sqlite src" do
6
+ command "mkdir -p #{src_dir} && curl -Lsf http://www.sqlite.org/sqlite-autoconf-3070602.tar.gz | tar xvz -C#{src_dir} --strip 1"
7
+ end
8
+
9
+ execute "configure sqlite" do
10
+ command "cd #{src_dir} && ./configure"
11
+ end
12
+
13
+ execute "make sqlite" do
14
+ command "cd #{src_dir} && make"
15
+ end
16
+
17
+ execute "install sqlite" do
18
+ command "cd #{src_dir} && make install"
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ swapfile_location = "/swapfile"
2
+ swap_in_megabytes = 512
3
+
4
+ execute "create swapfile" do
5
+ command "dd if=/dev/zero of=#{swapfile_location} bs=1024 count=#{swap_in_megabytes*1024}"
6
+ not_if { File.exists?(swapfile_location) }
7
+ end
8
+
9
+ execute "mkswap" do
10
+ command "mkswap /swapfile"
11
+ not_if "file #{swapfile_location} | grep -q 'swap file'"
12
+ end
13
+
14
+ execute "swapon" do
15
+ command "swapon #{swapfile_location}"
16
+ not_if "cat /proc/swaps | grep -q '/swapfile'"
17
+ end
@@ -0,0 +1,42 @@
1
+ user nginx;
2
+ worker_processes 1;
3
+ daemon off;
4
+
5
+ error_log logs/error.log info;
6
+
7
+ events {
8
+ worker_connections 200;
9
+ }
10
+
11
+ http {
12
+ auth_basic "CI";
13
+ auth_basic_user_file htpasswd;
14
+ include mime.types;
15
+ default_type application/octet-stream;
16
+ sendfile on;
17
+ keepalive_timeout 65;
18
+ tcp_nodelay on;
19
+
20
+ upstream app_server {
21
+ server 127.0.0.1:8080;
22
+ }
23
+
24
+ server {
25
+ root /usr/local/nginx/html/;
26
+
27
+ try_files $uri @app_server;
28
+
29
+ location @app_server {
30
+ proxy_set_header X-Real-IP $remote_addr;
31
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
32
+ proxy_set_header Host $http_host;
33
+ proxy_set_header X_FORWARDED_PROTO $scheme;
34
+ proxy_redirect off;
35
+ proxy_pass http://app_server;
36
+ }
37
+ error_page 500 502 503 504 /50x.html;
38
+ location = /50x.html {
39
+ root html;
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,3 @@
1
+ <% node["nginx_settings"]["basic_auth_users"].each do |user| %>
2
+ <%= "#{user["username"]}:#{user["password"].crypt("AA")}" %>
3
+ <% end %>
@@ -0,0 +1,75 @@
1
+
2
+ types {
3
+ text/html html htm shtml;
4
+ text/css css;
5
+ text/xml xml;
6
+ image/gif gif;
7
+ image/jpeg jpeg jpg;
8
+ application/x-javascript js;
9
+ application/atom+xml atom;
10
+ application/rss+xml rss;
11
+
12
+ text/mathml mml;
13
+ text/plain txt;
14
+ text/vnd.sun.j2me.app-descriptor jad;
15
+ text/vnd.wap.wml wml;
16
+ text/x-component htc;
17
+
18
+ image/png png;
19
+ image/tiff tif tiff;
20
+ image/vnd.wap.wbmp wbmp;
21
+ image/x-icon ico;
22
+ image/x-jng jng;
23
+ image/x-ms-bmp bmp;
24
+ image/svg+xml svg;
25
+
26
+ application/java-archive jar war ear;
27
+ application/mac-binhex40 hqx;
28
+ application/msword doc;
29
+ application/pdf pdf;
30
+ application/postscript ps eps ai;
31
+ application/rtf rtf;
32
+ application/vnd.ms-excel xls;
33
+ application/vnd.ms-powerpoint ppt;
34
+ application/vnd.wap.wmlc wmlc;
35
+ application/vnd.google-earth.kml+xml kml;
36
+ application/vnd.google-earth.kmz kmz;
37
+ application/x-7z-compressed 7z;
38
+ application/x-cocoa cco;
39
+ application/x-java-archive-diff jardiff;
40
+ application/x-java-jnlp-file jnlp;
41
+ application/x-makeself run;
42
+ application/x-perl pl pm;
43
+ application/x-pilot prc pdb;
44
+ application/x-rar-compressed rar;
45
+ application/x-redhat-package-manager rpm;
46
+ application/x-sea sea;
47
+ application/x-shockwave-flash swf;
48
+ application/x-stuffit sit;
49
+ application/x-tcl tcl tk;
50
+ application/x-x509-ca-cert der pem crt;
51
+ application/x-xpinstall xpi;
52
+ application/xhtml+xml xhtml;
53
+ application/zip zip;
54
+
55
+ application/octet-stream bin exe dll;
56
+ application/octet-stream deb;
57
+ application/octet-stream dmg;
58
+ application/octet-stream eot;
59
+ application/octet-stream iso img;
60
+ application/octet-stream msi msp msm;
61
+
62
+ audio/midi mid midi kar;
63
+ audio/mpeg mp3;
64
+ audio/ogg ogg;
65
+ audio/x-realaudio ra;
66
+
67
+ video/3gpp 3gpp 3gp;
68
+ video/mpeg mpeg mpg;
69
+ video/quicktime mov;
70
+ video/x-flv flv;
71
+ video/x-mng mng;
72
+ video/x-ms-asf asx asf;
73
+ video/x-ms-wmv wmv;
74
+ video/x-msvideo avi;
75
+ }
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ exec /usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ /command/setuidgid postgres postgres -D /usr/local/pgsql/data
@@ -0,0 +1,111 @@
1
+ namespace :ci do
2
+ desc "Spin up CI server on amazon"
3
+ task :server_start do
4
+ require 'fog'
5
+ require 'yaml'
6
+
7
+ aws_conf_location = File.expand_path('../../../config/ci.yml', __FILE__)
8
+ aws_conf = YAML.load_file(aws_conf_location)
9
+ aws_credentials = aws_conf['credentials']
10
+ ec2_server_access = aws_conf['ec2_server_access']
11
+ server_config = aws_conf['server']
12
+
13
+ security_group_name = server_config['security_group']
14
+
15
+ aws_connection = Fog::Compute.new(
16
+ :provider => aws_credentials['provider'],
17
+ :aws_access_key_id => aws_credentials['aws_access_key_id'],
18
+ :aws_secret_access_key => aws_credentials['aws_secret_access_key']
19
+ )
20
+
21
+ security_group = aws_connection.security_groups.get(security_group_name)
22
+
23
+ if security_group.nil?
24
+ puts "Could not find security group named '#{security_group_name}'. Creating..."
25
+ security_group = aws_connection.security_groups.new(:name => security_group_name, :description => 'ci servers group auto-created by lobot')
26
+ security_group.save
27
+ security_group.reload
28
+ p security_group
29
+ end
30
+
31
+ PORTS_TO_OPEN = [22, 443, 80]
32
+ PORTS_TO_OPEN.each do |port|
33
+ is_in_security_group = !!security_group.ip_permissions.detect{|group| (group['fromPort']..group['toPort']).include?(port) && group['ipRanges'].detect{|range| range["cidrIp"]== "0.0.0.0/0" } }
34
+
35
+ unless is_in_security_group
36
+ puts "Allowing port #{port} into '#{security_group_name}' security group"
37
+ security_group.authorize_port_range(port..port)
38
+ end
39
+ end
40
+
41
+ ec2_key_pair_name = ec2_server_access['key_pair_name'] || "ci"
42
+ public_key_local_path = "#{ec2_server_access['id_rsa_path']}.pub"
43
+
44
+ current_key_pair = aws_connection.key_pairs.get(ec2_key_pair_name)
45
+ if current_key_pair
46
+ puts "Using existing '#{ec2_key_pair_name}' keypair"
47
+ else
48
+ puts "Creating '#{ec2_key_pair_name}' keypair, uploading #{public_key_local_path} to aws"
49
+
50
+ aws_connection.key_pairs.new(
51
+ :name => ec2_key_pair_name,
52
+ :public_key => File.read(File.expand_path("#{public_key_local_path}"))
53
+ ).save
54
+ end
55
+
56
+ number_of_servers = aws_connection.servers.select{ |server| server.state == 'running' }.length
57
+ puts "you have #{number_of_servers} server(s) already running in this account" if number_of_servers > 0
58
+
59
+ puts "Launching server... (this costs money until you stop it)"
60
+ server = aws_connection.servers.create(
61
+ :image_id => 'ami-d4de25bd',
62
+ :flavor_id => server_config['flavor_id'] || 'm1.large',
63
+ :key_name => ec2_key_pair_name
64
+ )
65
+ server.wait_for { ready? }
66
+ sleep 15 # Server ready? seems to mean 'almost ready'. Sleep value is arbitrary at the moment
67
+
68
+ p server
69
+ puts "Server is ready"
70
+
71
+ p "Writing server public IP (#{server.dns_name}) to ci.yml"
72
+ aws_conf["server"].merge!("name" => server.dns_name, "instance_id" => server.id)
73
+
74
+ f = File.open(aws_conf_location, "w")
75
+ f.write(aws_conf.to_yaml)
76
+ f.close
77
+ end
78
+
79
+ desc "open the CI interface in a browser"
80
+ task :open do
81
+ aws_conf_location = File.expand_path('../../../config/ci.yml', __FILE__)
82
+ aws_conf = YAML.load_file(aws_conf_location)
83
+ server_config = aws_conf['server']
84
+ exec "open http://#{server_config['name']}"
85
+ end
86
+
87
+ desc "ssh to CI"
88
+ task :ssh do
89
+ aws_conf_location = File.expand_path('../../../config/ci.yml', __FILE__)
90
+ aws_conf = YAML.load_file(aws_conf_location)
91
+ server_config = aws_conf['server']
92
+ exec "ssh -i #{aws_conf['ec2_server_access']['id_rsa_path']} #{aws_conf['app_user']}@#{server_config['name']}"
93
+ end
94
+
95
+ desc "Get build status"
96
+ task :status do
97
+ require 'nokogiri'
98
+ ci_conf_location = File.expand_path('../../../config/ci.yml', __FILE__)
99
+ ci_conf = YAML.load_file(ci_conf_location)
100
+
101
+ hudson_rss_feed = `curl -s --user #{ci_conf['basic_auth'][0]['username']}:#{ci_conf['basic_auth'][0]['password']} --anyauth http://#{ci_conf['server']['name']}/rssAll`
102
+ latest_build = Nokogiri::XML.parse(hudson_rss_feed.downcase).css('feed entry:first').first
103
+ status = !!(latest_build.css("title").first.content =~ /success|stable|back to normal/)
104
+ if status
105
+ p "Great Success"
106
+ else
107
+ p "Someone needs to fix the build"
108
+ end
109
+ status ? exit(0) : exit(1)
110
+ end
111
+ end
@@ -0,0 +1,24 @@
1
+ ---
2
+ app_name: SHORT_APPLICATION_NAME
3
+ app_user: APPLICATION_USER
4
+ git_location: GIT CLONE URL
5
+ basic_auth:
6
+ - username: BASIC_AUTH_LOGIN_NAME
7
+ password: BASIC_AUTH_PASSWORD
8
+ credentials:
9
+ aws_access_key_id: AWS_ACCESS_KEY #https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key
10
+ aws_secret_access_key: AWS_SECRET
11
+ provider: AWS # leave this one
12
+ server:
13
+ flavor_id: m1.large
14
+ security_group: ci_servers
15
+ name: # run 'rake ci:server_start to populate'
16
+ instance_id: # run 'rake ci:server_start to populate'
17
+ build_command: ./cruise_build.sh
18
+ ec2_server_access:
19
+ key_pair_name: NAME_OF_YOUR_KEY_PAIR # like myapp_ci
20
+ id_rsa_path: ~/.ssh/id_rsa
21
+ id_rsa_for_github_access: |-
22
+ -----BEGIN RSA PRIVATE KEY-----
23
+ SSH KEY WITH ACCESS TO GITHUB GOES HERE
24
+ -----END RSA PRIVATE KEY-----