linecook 0.6.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/History +139 -0
  2. data/HowTo/Control Virtual Machines +106 -0
  3. data/HowTo/Generate Scripts +263 -0
  4. data/HowTo/Run Scripts +87 -0
  5. data/HowTo/Setup Virtual Machines +76 -0
  6. data/License.txt +1 -1
  7. data/README +78 -59
  8. data/bin/linecook +12 -5
  9. data/bin/linecook_run +45 -0
  10. data/bin/linecook_scp +50 -0
  11. data/lib/linecook.rb +1 -3
  12. data/lib/linecook/attributes.rb +49 -12
  13. data/lib/linecook/commands.rb +9 -4
  14. data/lib/linecook/commands/build.rb +69 -0
  15. data/lib/linecook/commands/command.rb +13 -3
  16. data/lib/linecook/commands/command_error.rb +6 -0
  17. data/lib/linecook/commands/env.rb +74 -8
  18. data/lib/linecook/commands/helper.rb +271 -24
  19. data/lib/linecook/commands/init.rb +10 -6
  20. data/lib/linecook/commands/package.rb +36 -18
  21. data/lib/linecook/commands/run.rb +66 -0
  22. data/lib/linecook/commands/snapshot.rb +114 -0
  23. data/lib/linecook/commands/ssh.rb +39 -0
  24. data/lib/linecook/commands/start.rb +34 -0
  25. data/lib/linecook/commands/state.rb +32 -0
  26. data/lib/linecook/commands/stop.rb +22 -0
  27. data/lib/linecook/commands/vbox_command.rb +130 -0
  28. data/lib/linecook/cookbook.rb +112 -55
  29. data/lib/linecook/package.rb +293 -109
  30. data/lib/linecook/proxy.rb +19 -0
  31. data/lib/linecook/recipe.rb +321 -62
  32. data/lib/linecook/template.rb +7 -101
  33. data/lib/linecook/test.rb +196 -141
  34. data/lib/linecook/test/command_parser.rb +75 -0
  35. data/lib/linecook/test/file_test.rb +153 -35
  36. data/lib/linecook/test/shell_test.rb +176 -0
  37. data/lib/linecook/utils.rb +25 -7
  38. data/lib/linecook/version.rb +4 -4
  39. data/templates/Rakefile +44 -47
  40. data/templates/_gitignore +1 -1
  41. data/templates/attributes/project_name.rb +4 -4
  42. data/templates/config/ssh +15 -0
  43. data/templates/files/help.txt +1 -0
  44. data/templates/helpers/project_name/assert_content_equal.erb +15 -0
  45. data/templates/helpers/project_name/create_dir.erb +9 -0
  46. data/templates/helpers/project_name/create_file.erb +8 -0
  47. data/templates/helpers/project_name/install_file.erb +8 -0
  48. data/templates/packages/abox.yml +4 -0
  49. data/templates/recipes/abox.rb +22 -0
  50. data/templates/recipes/abox_test.rb +14 -0
  51. data/templates/templates/todo.txt.erb +3 -0
  52. data/templates/test/project_name_test.rb +19 -0
  53. data/templates/test/test_helper.rb +14 -0
  54. metadata +43 -41
  55. data/cookbook +0 -0
  56. data/lib/linecook/commands/helpers.rb +0 -28
  57. data/lib/linecook/commands/vbox.rb +0 -85
  58. data/lib/linecook/helper.rb +0 -117
  59. data/lib/linecook/shell.rb +0 -11
  60. data/lib/linecook/shell/posix.rb +0 -145
  61. data/lib/linecook/shell/test.rb +0 -254
  62. data/lib/linecook/shell/unix.rb +0 -117
  63. data/lib/linecook/shell/utils.rb +0 -138
  64. data/templates/README +0 -90
  65. data/templates/files/file.txt +0 -1
  66. data/templates/helpers/project_name/echo.erb +0 -5
  67. data/templates/recipes/project_name.rb +0 -20
  68. data/templates/scripts/project_name.yml +0 -7
  69. data/templates/templates/template.txt.erb +0 -3
  70. data/templates/vbox/setup/virtual_box +0 -86
  71. data/templates/vbox/ssh/id_rsa +0 -27
  72. data/templates/vbox/ssh/id_rsa.pub +0 -1
@@ -0,0 +1,87 @@
1
+ = Run Scripts
2
+
3
+ Linecook runs scripts using the 'run' command. Internally run copies scripts
4
+ to a server using scp and then executes the script using ssh. More
5
+ specifically run copies a *package* to the server and executes a script within
6
+ the package using ssh. A package is simply a directory containing scripts and
7
+ any files the scripts use.
8
+
9
+ To manually recreate what run does, make a directory with an script, copy it,
10
+ and execute as below (assuming you set up the 'abox' server {as described
11
+ earlier}[link:files/Tutorial/1%20-%20VM%20Setup.html]). Note that the script
12
+ is made executable locally such that scp will make the script executable on
13
+ the server.
14
+
15
+ mkdir demo
16
+ cat > demo/script.sh <<"DOC"
17
+ echo "# $(whoami)@$(hostname): hello world!"
18
+ DOC
19
+ chmod +x demo/script.sh
20
+
21
+ scp -r -P 2220 demo linecook@localhost:/tmp/demo
22
+ ssh -p 2220 linecook@localhost -- "/tmp/demo/script.sh"
23
+ # linecook@abox-ubuntu: hello world!
24
+
25
+ To simplify this a little, move the redundant information used by scp and ssh
26
+ can into a standard ssh config file. Linecook looks for an ssh config file in
27
+ 'config/ssh' by default:
28
+
29
+ mkdir config
30
+ cat > config/ssh <<DOC
31
+ Host abox
32
+ User linecook
33
+ HostName localhost
34
+ Port 2220
35
+ DOC
36
+
37
+ Now run will copy the package under the 'packages' directory with the same
38
+ name as the Host config, and execute the specified script:
39
+
40
+ mkdir packages
41
+ mv demo packages/abox
42
+ linecook run --script script.sh abox
43
+ # linecook@abox-ubuntu: hello world!
44
+
45
+ To run multiple packages at once, simply add more hosts to the ssh config
46
+ file. Run copies each package to the appropriate host and then runs the same
47
+ script on each (in alphabetic order by host). So say you also set up a 'bbox'
48
+ same as 'abox':
49
+
50
+ cat >> config/ssh <<DOC
51
+ Host abox
52
+ Port 2220
53
+
54
+ Host bbox
55
+ Port 2221
56
+
57
+ Host *
58
+ User linecook
59
+ HostName localhost
60
+ DOC
61
+ cp packages/abox packages/bbox
62
+
63
+ Then:
64
+
65
+ linecook run --script script.sh abox bbox
66
+ # linecook@abox-ubuntu: hello world!
67
+ # linecook@bbox-ubuntu: hello world!
68
+
69
+ Note that by default run will execute the 'run' script on all hosts configured
70
+ in 'config/ssh'. Leveraging these defaults simplifies the last command:
71
+
72
+ mv packages/abox/script.sh packages/abox/run
73
+ mv packages/bbox/script.sh packages/bbox/run
74
+ linecook run
75
+ # linecook@abox-ubuntu: hello world!
76
+ # linecook@bbox-ubuntu: hello world!
77
+
78
+ If you've never used scp/ssh with a config file then this may seem unfamiliar
79
+ but hopefully quite graceful. For scp/ssh masters, these are equivalent for
80
+ each host:
81
+
82
+ linecook run --remote-dir=/tmp/linecook SCRIPT ARGS...
83
+
84
+ scp -q -r -p -F config/ssh packages/host "host:/tmp/linecook"
85
+ ssh -q -t -t -F config/ssh host -- "/tmp/linecook/SCRIPT ARGS..."
86
+
87
+ Now that you can run scripts, onward to generating scripts!
@@ -0,0 +1,76 @@
1
+ = Setup Virtual Machines
2
+
3
+ {VirtualBox}[http://www.virtualbox.org] runs virtual machines on your local
4
+ box. Local VMs help minimize development cycles because they are quick to
5
+ access and reset. In addition, VirtualBox allows snapshots which can save and
6
+ restore a particular server state - this functionality enables iterative
7
+ development.
8
+
9
+ To set up a Ubuntu VM using VirtualBox:
10
+
11
+ 1. Download and Install VirtualBox (http://www.virtualbox.org)
12
+ 2. Download a Ubuntu ISO (http://www.ubuntu.com/server/get-ubuntu/download)
13
+ 3. Build the Box
14
+
15
+ When done, see the documentation for {controlling
16
+ VMs}[link:files/HowTo/Control%20Virtual%20Machines.html]
17
+
18
+ == Building a Ubuntu Box
19
+
20
+ Use the VirtualBox wizard to get started. The name and other settings (ex
21
+ user, ssh port) may be changed but be sure to propagate changes throughout the
22
+ setup process.
23
+
24
+ - name: abox
25
+ - Linux/Ubuntu
26
+ - 512 MB memory
27
+ - 8 GB dynamically resizing drive
28
+
29
+ Add the Ubuntu iso to the cd/dvd device under Settings > Storage. Now start
30
+ the server and install Ubuntu (use default settings unless specified):
31
+
32
+ - hostname: abox-ubuntu
33
+ - user/password: linecook
34
+ - select 'OpenSSH server' in packages to install
35
+
36
+ When the server has rebooted and is at the login screen, remove the install
37
+ iso, take a snapshot, and setup port forwarding. Port forwarding allows you to
38
+ access the ssh port (22) on the VM via a port on your local box (2220).
39
+
40
+ (Devices > CD/DVD Devices > Remove disk from virtual drive)
41
+ VBoxManage snapshot abox take RAW
42
+ VBoxManage controlvm abox poweroff
43
+ # wait to fully power off
44
+ VBoxManage modifyvm abox --natpf1 'abox-ssh,tcp,,2220,,22'
45
+ VBoxManage -q snapshot abox restore RAW
46
+ VBoxManage startvm abox
47
+
48
+ Transfer your ssh key to the VM (notice port 2220). Help to generate ssh keys
49
+ can be found on {GitHub}[http://help.github.com/key-setup-redirect]:
50
+
51
+ scp -P 2220 -o UserKnownHostsFile=/dev/null ~/.ssh/id_rsa.pub linecook@localhost:id_rsa.pub
52
+
53
+ Login as linecook and setup SSH access:
54
+
55
+ vm: mkdir .ssh
56
+ vm: mv id_rsa.pub .ssh/authorized_keys
57
+ vm: chmod 0700 .ssh
58
+ vm: chmod 0600 .ssh/authorized_keys
59
+
60
+ Remove the login banner (as a convenience) and exit:
61
+
62
+ vm: sudo rm /etc/motd
63
+ vm: exit
64
+
65
+ Now take a base snapshot:
66
+
67
+ VBoxManage snapshot abox take BASE
68
+ VBoxManage controlvm abox poweroff
69
+
70
+ To cleanup port forwarding (run later, if ever):
71
+
72
+ VBoxManage modifyvm abox --natpf1 delete 'abox-ssh'
73
+
74
+ The same procedure can be repeated to build other VMs. Nothing is special
75
+ about this setup. The os, name, port, and other settings may be changed to
76
+ your liking - all that Linecook requires is ssh access.
data/License.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Pinnacol Assurance
1
+ Copyright (c) 2010-2011 Pinnacol Assurance
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README CHANGED
@@ -4,95 +4,114 @@ A shell script generator.
4
4
 
5
5
  == Description
6
6
 
7
- Linecook lets you generate shell scripts using an extensible set of tiny ERB
8
- helpers. The helpers output a shell script that you can use to (for example)
9
- provision a server.
7
+ Linecook generates shell scripts using an extensible set of ERB helpers. The
8
+ shell scripts and associated resources (files, subscripts, etc) make up
9
+ packages that can be used, for example, to provision servers.
10
10
 
11
- The workflow is like this:
11
+ Linecook provides a command line tool to manage development servers, generate
12
+ scripts, and run scripts on servers. Helpers and recipes can be shared as
13
+ gems; the canonical shell helpers are available through
14
+ {Linebook}[http://rubygems.org/gems/linebook/].
12
15
 
13
- * define helpers
14
- * write a recipe using the helpers
15
- * generate a script from the recipe
16
+ See the documentation for help to:
16
17
 
17
- Linecook provides very basic helpers for POSIX shells and a command-line tool
18
- for generating scripts and running them on a test vm.
18
+ * {Setup}[link:files/HowTo/Setup%20Virtual%20Machines.html] and {Control}[link:files/HowTo/Control%20Virtual%20Machines.html] Virtual Machines
19
+ * {Generate Scripts}[link:files/HowTo/Generate%20Scripts.html]
20
+ * {Run Scripts}[link:files/HowTo/Run%20Scripts.html]
19
21
 
20
22
  == Usage
21
23
 
22
- Generate a cookbook.
24
+ Generate a project.
23
25
 
24
- % linecook init example
25
- % cd example
26
+ % linecook init chalkboard
27
+ % cd chalkboard
26
28
 
27
- Make some helpers.
29
+ Define default attributes.
28
30
 
29
- [helpers/example/_head.rb]
30
- COLOR_CODES = Hash[*%W{
31
- black 0;30 red 0;31
32
- white 1;37 green 0;32
33
- light_gray 0;37 blue 0;34
34
- }]
35
-
36
- [helpers/example/color.erb]
37
- Adds color to a string.
31
+ [attributes/chalkboard.rb]
32
+ attrs['chalkboard']['n'] = 3
33
+ attrs['chalkboard']['color'] = 'white'
34
+ attrs['chalkboard']['message'] = 'I will not manually configure my server'
35
+
36
+ Define a helper.
37
+
38
+ [helpers/chalkboard/echo_in_color.erb]
39
+ Echo a string in color.
38
40
  (color, str)
41
+ color_codes = Hash[*%W{
42
+ black 0;30 red 0;31
43
+ white 1;37 green 0;32
44
+ light_gray 0;37 blue 0;34
45
+ }]
39
46
  --
40
- \033[<%= COLOR_CODES[color.to_s] %>m<%= str %>\033[0m
47
+ echo -e '\033[<%= color_codes[color.to_s] %>m<%= str %>\033[0m'
48
+
49
+ Use both in a recipe.
50
+
51
+ [recipes/chalkboard.rb]
52
+ attributes "chalkboard"
53
+ helpers "chalkboard"
41
54
 
42
- [helpers/example/echo.erb]
43
- Echo a string in color
44
- (str, options={})
45
- color = options[:color]
46
- --
47
- echo -e '<%= color ? _color(color, str) : str %>'
55
+ attrs['chalkboard']['n'].times do
56
+ echo_in_color attrs['chalkboard']['color'], attrs['chalkboard']['message']
57
+ end
48
58
 
49
- Define default attributes.
59
+ Define a package to use the recipe; set non-default attributes as needed.
50
60
 
51
- [recipes/example.rb]
52
- attrs['example']['n'] = 3
53
- attrs['example']['color'] = 'blue'
61
+ [packages/chalkboard.yml]
62
+ chalkboard:
63
+ n: 5
64
+ color: blue
54
65
 
55
- Use them in a recipe.
66
+ Generate the package from the attributes, helpers, and recipe.
56
67
 
57
- [recipes/example.rb]
58
- helpers "example"
59
- attributes "example"
60
-
61
- attrs['example']['n'].times do
62
- echo "I will not manually configure my server", :color => attrs['example']['color']
63
- end
68
+ % linecook build
64
69
 
65
- Define a script using the recipe.
70
+ Check the packages directory to see the resulting script.
66
71
 
67
- [scripts/example.yml]
68
- linecook:
69
- recipe_name: example
70
- script_name: example.sh
71
- example:
72
- n: 100
72
+ % cat packages/chalkboard/run
73
+ echo -e '\033[0;34mI will not manually configure my server\033[0m'
74
+ echo -e '\033[0;34mI will not manually configure my server\033[0m'
75
+ echo -e '\033[0;34mI will not manually configure my server\033[0m'
76
+ echo -e '\033[0;34mI will not manually configure my server\033[0m'
77
+ echo -e '\033[0;34mI will not manually configure my server\033[0m'
73
78
 
74
- Generate a script from the helpers, attributes, and recipe.
79
+ Now run the package.
75
80
 
76
- % rake scripts
81
+ % linecook run
77
82
 
78
- Start the VM and run the scripts (see the docs for setting up a VM).
83
+ The package can be run on any server accessible via ssh. See the generated
84
+ 'config/ssh' file as well as the documentation for {Running Scripts on
85
+ Servers}[link:files/HowTo/Run%20Scripts.html].
79
86
 
80
- % rake vbox:start
81
- % rake vbox:ssh
82
- vm: bash /vbox/scripts/example.sh
83
- vm: exit
87
+ == Composition
84
88
 
85
- Stop the VM.
89
+ Linecook consists of the following.
90
+
91
+ = Components =
92
+ attributes
93
+ helpers
94
+ |-----> recipes -> packages -a-> (scripts) -b-> (servers) <-c- server setup
95
+ files
96
+ templates
97
+
98
+ = Commands =
99
+ ex: 'linecook build' on the command line
100
+
101
+ a) env, helper, package, build # build scripts
102
+ b) run # run scripts
103
+ c) start, stop, ssh, snapshot, reset # server setup/control
86
104
 
87
- % rake vbox:stop
105
+ Everything to the left of 'scripts' has to do with generating scripts;
106
+ everything to the right with running scripts on servers.
88
107
 
89
108
  == Installation
90
109
 
91
- Linecook is available as a gem on {Gemcutter}[http://gemcutter.org/gems/linecook]
110
+ Linecook is available as a {gem}[http://rubygems.org/gems/linecook].
92
111
 
93
112
  % gem install linecook
94
113
 
95
114
  == Info
96
115
 
97
- Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
116
+ Developer:: {Simon Chiang}[http://github.com/thinkerbot]
98
117
  License:: {MIT-Style}[link:files/License_txt.html]
data/bin/linecook CHANGED
@@ -1,5 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ if File.exists?('Gemfile')
4
+ require 'rubygems'
5
+ require 'bundler'
6
+ Bundler.setup
7
+ end
8
+
3
9
  require 'linecook/version'
4
10
  require 'linecook/commands'
5
11
  registry = Linecook::Commands::Command.registry
@@ -24,7 +30,7 @@ if cmd_class.nil?
24
30
 
25
31
  exit
26
32
  when '-v', '--version'
27
- puts "version #{Linecook::VERSION} -- #{Linecook::WEBSITE}"
33
+ puts "linecook version #{Linecook::VERSION} -- #{Linecook::WEBSITE}"
28
34
  exit
29
35
  else
30
36
  puts "unknown command: #{cmd.inspect}"
@@ -37,10 +43,10 @@ parser.add cmd_class.configurations
37
43
  parser.on '-h', '--help', 'print this help' do
38
44
  puts "usage: linecook [options] #{cmd} #{cmd_class.args}"
39
45
 
40
- desc = cmd_class.desc.wrap
46
+ desc = cmd_class.desc.wrap(76, 2, "\n ")
41
47
  unless desc.empty?
42
48
  puts
43
- puts cmd_class.desc.wrap
49
+ puts " #{desc}"
44
50
  puts
45
51
  end
46
52
 
@@ -53,6 +59,7 @@ parser.parse! ARGV
53
59
  begin
54
60
  cmd_class.new(parser.config).call ARGV
55
61
  rescue Linecook::Commands::CommandError
56
- puts $!.message
57
- exit 1
62
+ puts $!.message unless $!.message.strip.empty?
63
+ puts $!.backtrace if $DEBUG
64
+ exit $!.exitstatus
58
65
  end
data/bin/linecook_run ADDED
@@ -0,0 +1,45 @@
1
+ #! /bin/sh
2
+ ############################################################################
3
+
4
+ ssh_config_file=${SSH_CONFIG_FILE:-config/ssh}
5
+ remote_dir=${REMOTE_DIR:-$(pwd)/linecook}
6
+ remote_script=${REMOTE_SCRIPT:-run}
7
+
8
+ usage="usage: %s [-F SSH_CONFIG_FILE] [-D REMOTE_DIR] [-S REMOTE_SCRIPT] [-h] PACKAGE_DIRS...\n"
9
+ option=" %s %s\n"
10
+ while getopts "F:D:S:h" opt
11
+ do
12
+ case $opt in
13
+ F ) ssh_config_file=$OPTARG ;;
14
+ D ) remote_dir=$OPTARG ;;
15
+ S ) remote_script=$OPTARG ;;
16
+ h ) printf "$usage" $0
17
+ printf "$option" "-F" "the ssh config file"
18
+ printf "$option" "-D" "the remote package dir"
19
+ printf "$option" "-S" "the remote script"
20
+ printf "$option" "-h" "prints this help"
21
+ exit 0 ;;
22
+ \? ) printf "$usage" $0
23
+ exit 2 ;;
24
+ esac
25
+ done
26
+ shift $(($OPTIND - 1))
27
+
28
+ ################################### run ####################################
29
+
30
+ for package_dir in "$@"
31
+ do
32
+ host=$(basename -- "$package_dir")
33
+
34
+ ssh -q -t -t -F "$ssh_config_file" "$host" -- "$remote_dir/$remote_script" 2>/dev/null </dev/null
35
+
36
+ status=$?
37
+ if [ $status -ne 0 ]
38
+ then
39
+ echo "[$status] $remote_dir/$remote_script" >&2
40
+ exit 1
41
+ fi
42
+
43
+ done
44
+
45
+ ################################## (run) ###################################
data/bin/linecook_scp ADDED
@@ -0,0 +1,50 @@
1
+ #! /bin/sh
2
+ ############################################################################
3
+
4
+ ssh_config_file=${SSH_CONFIG_FILE:-config/ssh}
5
+ remote_dir=${REMOTE_DIR:-\$(pwd)/linecook}
6
+
7
+ usage="usage: %s [-D REMOTE_DIR] [-F SSH_CONFIG_FILE] [-h] PACKAGE_DIRS...\n"
8
+ option=" %s %s\n"
9
+ while getopts "F:D:h" opt
10
+ do
11
+ case $opt in
12
+ F ) ssh_config_file=$OPTARG ;;
13
+ D ) remote_dir=$OPTARG ;;
14
+ h ) printf "$usage" $0
15
+ printf "$option" "-F" "the ssh config file"
16
+ printf "$option" "-D" "the remote package dir"
17
+ printf "$option" "-h" "prints this help"
18
+ exit 0 ;;
19
+ \? ) printf "$usage" $0
20
+ exit 2 ;;
21
+ esac
22
+ done
23
+ shift $(($OPTIND - 1))
24
+
25
+ ################################### scp ####################################
26
+
27
+ for package_dir in "$@"
28
+ do
29
+ host=$(basename -- "$package_dir")
30
+
31
+ ssh -q -T -F "$ssh_config_file" "$host" -- <<SCRIPT
32
+ rm -rf "$remote_dir"
33
+ if [ "\$(dirname "$remote_dir")" != "" ]
34
+ then
35
+ mkdir -p "\$(dirname "$remote_dir")"
36
+ fi
37
+ SCRIPT
38
+
39
+ scp -q -r -p -F "$ssh_config_file" "$package_dir" "$host:$remote_dir"
40
+
41
+ status=$?
42
+ if [ $status -ne 0 ]
43
+ then
44
+ echo "[$status] $remote_dir/$script_name " >&2
45
+ exit 1
46
+ fi
47
+ done
48
+
49
+ ################################## (scp) ###################################
50
+