machines 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ == 0.5.3
2
+
3
+ * Implement `list` command to list available machines from machines.yml
4
+ * Display syntax when `build` called with no machine
5
+ * Support running multiple tasks - e.g. `machines build machine passenger passenger_nginx nginx`
6
+ * modify git_clone to pull if the repo already exists
7
+
8
+ == 0.5.2
9
+
10
+ * Bug fixes
11
+
12
+
13
+ == 0.5.1
14
+
15
+ * Added opensource flag to allow alternatives to be installed (e.g. Chrome/Chromium)
16
+ * Added config.yml option to autostart VBoxClient for WMs that don't use XDG autostart
17
+ * Only append lines in a file if they do not exist (allows repeat running of commands)
data/EXAMPLES.md CHANGED
@@ -1,3 +1,6 @@
1
+ Adding new packages
2
+ =======================================
3
+
1
4
  It's easy to add new packages if you need something new on your current install.
2
5
  I added the following to `packages/printer.rb`:
3
6
 
@@ -16,3 +19,23 @@ Then ran it locally:
16
19
 
17
20
  Now the drivers for my printer are installed.
18
21
 
22
+
23
+ Running individual tasks
24
+ =======================================
25
+
26
+ Here is an example of upgrading Ruby, passenger and Nginx. First we check what commands will be run with the `dryrun` command.
27
+
28
+ machines dryrun phil rbenv passenger passenger_nginx nginx webapps
29
+ cat log/output.log
30
+
31
+ 2% SUDO apt-get -q -y install git-core
32
+ 4% SUDO apt-get -q -y install curl
33
+ 5% RUN test -d ruby-build && (cd ruby-build && git pull) || git clone --quiet git://github.com...
34
+ 7% SUDO cd ~/ruby-build && ./install.sh
35
+ ...
36
+
37
+ We can see that git and curl are installed as part of the rbenv install (although they will be ignored as they're already installed). the latest ruby-build is then pulled as it's already on the machine and the installer run.
38
+
39
+ All looks good so we'll run the build:
40
+
41
+ machines build phil rbenv passenger passenger_nginx nginx webapps
data/TODO.md CHANGED
@@ -1,7 +1,8 @@
1
1
  TODO next
2
2
  ----------------------------------------
3
3
 
4
- Support missing environment (e.g. scm machine)
4
+ Handle unknown tasks and display a proper error message (at the moment we get an obscure undefined method on NilClass)
5
+ Support missing environment (e.g. source repo machine)
5
6
  `machines dryrun/build` with no machine name should list the machines available
6
7
  DRY up per user config by creating a "common" user config that all users pull default config from
7
8
  DRY up further by having default templates in the same way that packages default to built-in ones
@@ -9,6 +10,8 @@ DRY up further by having default templates in the same way that packages default
9
10
  Complement this by providing a command to view packages and templates
10
11
  Move dotfiles to a repo so they can be managed across projects
11
12
  Handle apt-get error 110 and retry
13
+ Move packages into a separate gem
14
+ Move template into a separate gem
12
15
 
13
16
 
14
17
  Cloud
@@ -34,7 +37,6 @@ EC2 - Look at assigning and freeing elastic IP addresses
34
37
  Package and Task Tasks
35
38
  ----------------------------------------
36
39
 
37
- Support running multiple tasks - e.g. `machines build passenger passenger_nginx nginx`
38
40
  Any methods other than `append` that cannot be repeatedly run?
39
41
  Display additional install notes for a particular package (at the end of installation) - e.g. printer setup requires Windows share to be setup
40
42
  CODE/DOC: Describe difference between package and task or merge packages with tasks if possible
@@ -3,11 +3,11 @@ module Machines
3
3
  # Loads Machinesfile, opens an SCP connection and runs all commands and file uploads
4
4
  def build options
5
5
  $conf.machine_name = options.shift
6
- $conf.task = options.shift
6
+ return say(Help.new.syntax) unless $conf.machine_name
7
7
  init
8
8
  load_machinesfile
9
9
 
10
- task $conf.task.to_sym if $conf.task
10
+ task options if options.any?
11
11
 
12
12
  ssh_options = {:paranoid => false}
13
13
  if $conf.machine.cloud
@@ -44,7 +44,7 @@ module Machines
44
44
  end
45
45
 
46
46
  # Execute a given command e.g. dryrun, build, generate, htpasswd, packages, override, tasks
47
- def execute(options)
47
+ def execute options
48
48
  help = Help.new
49
49
  action = options.shift
50
50
  if help.actions.include?(action)
@@ -90,6 +90,10 @@ module Machines
90
90
  Command.console ||= Machines::Logger.new STDOUT, :truncate => true
91
91
  end
92
92
 
93
+ def list notused
94
+ say Help.new.machine_list
95
+ end
96
+
93
97
  def load_machinesfile
94
98
  eval File.read('Machinesfile'), nil, "eval: Machinesfile"
95
99
  rescue LoadError => e
@@ -126,7 +130,10 @@ module Machines
126
130
  end
127
131
  end
128
132
 
129
- def tasks
133
+ def tasks options
134
+ $conf.machine_name = options.shift
135
+ return say(Help.new.syntax) unless $conf.machine_name
136
+
130
137
  $conf.log_only = true
131
138
  init
132
139
  load_machinesfile
data/lib/machines/core.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Machines
2
2
  module Core
3
3
  # If a block is given, store the task, log it and run it
4
- # If no block is given, sets commands to only those of the specified task so they can be run standalone
5
- # @param [Symbol] name Name of the task
4
+ # If no block is given, sets commands to only those of the specified tasks so they can be run standalone
5
+ # @param [Symbol, String, Array] name Name of the task or array of task names
6
6
  # @param [String] description Describe the task
7
7
  # @param [Hash] options
8
8
  # @option options [Symbol, Array] :if Dependent tasks that must already have been added for this task to be added
@@ -14,8 +14,11 @@ module Machines
14
14
  $conf.commands << LogCommand.new(name, description)
15
15
  yield
16
16
  else
17
+ tasks = [name].flatten
17
18
  $conf.commands = []
18
- $conf.tasks[name][:block].call
19
+ tasks.each do |name|
20
+ $conf.tasks[name.to_sym][:block].call
21
+ end
19
22
  end
20
23
  end
21
24
 
data/lib/machines/help.rb CHANGED
@@ -4,9 +4,9 @@ module Machines
4
4
  @actions = {
5
5
  'htpasswd' => 'Generates basic auth in webserver/conf/htpasswd',
6
6
  'new <DIR>' => 'Generates an example machines project in DIR',
7
- 'dryrun <machine>' => 'Logs commands but does not run them',
8
- 'tasks' => 'Lists the available tasks',
9
- 'build <machine> [task]' => 'Builds your chosen machine. Optionally, build just one task',
7
+ 'dryrun <machine> [tasks]' => 'Display commands that would be run. Optionally, specify tasks to run',
8
+ 'tasks <machine>' => 'Lists the available tasks for the specified machine',
9
+ 'build <machine> [tasks]' => 'Builds your chosen machine. Optionally, specify tasks to run',
10
10
  'list' => 'Lists the available machines',
11
11
  'packages' => 'Lists the available packages',
12
12
  'override <PACKAGE>' => 'Copies the default package into project/packages so it can be edited/overidden'
@@ -17,8 +17,17 @@ module Machines
17
17
  @actions.keys.map{|key| key.gsub(/ .*/, '')}
18
18
  end
19
19
 
20
+ def machine_list
21
+ $conf.machines = AppConf.new
22
+ $conf.load('machines.yml')
23
+ <<-LIST
24
+ Machines from machines.yml:
25
+ #{$conf.machines.keys.map{|machine| " #{machine}" }.join("\n")}
26
+ LIST
27
+ end
28
+
20
29
  def syntax
21
- <<HELP
30
+ <<-HELP
22
31
  machines v#{Machines::VERSION} - Ubuntu/Ruby configuration tool.
23
32
  machines COMMAND
24
33
  COMMAND can be:
@@ -73,7 +73,7 @@ module Machines
73
73
  Command.new("gem update #{options}", nil)
74
74
  end
75
75
 
76
- # Clone a project from a Git repository
76
+ # Clone (or update) a project from a Git repository
77
77
  # @param [String] url URL to clone
78
78
  # @param [Hash] options
79
79
  # @option options [Optional String] :to Folder to clone to
@@ -83,7 +83,8 @@ module Machines
83
83
  raise ArgumentError.new('git_clone Must include a url and folder') if url.nil? || url.empty?
84
84
  raise ArgumentError.new('specifying :tag also requires :to') if options[:tag] && options[:to].nil?
85
85
  branch = "--branch #{options[:branch]} " if options[:branch]
86
- command = "git clone --quiet #{branch}#{url}"
86
+ dir = options[:to] || url.gsub(/^.*\/|.git/, '')
87
+ command = "test -d #{dir} && (cd #{dir} && git pull) || git clone --quiet #{branch}#{url}"
87
88
  command << " #{options[:to]}" if options[:to]
88
89
  command = Command.new(command, check_dir(options[:to]))
89
90
  command = [command, Command.new("cd #{options[:to]} && git checkout #{options[:tag]}", "git name-rev --name-only HEAD | grep #{options[:tag]}")] if options[:tag]
@@ -1,4 +1,4 @@
1
1
  module Machines
2
- VERSION = '0.5.2'
2
+ VERSION = '0.5.3'
3
3
  end
4
4
 
@@ -2,7 +2,7 @@ task :abiword, 'Install a lightweight word processor' do
2
2
  sudo install ['abiword']
3
3
  end
4
4
 
5
- task :abiword_associations, 'Setup file associations for Abiword' do
5
+ task :abiword_assoc, 'Setup file associations for Abiword' do
6
6
  mimetypes = 'application/x-abiword;application/msword;application/rtf;'
7
7
  mimetypes.split(';').each do |mimetype|
8
8
  run append "#{mimetype}=abiword.desktop", :to => '.local/share/applications/mimeapps.list'
@@ -1,6 +1,6 @@
1
1
  username = $conf.machine.user
2
2
 
3
- task :dotfiles, "Upload files in users/#{username}/dotfiles, prepend a dot and substitute some bashrc vars" do
3
+ task :dotfiles, "Upload users/#{username}/dotfiles and set some env vars" do
4
4
  Dir["users/#{username}/dotfiles/*"].each do |source|
5
5
  run upload source, ".#{File.basename(source)}" if File.exists?(source)
6
6
  end
@@ -3,7 +3,7 @@ task :file_roller, 'Install file-roller archive manager' do
3
3
  end
4
4
 
5
5
  # Mimetypes can be discovered by looking in /usr/share/applications/*.desktop
6
- task :file_roller_associations, 'Setup file associations for file-roller' do
6
+ task :file_roller_assoc, 'Setup file associations for file-roller' do
7
7
  mimetypes = 'application/x-7z-compressed;application/x-7z-compressed-tar;application/x-ace;application/x-alz;application/x-ar;application/x-arj;application/x-bzip;application/x-bzip-compressed-tar;application/x-bzip1;application/x-bzip1-compressed-tar;application/x-cabinet;application/x-cbr;application/x-cbz;application/x-cd-image;application/x-compress;application/x-compressed-tar;application/x-cpio;application/x-deb;application/x-ear;application/x-ms-dos-executable;application/x-gtar;application/x-gzip;application/x-gzpostscript;application/x-java-archive;application/x-lha;application/x-lhz;application/x-lrzip;application/x-lrzip-compressed-tar;application/x-lzip;application/x-lzip-compressed-tar;application/x-lzma;application/x-lzma-compressed-tar;application/x-lzop;application/x-lzop-compressed-tar;application/x-rar;application/x-rar-compressed;application/x-rpm;application/x-rzip;application/x-tar;application/x-tarz;application/x-stuffit;application/x-war;application/x-xz;application/x-xz-compressed-tar;application/x-zip;application/x-zip-compressed;application/x-zoo;application/zip;'
8
8
  mimetypes.split(';').each do |mimetype|
9
9
  run append "#{mimetype}=file-roller.desktop", :to => '.local/share/applications/mimeapps.list'
@@ -2,7 +2,7 @@ task :gnumeric, 'Install gnumeric lightweight spreadsheet' do
2
2
  sudo install ['gnumeric']
3
3
  end
4
4
 
5
- task :gnumeric_associations, 'Setup file associations for Gnumeric' do
5
+ task :gnumeric_assoc, 'Setup file associations for Gnumeric' do
6
6
  mimetypes = 'application/x-gnumeric;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;text/csv;application/msexcel'
7
7
  mimetypes.split(';').each do |mimetype|
8
8
  run append "#{mimetype}=gnumeric.desktop", :to => '.local/share/applications/mimeapps.list'
@@ -1,8 +1,8 @@
1
1
  task :nginx, 'Download and configure Nginx' do
2
- sudo extract $conf.webserver.url
2
+ sudo extract "http://nginx.org/download/nginx-#{$conf.webserver.version}.tar.gz"
3
3
  modules = "#{$conf.webserver.modules} --add-module=#{$conf.passenger.nginx}"
4
4
  commands = [
5
- "cd #{$conf.webserver.src_path}",
5
+ "cd /usr/local/src/nginx-#{$conf.webserver.version}",
6
6
  "./configure #{modules}",
7
7
  "make",
8
8
  "make install"
@@ -7,7 +7,7 @@ task :logrotate_nginx, 'Logrotate nginx access and error logs and optionally gen
7
7
  else
8
8
  stats_prerotate = stats_postrotate = nil
9
9
  end
10
- settings = AppBuilder.new(
10
+ settings = Machines::AppSettings::AppBuilder.new(
11
11
  log_path: "/var/log/nginx/#{app.name}.#{type}.log",
12
12
  stats_prerotate: stats_prerotate,
13
13
  stats_postrotate: stats_postrotate
@@ -19,7 +19,7 @@ end
19
19
 
20
20
  task :logrotate_apps, 'Logrotate Rails app logs' do
21
21
  $conf.webapps.each do |app_name, app|
22
- settings = AppBuilder.new(log_path: File.join(app.path, 'shared', 'log', '*.log'))
22
+ settings = Machines::AppSettings::AppBuilder.new(log_path: File.join(app.path, 'shared', 'log', '*.log'))
23
23
  sudo create_from 'logrotate/app.erb', settings: settings, to: File.join('/etc', 'logrotate.d', "#{app.name}_app")
24
24
  end
25
25
  end
@@ -1,4 +1,4 @@
1
- task :rbenv, "Install ruby-build, rbenv, ruby #{$conf.ruby.version} and Bundler" do
1
+ task :rbenv, "Install ruby-build, rbenv, ruby #{$conf.ruby.version}-#{$conf.ruby.build} and Bundler" do
2
2
  sudo install ['git-core', 'curl']
3
3
  run git_clone 'git://github.com/sstephenson/ruby-build.git'
4
4
  sudo 'cd ~/ruby-build && ./install.sh', check_file('/usr/local/bin/ruby-build')
@@ -16,9 +16,14 @@ task :rbenv, "Install ruby-build, rbenv, ruby #{$conf.ruby.version} and Bundler"
16
16
  run append path, :to => '~/.profile'
17
17
  rbenv = '$HOME/.rbenv/bin/rbenv'
18
18
 
19
- run "#{rbenv} install #{$conf.ruby.full_version}", check_command("#{rbenv} versions", $conf.ruby.version)
19
+ full_version = "#{$conf.ruby.version}-#{$conf.ruby.build}"
20
+
21
+ $conf.ruby.gems_path = ".rbenv/versions/#{full_version}/lib/ruby/gems/1.9.1/gems"
22
+ $conf.ruby.executable = ".rbenv/versions/#{full_version}/bin/ruby"
23
+
24
+ run "#{rbenv} install #{full_version}", check_command("#{rbenv} versions", $conf.ruby.version)
20
25
  run "#{rbenv} rehash", check_command("#{path} which gem", '.rbenv/shims/gem')
21
- run "#{rbenv} global #{$conf.ruby.full_version}", check_command("#{rbenv} exec ruby -v", $conf.ruby.version)
26
+ run "#{rbenv} global #{full_version}", check_command("#{rbenv} exec ruby -v", $conf.ruby.version)
22
27
 
23
28
  run write "gem: --no-rdoc --no-ri", :to => '.gemrc', :name => '.gemrc'
24
29
  run "#{rbenv} exec gem install bundler", check_command("#{rbenv} exec gem list", 'bundler')
data/lib/packages/rvm.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  task :rvm, 'Install RVM' do
2
+ full_version = "#{$conf.ruby.version}-#{$conf.ruby.build}"
3
+ $conf.ruby.gems_path = ".rvm/gems/#{full_version}/@global/gems"
4
+ $conf.ruby.executable = ".rvm/wrappers/#{full_version}@global/ruby"
5
+
2
6
  sudo install ['git-core']
3
7
  installer = "bash -s #{$conf.rvm.version} < <(wget -q https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )"
4
8
  run installer, check_file('~/.rvm/bin/rvm')
@@ -11,7 +15,7 @@ task :rvm_prompt_off, 'turn off trust prompting for new .rvmrc files' do
11
15
  run append 'export rvm_trust_rvmrcs_flag=1', :to => '.rvmrc'
12
16
  end
13
17
 
14
- task :ruby, "Install Ruby, make #{$conf.ruby.version}@global the default and install Bundler" do
18
+ task :ruby, "Install Ruby, make #{$conf.ruby.version}-#{$conf.ruby.build}@global the default and install Bundler" do
15
19
  run "rvm install #{$conf.ruby.version}", "rvm #{$conf.ruby.version} #{echo_result}"
16
20
  run "rvm #{$conf.ruby.version}@global --default", "ruby -v | grep #{$conf.ruby.version} #{echo_result}"
17
21
  run write "gem: --no-rdoc --no-ri", :to => '.gemrc', :name => '.gemrc'
@@ -1,4 +1,4 @@
1
- task :shutdown_without_password, 'Ensure we can shutdown/reboot without needing a password for sudo' do
1
+ task :shutdown_no_password, 'Ensure we can shutdown/reboot without needing a password for sudo' do
2
2
  sudo append 'ALL ALL=NOPASSWD:/sbin/shutdown', :to => '/etc/sudoers.d/shutdown'
3
3
  sudo append 'ALL ALL=NOPASSWD:/sbin/reboot', :to => '/etc/sudoers.d/shutdown'
4
4
  sudo chmod 440, '/etc/sudoers.d/shutdown'
@@ -1,4 +1,4 @@
1
- task :unison, 'Install unison two way file sync and set it to run hourly. Config in users/user/.unison/default.prf' do
1
+ task :unison, "Install and configure Unison (users/#{$conf.machine.user}/.unison/default.prf)" do
2
2
  sudo install 'unison'
3
3
  run "echo '30 18 * * * /usr/bin/unison' | crontab", check_command('crontab -l', 'unison')
4
4
  end
@@ -1,4 +1,4 @@
1
- task :webapps, 'Sets up Web apps in config/webapps.yml using app_server.conf.erb. Copies SSL certs.' do
1
+ task :webapps, 'Sets up Web apps in config/webapps.yml using app_server.conf.erb' do
2
2
  sudo mkdir File.join($conf.webserver.path, $conf.webserver.servers_dir) if $conf.webserver.servers_dir
3
3
  $conf.webapps.each do |app_name, app|
4
4
  if $conf.environment == 'development'
@@ -54,25 +54,20 @@ monit:
54
54
  # Latest version including preferred nginx version:
55
55
  # https://github.com/FooBarWidget/passenger/blob/master/NEWS
56
56
  passenger:
57
- version: 3.0.11
58
- # Set in passenger.rb package
59
- # root: Points to passenger path in rubygems
60
- # ruby: Points to the ruby executable in rbenv, rvm, compiled or installed by your package manager
57
+ version: 3.0.17
58
+ # Set in passenger.rb package
59
+ # root: Points to passenger path in rubygems
60
+ # ruby: Points to the ruby executable in rbenv, rvm, compiled or installed by your package manager
61
61
 
62
62
  # Uncomment to use RVM
63
63
  # Ruby will be installed using RVM
64
64
  # Passenger will be installed using rvmsudo
65
65
  #rvm:
66
- # url: https://rvm.beginrescueend.com/install/rvm
67
66
  # version: 1.9.2
68
67
 
69
68
  ruby:
70
- version: 1.9.2
71
- full_version: 1.9.2-p290
72
- # gems_path: '.rvm/gems/1.9.2-p290/@global/gems'
73
- # executable: .rvm/wrappers/1.9.2-p290@global/ruby
74
- gems_path: .rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems
75
- executable: .rbenv/versions/1.9.2-p290/bin/ruby
69
+ version: 1.9.3
70
+ build: p194
76
71
 
77
72
  set_rails_env_for:
78
73
  - qa
@@ -90,7 +85,7 @@ use_opensource: true
90
85
  webserver:
91
86
  name: nginx
92
87
  modules: --with-http_ssl_module
93
- version: 1.0.11
88
+ version: 1.2.3
94
89
  url: http://nginx.org/download/nginx-1.0.11.tar.gz
95
90
  src_path: /usr/local/src/nginx-1.0.11
96
91
  path: /usr/local/nginx
@@ -7,7 +7,7 @@ describe Machines::Commandline do
7
7
 
8
8
  before(:each) do
9
9
  $conf.log_only = false
10
- File.open('config.yml', 'w') { |f| f.puts "timezone: GB" }
10
+ File.open('config.yml', 'w') {|f| f.puts "timezone: GB" }
11
11
  FileUtils.mkdir_p 'log'
12
12
  end
13
13
 
@@ -24,23 +24,29 @@ describe Machines::Commandline do
24
24
  Net::SSH.stubs(:start).returns @ssh_stub
25
25
  end
26
26
 
27
+ it 'displays syntax when no machine name specified' do
28
+ lambda { build [] }.must_output Machines::Help.new.syntax
29
+ end
30
+
27
31
  it 'sets machine_name' do
28
32
  build ['machine']
29
33
  $conf.machine_name.must_equal 'machine'
30
34
  end
31
35
 
32
36
  it 'starts an SCP session using password authentication' do
33
- Net::SSH.expects(:start).with('target', 'username', :paranoid => false, :password => 'userpass').returns @ssh_stub
34
- build []
37
+ options = {paranoid: false, password: 'userpass'}
38
+ Net::SSH.expects(:start).with('target', 'username', options).returns @ssh_stub
39
+ build ['machine']
35
40
  end
36
41
 
37
42
  it 'starts an SCP session using key based authentication' do
38
43
  $conf.machine.cloud = AppConf.new
39
44
  $conf.machine.cloud.private_key_path = 'path/to/private_key'
40
45
  $conf.machine.cloud.username = 'ubuntu'
41
- Net::SSH.expects(:start).with('target', 'ubuntu', :paranoid => false, :keys => ['path/to/private_key']).returns @ssh_stub
46
+ options = {paranoid: false, keys: ['path/to/private_key']}
47
+ Net::SSH.expects(:start).with('target', 'ubuntu', options).returns @ssh_stub
42
48
 
43
- build []
49
+ build ['machine']
44
50
  end
45
51
 
46
52
  it 'runs each command' do
@@ -49,7 +55,7 @@ describe Machines::Commandline do
49
55
 
50
56
  mock_command.expects(:run)
51
57
 
52
- build []
58
+ build ['machine']
53
59
  end
54
60
 
55
61
  it 'flushes log file after running command' do
@@ -58,17 +64,21 @@ describe Machines::Commandline do
58
64
  $conf.commands = [command_stub]
59
65
 
60
66
  Machines::Command.file.expects(:flush)
61
- build []
67
+ build ['machine']
62
68
  end
63
69
 
64
- it 'replaces commands with the single task when supplied' do
70
+ it 'only run specified tasks' do
65
71
  command_will_run = Machines::Command.new '', ''
72
+ command_also_run = Machines::Command.new '', ''
66
73
  command_wont_run = Machines::Command.new '', ''
67
- $conf.tasks = { :task => {:block => Proc.new { run command_will_run }} }
74
+ $conf.tasks = {
75
+ :task1 => {:block => Proc.new { run command_will_run }},
76
+ :task2 => {:block => Proc.new { run command_also_run }}
77
+ }
68
78
 
69
- build ['machine', 'task']
79
+ build ['machine', 'task1', 'task2']
70
80
 
71
- $conf.commands.must_equal [command_will_run]
81
+ $conf.commands.must_equal [command_will_run, command_also_run]
72
82
  end
73
83
 
74
84
  it 'logs instead of SSHing and running commands' do
@@ -76,7 +86,7 @@ describe Machines::Commandline do
76
86
  $conf.commands = [mock('Machines::Command')]
77
87
  $conf.commands.first.expects(:run)
78
88
  $conf.log_only = true
79
- build []
89
+ build ['machine']
80
90
  end
81
91
 
82
92
  describe 'interrupts' do
@@ -91,14 +101,15 @@ describe Machines::Commandline do
91
101
  it 'handles CTRL+C and calls handler' do
92
102
  expects(:prepare_to_exit)
93
103
  Kernel.expects(:trap).with('INT').yields
94
- build []
104
+ build ['machine']
95
105
  end
96
106
 
97
107
 
98
108
  it 'sets exit flag and displays message' do
99
109
  prepare_to_exit
100
110
  $exit_requested.must_equal true
101
- $console.next.must_equal colored("\nEXITING after current command completes...\n", :warning)
111
+ message = "\nEXITING after current command completes...\n"
112
+ $console.next.must_equal colored(message, :warning)
102
113
  end
103
114
 
104
115
  it 'second request to exit exits immediately' do
@@ -111,7 +122,7 @@ describe Machines::Commandline do
111
122
  $exit_requested = true
112
123
  expects(:exit)
113
124
 
114
- build []
125
+ build ['machine']
115
126
  end
116
127
  end
117
128
  end
@@ -123,6 +134,12 @@ describe Machines::Commandline do
123
134
  dryrun options
124
135
  $conf.log_only.must_equal true
125
136
  end
137
+
138
+ it 'passes tasks to build' do
139
+ options = ['machine', 'task']
140
+ expects(:build).with options
141
+ dryrun options
142
+ end
126
143
  end
127
144
 
128
145
  describe 'execute' do
@@ -210,6 +227,13 @@ describe Machines::Commandline do
210
227
  end
211
228
  end
212
229
 
230
+ describe 'list' do
231
+ it 'lists machines' do
232
+ File.open('machines.yml', 'w') {|f| f.puts({'machines' => {'machine_1' => {}, 'machine_2' => {}}}.to_yaml) }
233
+ lambda { list nil }.must_output "Machines from machines.yml:\n machine_1\n machine_2\n"
234
+ end
235
+ end
236
+
213
237
  describe 'load_machinesfile' do
214
238
  it 'raises LoadError with custom message when no Machinesfile' do
215
239
  File.expects(:read).with("Machinesfile").raises LoadError.new('Machinesfile not found')
@@ -288,11 +312,12 @@ Project packages
288
312
  :task2 => {:description => 'description 2'},
289
313
  :task3 => {:description => 'description 3'}
290
314
  }
291
- lambda { tasks }.must_output 'Tasks
315
+ lambda { tasks ['machine'] }.must_output 'Tasks
292
316
  task1 description 1
293
317
  task2 description 2
294
318
  task3 description 3
295
319
  '
320
+ $conf.machine_name.must_equal 'machine'
296
321
  end
297
322
  end
298
323
  end
@@ -37,12 +37,21 @@ describe Machines::Core do
37
37
  $conf.tasks.must_equal :name => {:description => 'description', :block => block}
38
38
  end
39
39
 
40
- it 'sets commands to only run those from the specified task' do
41
- block_ran = false
42
- block = Proc.new { block_ran = true }
43
- $conf.tasks[:name] = {:block => block}
44
- task :name, nil
45
- block_ran.must_equal true
40
+ it 'sets commands to only run those from the specified tasks' do
41
+ block_run_count = 0
42
+ block = Proc.new { block_run_count += 1 }
43
+ $conf.tasks[:task1] = {:block => block}
44
+ $conf.tasks[:task2] = {:block => block}
45
+ task [:task1, 'task2']
46
+ block_run_count.must_equal 2
47
+ end
48
+
49
+ it 'sets commands to only run those of a single task' do
50
+ block_run = false
51
+ block = Proc.new { block_run = true }
52
+ $conf.tasks[:task] = {:block => block}
53
+ task :task
54
+ block_run.must_equal true
46
55
  end
47
56
 
48
57
  describe 'when dependent task' do
@@ -7,6 +7,13 @@ describe Machines::Help do
7
7
  it { subject.actions.must_equal ['htpasswd', 'new', 'dryrun', 'tasks', 'build', 'list', 'packages', 'override'] }
8
8
  end
9
9
 
10
+ describe 'machine_list' do
11
+ it 'lists the machines from machines.yml' do
12
+ File.open('machines.yml', 'w') {|f| f.puts({'machines' => {'machine_1' => {}, 'machine_2' => {}}}.to_yaml) }
13
+ subject.machine_list.must_equal "Machines from machines.yml:\n machine_1\n machine_2\n"
14
+ end
15
+ end
16
+
10
17
  describe 'syntax' do
11
18
  it 'includes version' do
12
19
  subject.syntax.must_match /machines v0\.[0-9]+\.[0-9]+ - Ubuntu\/Ruby configuration tool\./
@@ -15,7 +22,7 @@ describe Machines::Help do
15
22
  it 'includes syntax' do
16
23
  subject.syntax.must_match /machines COMMAND/
17
24
  subject.syntax.must_match /COMMAND can be:/
18
- subject.syntax.must_match /build <machine> \[task\] Builds your chosen machine\. Optionally, build just one task/
25
+ subject.syntax.must_match /build \<machine\> \[tasks\] Builds your chosen machine/
19
26
  end
20
27
  end
21
28
  end
@@ -82,12 +82,12 @@ describe 'Installation' do
82
82
  describe 'git_clone' do
83
83
  it 'instaniates a command to clone a git repository' do
84
84
  subject = git_clone 'http://git_url.git'
85
- subject.command.must_equal 'git clone --quiet http://git_url.git'
85
+ subject.command.must_equal 'test -d git_url && (cd git_url && git pull) || git clone --quiet http://git_url.git'
86
86
  end
87
87
 
88
88
  it 'instaniates a command to clone a git repository to a specified folder' do
89
89
  subject = git_clone 'http://git_url.git', :to => 'dir'
90
- subject.command.must_equal 'git clone --quiet http://git_url.git dir'
90
+ subject.command.must_equal 'test -d dir && (cd dir && git pull) || git clone --quiet http://git_url.git dir'
91
91
  end
92
92
 
93
93
  it 'raises when no url supplied' do
@@ -98,7 +98,7 @@ describe 'Installation' do
98
98
  describe ':branch option' do
99
99
  it 'clones to a specific branch' do
100
100
  subject = git_clone 'http://git_url.git', :branch => 'other'
101
- subject.command.must_equal 'git clone --quiet --branch other http://git_url.git'
101
+ subject.command.must_equal 'test -d git_url && (cd git_url && git pull) || git clone --quiet --branch other http://git_url.git'
102
102
  end
103
103
  end
104
104
 
@@ -106,7 +106,7 @@ describe 'Installation' do
106
106
  it 'checks out a specific tag' do
107
107
  subject = git_clone 'http://git_url.git', :to => 'dir', :tag => 'v1.0'
108
108
  subject.map(&:command).must_equal [
109
- 'git clone --quiet http://git_url.git dir',
109
+ 'test -d dir && (cd dir && git pull) || git clone --quiet http://git_url.git dir',
110
110
  'cd dir && git checkout v1.0'
111
111
  ]
112
112
  end
@@ -10,7 +10,7 @@ describe 'packages/apps' do
10
10
  $conf.commands.map(&:info).must_equal [
11
11
  "TASK abiword - Install a lightweight word processor",
12
12
  "SUDO apt-get -q -y install abiword",
13
- "TASK abiword_associations - Setup file associations for Abiword",
13
+ "TASK abiword_assoc - Setup file associations for Abiword",
14
14
  "RUN grep \"application/x-abiword=abiword.desktop\" .local/share/applications/mimeapps.list || echo \"application/x-abiword=abiword.desktop\" >> .local/share/applications/mimeapps.list",
15
15
  "RUN grep \"application/msword=abiword.desktop\" .local/share/applications/mimeapps.list || echo \"application/msword=abiword.desktop\" >> .local/share/applications/mimeapps.list",
16
16
  "RUN grep \"application/rtf=abiword.desktop\" .local/share/applications/mimeapps.list || echo \"application/rtf=abiword.desktop\" >> .local/share/applications/mimeapps.list"
@@ -19,7 +19,7 @@ describe 'packages/cruisecontrol' do
19
19
  eval_package
20
20
  $conf.commands.map(&:info).join("\n").must_equal [
21
21
  "TASK cruisecontrol - Install, configure and set to start on boot",
22
- "RUN git clone --quiet https://github.com/thoughtworks/cruisecontrol.rb.git",
22
+ "RUN test -d cruisecontrol.rb && (cd cruisecontrol.rb && git pull) || git clone --quiet https://github.com/thoughtworks/cruisecontrol.rb.git",
23
23
  "RUN cd cruisecontrol.rb && bundle",
24
24
  "RUN cd cruisecontrol.rb && ruby ./cruise add Application -r github.com/project",
25
25
  "SUDO cp -rf cruisecontrol.rb/daemon/cruise /etc/init.d/cruise",
@@ -17,7 +17,7 @@ describe 'packages/dotfiles' do
17
17
  it 'adds the following commands' do
18
18
  eval_package
19
19
  $conf.commands.map(&:info).join("\n").must_equal [
20
- "TASK dotfiles - Upload files in users/username/dotfiles, prepend a dot and substitute some bashrc vars",
20
+ "TASK dotfiles - Upload users/username/dotfiles and set some env vars",
21
21
  "UPLOAD #{File.expand_path('users/username/dotfiles/bashrc')} to .bashrc",
22
22
  "RUN mkdir -p $HOME/.ssh",
23
23
  "RUN chmod 700 $HOME/.ssh",
@@ -14,7 +14,7 @@ describe 'packages/apps' do
14
14
  $conf.commands.map(&:info).must_equal [
15
15
  "TASK file_roller - Install file-roller archive manager",
16
16
  "SUDO apt-get -q -y install file-roller",
17
- "TASK file_roller_associations - Setup file associations for file-roller",
17
+ "TASK file_roller_assoc - Setup file associations for file-roller",
18
18
  append_command('application/x-7z-compressed=file-roller.desktop'),
19
19
  append_command('application/x-7z-compressed-tar=file-roller.desktop'),
20
20
  append_command('application/x-ace=file-roller.desktop'),
@@ -12,7 +12,7 @@ describe 'packages/gmate' do
12
12
  "TASK gmate - Clone and install gmate for gEdit from Github and set some preferences and plugins",
13
13
  "SUDO apt-get -q -y install python-pyinotify",
14
14
  "SUDO apt-get -q -y install ack-grep",
15
- "RUN git clone --quiet git://github.com/gmate/gmate.git apps_root/gmate",
15
+ "RUN test -d apps_root/gmate && (cd apps_root/gmate && git pull) || git clone --quiet git://github.com/gmate/gmate.git apps_root/gmate",
16
16
  "RUN cd apps_root/gmate && echo \\n | ./install.sh",
17
17
  'RUN gconftool-2 --set "/apps/gedit-2/plugins/active-plugins" --type list --list-type=string ["text_tools","smart_indent","align","rails_hotkeys","trailsave","gemini","rubyonrailsloader","gedit_openfiles","quickhighlightmode","completion","time","docinfo","filebrowser","snippets","spell","indent","tabswitch"]',
18
18
  'RUN gconftool-2 --set "/apps/gedit-2/plugins/smart_indent/haml_tab_size" --type int 2',
@@ -10,7 +10,7 @@ describe 'packages/apps' do
10
10
  $conf.commands.map(&:info).must_equal [
11
11
  "TASK gnumeric - Install gnumeric lightweight spreadsheet",
12
12
  "SUDO apt-get -q -y install gnumeric",
13
- "TASK gnumeric_associations - Setup file associations for Gnumeric",
13
+ "TASK gnumeric_assoc - Setup file associations for Gnumeric",
14
14
  "RUN grep \"application/x-gnumeric=gnumeric.desktop\" .local/share/applications/mimeapps.list || echo \"application/x-gnumeric=gnumeric.desktop\" >> .local/share/applications/mimeapps.list",
15
15
  "RUN grep \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet=gnumeric.desktop\" .local/share/applications/mimeapps.list || echo \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet=gnumeric.desktop\" >> .local/share/applications/mimeapps.list",
16
16
  "RUN grep \"text/csv=gnumeric.desktop\" .local/share/applications/mimeapps.list || echo \"text/csv=gnumeric.desktop\" >> .local/share/applications/mimeapps.list",
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  describe 'packages/nginx' do
4
4
  before(:each) do
5
5
  load_package('nginx')
6
- $conf.from_hash(:webserver => {:name => 'nginx', :version => '1.0.2', :path => 'nginx_path', :conf_path => 'conf',
7
- :url => 'nginx_url/package', :src_path => '/usr/local/src/nginx-1.2.3', :modules => '--with-http_ssl_module'})
6
+ $conf.from_hash(webserver: {name: 'nginx', version: '1.2.3',
7
+ path: 'nginx_path', conf_path: 'conf', modules: '--with-http_ssl_module'})
8
8
  $conf.from_hash(:passenger => {:nginx => '/passenger/path/ext/nginx'})
9
9
  FileUtils.mkdir_p 'nginx'
10
10
  File.open('nginx/nginx.conf.erb', 'w') {|f| f.puts 'the template' }
@@ -16,7 +16,7 @@ describe 'packages/nginx' do
16
16
  eval_package
17
17
  $conf.commands.map(&:info).join("\n").must_equal [
18
18
  "TASK nginx - Download and configure Nginx",
19
- "SUDO cd /usr/local/src && wget nginx_url/package && tar -zxf package && rm package && cd -",
19
+ "SUDO cd /usr/local/src && wget http://nginx.org/download/nginx-1.2.3.tar.gz && tar -zxf nginx-1.2.3.tar.gz && rm nginx-1.2.3.tar.gz && cd -",
20
20
  'SUDO cd /usr/local/src/nginx-1.2.3 && ./configure --with-http_ssl_module --add-module=/passenger/path/ext/nginx && make && make install',
21
21
  "UPLOAD buffer from nginx/nginx.conf.erb to /tmp/nginx.conf",
22
22
  "SUDO cp -rf /tmp/nginx.conf nginx_path/conf/nginx.conf",
@@ -32,7 +32,7 @@ describe 'packages/nginx' do
32
32
  eval_package
33
33
  $conf.commands.map(&:info).join("\n").must_equal [
34
34
  "TASK nginx - Download and configure Nginx",
35
- "SUDO cd /usr/local/src && wget nginx_url/package && tar -zxf package && rm package && cd -",
35
+ "SUDO cd /usr/local/src && wget http://nginx.org/download/nginx-1.2.3.tar.gz && tar -zxf nginx-1.2.3.tar.gz && rm nginx-1.2.3.tar.gz && cd -",
36
36
  'SUDO cd /usr/local/src/nginx-1.2.3 && ./configure --with-http_ssl_module --add-module=/passenger/path/ext/nginx && make && make install',
37
37
  "UPLOAD buffer from nginx/nginx.conf.erb to /tmp/nginx.conf",
38
38
  "SUDO cp -rf /tmp/nginx.conf nginx_path/conf/nginx.conf",
@@ -5,18 +5,28 @@ describe 'packages/rbenv' do
5
5
  load_package('rbenv')
6
6
  $conf.ruby = AppConf.new
7
7
  $conf.ruby.version = '1.9.2'
8
- $conf.ruby.full_version = '1.9.2-p290'
8
+ $conf.ruby.build = 'p290'
9
+ end
10
+
11
+ it 'sets gems_path' do
12
+ eval_package
13
+ $conf.ruby.gems_path.must_equal '.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems'
14
+ end
15
+
16
+ it 'sets executable' do
17
+ eval_package
18
+ $conf.ruby.executable.must_equal '.rbenv/versions/1.9.2-p290/bin/ruby'
9
19
  end
10
20
 
11
21
  it 'adds the following commands' do
12
22
  eval_package
13
23
  $conf.commands.map(&:info).join("\n").must_equal [
14
- 'TASK rbenv - Install ruby-build, rbenv, ruby 1.9.2 and Bundler',
24
+ 'TASK rbenv - Install ruby-build, rbenv, ruby 1.9.2-p290 and Bundler',
15
25
  "SUDO apt-get -q -y install git-core",
16
26
  "SUDO apt-get -q -y install curl",
17
- 'RUN git clone --quiet git://github.com/sstephenson/ruby-build.git',
27
+ 'RUN test -d ruby-build && (cd ruby-build && git pull) || git clone --quiet git://github.com/sstephenson/ruby-build.git',
18
28
  'SUDO cd ~/ruby-build && ./install.sh',
19
- 'RUN git clone --quiet git://github.com/sstephenson/rbenv.git ~/.rbenv',
29
+ 'RUN test -d ~/.rbenv && (cd ~/.rbenv && git pull) || git clone --quiet git://github.com/sstephenson/rbenv.git ~/.rbenv',
20
30
  'RUN grep "PATH=.bin/safe/../../.bin:\\$HOME/.rbenv/bin:\\$HOME/.rbenv/shims:\\$PATH" ~/.profile || echo "PATH=.bin/safe/../../.bin:\\$HOME/.rbenv/bin:\\$HOME/.rbenv/shims:\\$PATH" >> ~/.profile',
21
31
 
22
32
  'RUN $HOME/.rbenv/bin/rbenv install 1.9.2-p290',
@@ -3,13 +3,23 @@ require 'spec_helper'
3
3
  describe 'packages/rvm' do
4
4
  before(:each) do
5
5
  load_package('rvm')
6
- $conf.from_hash(:ruby => {:version => '1.9'})
7
- $conf.from_hash(:rvm => {:url => 'rvm_url', :version => '1.0'})
6
+ $conf.from_hash(ruby: {version: '1.9.2', build: 'p290'})
7
+ $conf.from_hash(rvm: {version: '1.0'})
8
+ end
9
+
10
+ it 'sets gems_path' do
11
+ eval_package
12
+ $conf.ruby.gems_path.must_equal '.rvm/gems/1.9.2-p290/@global/gems'
13
+ end
14
+
15
+ it 'sets executable' do
16
+ eval_package
17
+ $conf.ruby.executable.must_equal '.rvm/wrappers/1.9.2-p290@global/ruby'
8
18
  end
9
19
 
10
20
  it 'adds the following commands' do
11
21
  eval_package
12
- $conf.commands.map(&:info).must_equal [
22
+ $conf.commands.map(&:info).join("\n").must_equal [
13
23
  "TASK rvm - Install RVM",
14
24
  "SUDO apt-get -q -y install git-core",
15
25
  'RUN bash -s 1.0 < <(wget -q https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )',
@@ -20,12 +30,12 @@ describe 'packages/rvm' do
20
30
  "TASK rvm_prompt_off - turn off trust prompting for new .rvmrc files",
21
31
  "RUN grep \"export rvm_trust_rvmrcs_flag=1\" .rvmrc || echo \"export rvm_trust_rvmrcs_flag=1\" >> .rvmrc",
22
32
 
23
- 'TASK ruby - Install Ruby, make 1.9@global the default and install Bundler',
24
- 'RUN rvm install 1.9',
25
- 'RUN rvm 1.9@global --default',
33
+ 'TASK ruby - Install Ruby, make 1.9.2-p290@global the default and install Bundler',
34
+ 'RUN rvm install 1.9.2',
35
+ 'RUN rvm 1.9.2@global --default',
26
36
  'UPLOAD buffer from .gemrc to .gemrc',
27
37
  'RUN gem install bundler'
28
- ]
38
+ ].join("\n")
29
39
  end
30
40
  end
31
41
 
@@ -9,7 +9,7 @@ describe 'packages/sqlserver' do
9
9
  eval_package
10
10
  $conf.commands.map(&:info).must_equal [
11
11
  "TASK sqlserver - Download and build sqlserver driver",
12
- "RUN git clone --quiet git://github.com/rails-sqlserver/tiny_tds.git",
12
+ "RUN test -d tiny_tds && (cd tiny_tds && git pull) || git clone --quiet git://github.com/rails-sqlserver/tiny_tds.git",
13
13
  "RUN cd tiny_tds && rake compile && rake native gem"
14
14
  ]
15
15
  end
@@ -3,12 +3,14 @@ require 'spec_helper'
3
3
  describe 'packages/unison' do
4
4
  before(:each) do
5
5
  load_package('unison')
6
+ $conf.machine = AppConf.new
7
+ $conf.machine.user = 'username'
6
8
  end
7
9
 
8
10
  it 'adds the following commands' do
9
11
  eval_package
10
12
  $conf.commands.map(&:info).must_equal [
11
- "TASK unison - Install unison two way file sync and set it to run hourly. Config in users/user/.unison/default.prf",
13
+ "TASK unison - Install and configure Unison (users/username/.unison/default.prf)",
12
14
  "SUDO apt-get -q -y install unison",
13
15
  "RUN echo '30 18 * * * /usr/bin/unison' | crontab"
14
16
  ]
@@ -27,7 +27,7 @@ describe 'packages/webapps' do
27
27
  $conf.environment = 'production'
28
28
  eval_package
29
29
  $conf.commands.map(&:info).join("\n").must_equal [
30
- "TASK webapps - Sets up Web apps in config/webapps.yml using app_server.conf.erb. Copies SSL certs.",
30
+ "TASK webapps - Sets up Web apps in config/webapps.yml using app_server.conf.erb",
31
31
  "SUDO mkdir -p nginx_path/servers",
32
32
  "RUN mkdir -p /home/users/application/releases",
33
33
  "RUN mkdir -p /home/users/application/shared/config",
@@ -54,9 +54,9 @@ describe 'packages/webapps' do
54
54
  eval_package
55
55
  commandline = $conf.commands.map(&:info).join("\n")
56
56
  commandline.must_equal [
57
- "TASK webapps - Sets up Web apps in config/webapps.yml using app_server.conf.erb. Copies SSL certs.",
57
+ "TASK webapps - Sets up Web apps in config/webapps.yml using app_server.conf.erb",
58
58
  "SUDO mkdir -p nginx_path/servers",
59
- "RUN git clone --quiet --branch master github.com/project /home/users/application",
59
+ "RUN test -d /home/users/application && (cd /home/users/application && git pull) || git clone --quiet --branch master github.com/project /home/users/application",
60
60
  "RUN cd /home/users/application && $HOME/.rbenv/bin/rbenv exec bundle",
61
61
  "RUN cd /home/users/application && $HOME/.rbenv/bin/rbenv exec bundle --binstubs=.bin",
62
62
  "UPLOAD buffer from nginx/app_server.conf.erb to /tmp/application.conf",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: machines
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-13 00:00:00.000000000 Z
12
+ date: 2012-09-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -318,7 +318,8 @@ dependencies:
318
318
  description: Install and configure Ubuntu desktops, laptops, servers and cloud instances.
319
319
  Install software, configure settings, preferences, keys, projects, applications,
320
320
  scripts, etc...
321
- email: phil@electricvisions.com
321
+ email: !binary |-
322
+ cGhpbEBlbGVjdHJpY3Zpc2lvbnMuY29t
322
323
  executables:
323
324
  - machines
324
325
  extensions: []
@@ -326,6 +327,7 @@ extra_rdoc_files: []
326
327
  files:
327
328
  - .gitignore
328
329
  - .yardopts
330
+ - CHANGELOG.md
329
331
  - EXAMPLES.md
330
332
  - Gemfile
331
333
  - Guardfile
@@ -518,7 +520,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
518
520
  version: '0'
519
521
  segments:
520
522
  - 0
521
- hash: 1670062508932557270
523
+ hash: 4483574387537312947
522
524
  required_rubygems_version: !ruby/object:Gem::Requirement
523
525
  none: false
524
526
  requirements: