linecook 1.2.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{History → History.rdoc} +3 -2
- data/README.rdoc +93 -0
- data/bin/linecook +32 -56
- data/bin/linecook_run +19 -6
- data/bin/linecook_scp +12 -4
- data/doc/vm_setup.rdoc +75 -0
- data/lib/linecook.rb +3 -2
- data/lib/linecook/attributes.rb +33 -8
- data/lib/linecook/command.rb +61 -0
- data/lib/linecook/command_set.rb +85 -0
- data/lib/linecook/command_utils.rb +20 -0
- data/lib/linecook/commands/build.rb +108 -57
- data/lib/linecook/commands/compile.rb +181 -0
- data/lib/linecook/commands/{helper.rb → compile_helper.rb} +123 -94
- data/lib/linecook/commands/run.rb +43 -39
- data/lib/linecook/commands/snapshot.rb +24 -24
- data/lib/linecook/commands/ssh.rb +7 -7
- data/lib/linecook/commands/start.rb +10 -10
- data/lib/linecook/commands/state.rb +7 -7
- data/lib/linecook/commands/stop.rb +3 -3
- data/lib/linecook/commands/{vbox_command.rb → virtual_box_command.rb} +31 -29
- data/lib/linecook/cookbook.rb +149 -131
- data/lib/linecook/executable.rb +28 -0
- data/lib/linecook/package.rb +177 -361
- data/lib/linecook/proxy.rb +4 -10
- data/lib/linecook/recipe.rb +289 -369
- data/lib/linecook/test.rb +114 -98
- data/lib/linecook/utils.rb +31 -41
- data/lib/linecook/version.rb +2 -6
- metadata +120 -68
- data/HowTo/Control Virtual Machines +0 -106
- data/HowTo/Generate Scripts +0 -268
- data/HowTo/Run Scripts +0 -87
- data/HowTo/Setup Virtual Machines +0 -76
- data/README +0 -117
- data/lib/linecook/commands.rb +0 -11
- data/lib/linecook/commands/command.rb +0 -58
- data/lib/linecook/commands/command_error.rb +0 -12
- data/lib/linecook/commands/env.rb +0 -89
- data/lib/linecook/commands/init.rb +0 -86
- data/lib/linecook/commands/package.rb +0 -57
- data/lib/linecook/template.rb +0 -17
- data/lib/linecook/test/command_parser.rb +0 -75
- data/lib/linecook/test/file_test.rb +0 -197
- data/lib/linecook/test/regexp_escape.rb +0 -86
- data/lib/linecook/test/shell_test.rb +0 -177
- data/lib/linecook/test/shim.rb +0 -71
- data/templates/Gemfile +0 -3
- data/templates/Rakefile +0 -146
- data/templates/_gitignore +0 -4
- data/templates/attributes/project_name.rb +0 -3
- data/templates/config/ssh +0 -14
- data/templates/cookbook +0 -10
- data/templates/files/example.txt +0 -1
- data/templates/helpers/project_name/echo.erb +0 -4
- data/templates/packages/abox.yml +0 -2
- data/templates/project_name.gemspec +0 -30
- data/templates/recipes/abox.rb +0 -16
- data/templates/templates/example.erb +0 -1
- data/templates/test/project_name_test.rb +0 -24
- data/templates/test/test_helper.rb +0 -14
@@ -1,76 +0,0 @@
|
|
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/README
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
= Linecook
|
2
|
-
|
3
|
-
A shell script generator.
|
4
|
-
|
5
|
-
== Description
|
6
|
-
|
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
|
-
|
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/].
|
15
|
-
|
16
|
-
See the documentation for help to:
|
17
|
-
|
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]
|
21
|
-
|
22
|
-
== Usage
|
23
|
-
|
24
|
-
Generate a project.
|
25
|
-
|
26
|
-
% linecook init chalkboard
|
27
|
-
% cd chalkboard
|
28
|
-
|
29
|
-
Define default attributes.
|
30
|
-
|
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.
|
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
|
-
}]
|
46
|
-
--
|
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"
|
54
|
-
|
55
|
-
attrs['chalkboard']['n'].times do
|
56
|
-
echo_in_color attrs['chalkboard']['color'], attrs['chalkboard']['message']
|
57
|
-
end
|
58
|
-
|
59
|
-
Define a package to use the recipe; set non-default attributes as needed.
|
60
|
-
|
61
|
-
[packages/chalkboard.yml]
|
62
|
-
chalkboard:
|
63
|
-
n: 5
|
64
|
-
color: blue
|
65
|
-
|
66
|
-
Generate the package from the attributes, helpers, and recipe.
|
67
|
-
|
68
|
-
% linecook build
|
69
|
-
|
70
|
-
Check the packages directory to see the resulting script.
|
71
|
-
|
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'
|
78
|
-
|
79
|
-
Now run the package.
|
80
|
-
|
81
|
-
% linecook run
|
82
|
-
|
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].
|
86
|
-
|
87
|
-
== Composition
|
88
|
-
|
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
|
104
|
-
|
105
|
-
Everything to the left of 'scripts' has to do with generating scripts;
|
106
|
-
everything to the right with running scripts on servers.
|
107
|
-
|
108
|
-
== Installation
|
109
|
-
|
110
|
-
Linecook is available as a {gem}[http://rubygems.org/gems/linecook].
|
111
|
-
|
112
|
-
% gem install linecook
|
113
|
-
|
114
|
-
== Info
|
115
|
-
|
116
|
-
Developer:: {Simon Chiang}[http://github.com/thinkerbot]
|
117
|
-
License:: {MIT-Style}[link:files/License_txt.html]
|
data/lib/linecook/commands.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'linecook/commands/build'
|
2
|
-
require 'linecook/commands/env'
|
3
|
-
require 'linecook/commands/helper'
|
4
|
-
require 'linecook/commands/init'
|
5
|
-
require 'linecook/commands/package'
|
6
|
-
require 'linecook/commands/snapshot'
|
7
|
-
require 'linecook/commands/ssh'
|
8
|
-
require 'linecook/commands/start'
|
9
|
-
require 'linecook/commands/state'
|
10
|
-
require 'linecook/commands/stop'
|
11
|
-
require 'linecook/commands/run'
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'linecook/commands/command_error'
|
2
|
-
require 'configurable'
|
3
|
-
|
4
|
-
module Linecook
|
5
|
-
module Commands
|
6
|
-
class Command
|
7
|
-
class << self
|
8
|
-
def registry
|
9
|
-
REGISTRY
|
10
|
-
end
|
11
|
-
|
12
|
-
def inherited(base)
|
13
|
-
super
|
14
|
-
registry[base.to_s.split('::').last.downcase] = base
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
REGISTRY = {}
|
19
|
-
|
20
|
-
extend Lazydoc::Attributes
|
21
|
-
include Configurable
|
22
|
-
|
23
|
-
lazy_attr :desc
|
24
|
-
lazy_attr :args, :process
|
25
|
-
lazy_register :process, Lazydoc::Arguments
|
26
|
-
|
27
|
-
attr_accessor :quiet
|
28
|
-
|
29
|
-
def initialize(config={})
|
30
|
-
@quiet = true
|
31
|
-
initialize_config(config)
|
32
|
-
end
|
33
|
-
|
34
|
-
def log(action, msg)
|
35
|
-
$stderr.puts(" %s %s" % [action, msg])
|
36
|
-
end
|
37
|
-
|
38
|
-
def sh(cmd)
|
39
|
-
puts "% #{cmd}" unless quiet
|
40
|
-
system(cmd)
|
41
|
-
end
|
42
|
-
|
43
|
-
def sh!(cmd)
|
44
|
-
unless sh(cmd)
|
45
|
-
raise CommandError.new("", $?.exitstatus)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def call(argv)
|
50
|
-
process(*argv)
|
51
|
-
end
|
52
|
-
|
53
|
-
def process(*args)
|
54
|
-
raise NotImplementedError
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
require 'linecook/commands/command'
|
2
|
-
require 'linecook/cookbook'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
module Linecook
|
6
|
-
module Commands
|
7
|
-
|
8
|
-
# :startdoc::desc prints a package env
|
9
|
-
#
|
10
|
-
# Prints the env for the current project directory. Specifically the
|
11
|
-
# cookbook file is loaded and used to determine all resources that are
|
12
|
-
# current available. The full build env for a package can be viewed by
|
13
|
-
# specifying the package file as an option.
|
14
|
-
#
|
15
|
-
# A specific env value can be printed by specifying the key path to it.
|
16
|
-
class Env < Command
|
17
|
-
config :project_dir, '.', :short => :d # the project directory
|
18
|
-
config :package_file, nil, :short => :p # the package file
|
19
|
-
|
20
|
-
# :stopdoc:
|
21
|
-
# Evaluate to replace the to_yaml function on Hash so that it will
|
22
|
-
# serialize keys in order. Evaluate the OFF code to turn this hack off
|
23
|
-
# (and thereby ease up on the code pollution)
|
24
|
-
#
|
25
|
-
# Modified from: http://snippets.dzone.com/posts/show/5811 Original
|
26
|
-
# func: /usr/lib/ruby/1.8/yaml/rubytypes.rb
|
27
|
-
ORIGINAL_TO_YAML = 'linecook_original_to_yaml'
|
28
|
-
SORTED_HASH_ON_LINE = __LINE__ + 1
|
29
|
-
SORTED_HASH_ON = %{
|
30
|
-
class Hash
|
31
|
-
unless instance_methods.include?('#{ORIGINAL_TO_YAML}')
|
32
|
-
alias #{ORIGINAL_TO_YAML} to_yaml
|
33
|
-
undef_method :to_yaml
|
34
|
-
def to_yaml( opts = {} )
|
35
|
-
YAML::quick_emit( object_id, opts ) do |out|
|
36
|
-
out.map( taguri, to_yaml_style ) do |map|
|
37
|
-
keys.sort_by do |k|
|
38
|
-
k.to_s
|
39
|
-
end.each do |k|
|
40
|
-
map.add( k, fetch(k) )
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end}
|
47
|
-
|
48
|
-
SORTED_HASH_OFF_LINE = __LINE__ + 1
|
49
|
-
SORTED_HASH_OFF = %{
|
50
|
-
class Hash
|
51
|
-
if instance_methods.include?('#{ORIGINAL_TO_YAML}')
|
52
|
-
undef_method :to_yaml
|
53
|
-
alias to_yaml #{ORIGINAL_TO_YAML}
|
54
|
-
undef_method :#{ORIGINAL_TO_YAML}
|
55
|
-
end
|
56
|
-
end}
|
57
|
-
# :startdoc:
|
58
|
-
|
59
|
-
def select(current, *keys)
|
60
|
-
keys.each do |key|
|
61
|
-
unless current.kind_of?(Hash)
|
62
|
-
return nil
|
63
|
-
end
|
64
|
-
|
65
|
-
current = current[key]
|
66
|
-
end
|
67
|
-
|
68
|
-
current
|
69
|
-
end
|
70
|
-
|
71
|
-
# Serializes the env to the target as YAML. Ensures hashes are
|
72
|
-
# serialized with their keys sorted by their to_s value.
|
73
|
-
def serialize(env, target="")
|
74
|
-
begin
|
75
|
-
eval SORTED_HASH_ON, TOPLEVEL_BINDING, __FILE__, SORTED_HASH_ON_LINE
|
76
|
-
YAML.dump(env, target)
|
77
|
-
ensure
|
78
|
-
eval SORTED_HASH_OFF, TOPLEVEL_BINDING, __FILE__, SORTED_HASH_OFF_LINE
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def process(*keys)
|
83
|
-
package = Linecook::Package.init(package_file, project_dir)
|
84
|
-
env = select(package.env, *keys)
|
85
|
-
serialize(env, $stdout)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'linecook/commands/command'
|
2
|
-
require 'linecook/utils'
|
3
|
-
require 'fileutils'
|
4
|
-
require 'erb'
|
5
|
-
require 'ostruct'
|
6
|
-
|
7
|
-
module Linecook
|
8
|
-
module Commands
|
9
|
-
|
10
|
-
# :startdoc::desc create a linecook scaffold
|
11
|
-
#
|
12
|
-
# Initializes a linecook scaffold in the specified directory. This
|
13
|
-
# initializer is currently very basic; it is not a true generator.
|
14
|
-
#
|
15
|
-
class Init < Command
|
16
|
-
config :force, false, :short => :f, &c.flag # force creation
|
17
|
-
|
18
|
-
def source_dir
|
19
|
-
@source_dir ||= File.expand_path('../../../../templates', __FILE__)
|
20
|
-
end
|
21
|
-
|
22
|
-
def process(project_dir)
|
23
|
-
project_dir = File.expand_path(project_dir)
|
24
|
-
|
25
|
-
prepare project_dir
|
26
|
-
template project_dir
|
27
|
-
end
|
28
|
-
|
29
|
-
def prepare(project_dir)
|
30
|
-
if File.exists?(project_dir)
|
31
|
-
unless force
|
32
|
-
raise CommandError.new("already exists: #{project_dir}")
|
33
|
-
end
|
34
|
-
|
35
|
-
current_dir = File.expand_path('.')
|
36
|
-
unless project_dir.index(current_dir) == 0 && project_dir.length > current_dir.length
|
37
|
-
raise CommandError.new("cannot force creation of current or parent directory (safety issue)")
|
38
|
-
end
|
39
|
-
|
40
|
-
FileUtils.rm_rf(project_dir)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def template(project_dir, project_name=nil)
|
45
|
-
project_name ||= File.basename(project_dir)
|
46
|
-
context = OpenStruct.new(
|
47
|
-
:project_name => project_name,
|
48
|
-
:const_name => Utils.camelize(project_name)
|
49
|
-
).instance_eval('binding')
|
50
|
-
|
51
|
-
#
|
52
|
-
# Copy template files into place
|
53
|
-
#
|
54
|
-
|
55
|
-
Dir.glob("#{source_dir}/**/*").each do |source|
|
56
|
-
if File.directory?(source)
|
57
|
-
next
|
58
|
-
end
|
59
|
-
|
60
|
-
path = source[(source_dir.length + 1)..-1]
|
61
|
-
path = path.sub('project_name', project_name).sub(/^_/, '.')
|
62
|
-
target = File.join(project_dir, path)
|
63
|
-
|
64
|
-
log :create, path
|
65
|
-
|
66
|
-
target_dir = File.dirname(target)
|
67
|
-
unless File.exists?(target_dir)
|
68
|
-
FileUtils.mkdir_p(target_dir)
|
69
|
-
end
|
70
|
-
|
71
|
-
File.open(target, 'w') do |io|
|
72
|
-
erb = ERB.new(File.read(source), nil, '<>')
|
73
|
-
erb.filename = source
|
74
|
-
io << erb.result(context)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Link up project dir into test
|
79
|
-
target = File.join(project_dir, 'test', "#{project_name}_test", "test_#{project_name}")
|
80
|
-
FileUtils.mkdir_p File.dirname(target)
|
81
|
-
FileUtils.ln_s project_dir, target
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|