necktie 0.2.1 → 0.3.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.
- data/README.rdoc +174 -0
- data/bin/necktie +2 -1
- data/lib/necktie/files.rb +29 -0
- data/lib/necktie/rake.rb +127 -0
- data/lib/necktie/services.rb +11 -7
- data/lib/necktie.rb +4 -54
- data/necktie.gemspec +3 -3
- data/vendor/rake/CHANGES +477 -0
- data/vendor/rake/MIT-LICENSE +21 -0
- data/vendor/rake/README.rdoc +194 -0
- data/vendor/rake/Rakefile +421 -0
- data/vendor/rake/TODO +20 -0
- data/vendor/rake/bin/rake +31 -0
- data/vendor/rake/doc/command_line_usage.rdoc +102 -0
- data/vendor/rake/doc/example/Rakefile1 +38 -0
- data/vendor/rake/doc/example/Rakefile2 +35 -0
- data/vendor/rake/doc/example/a.c +6 -0
- data/vendor/rake/doc/example/b.c +6 -0
- data/vendor/rake/doc/example/main.c +11 -0
- data/vendor/rake/doc/glossary.rdoc +51 -0
- data/vendor/rake/doc/jamis.rb +591 -0
- data/vendor/rake/doc/proto_rake.rdoc +127 -0
- data/vendor/rake/doc/rake.1.gz +0 -0
- data/vendor/rake/doc/rakefile.rdoc +566 -0
- data/vendor/rake/doc/rational.rdoc +151 -0
- data/vendor/rake/doc/release_notes/rake-0.4.14.rdoc +23 -0
- data/vendor/rake/doc/release_notes/rake-0.4.15.rdoc +35 -0
- data/vendor/rake/doc/release_notes/rake-0.5.0.rdoc +53 -0
- data/vendor/rake/doc/release_notes/rake-0.5.3.rdoc +78 -0
- data/vendor/rake/doc/release_notes/rake-0.5.4.rdoc +46 -0
- data/vendor/rake/doc/release_notes/rake-0.6.0.rdoc +141 -0
- data/vendor/rake/doc/release_notes/rake-0.7.0.rdoc +119 -0
- data/vendor/rake/doc/release_notes/rake-0.7.1.rdoc +59 -0
- data/vendor/rake/doc/release_notes/rake-0.7.2.rdoc +121 -0
- data/vendor/rake/doc/release_notes/rake-0.7.3.rdoc +47 -0
- data/vendor/rake/doc/release_notes/rake-0.8.0.rdoc +114 -0
- data/vendor/rake/doc/release_notes/rake-0.8.2.rdoc +165 -0
- data/vendor/rake/doc/release_notes/rake-0.8.3.rdoc +112 -0
- data/vendor/rake/doc/release_notes/rake-0.8.4.rdoc +147 -0
- data/vendor/rake/doc/release_notes/rake-0.8.5.rdoc +53 -0
- data/vendor/rake/doc/release_notes/rake-0.8.6.rdoc +55 -0
- data/vendor/rake/doc/release_notes/rake-0.8.7.rdoc +55 -0
- data/vendor/rake/install.rb +88 -0
- data/vendor/rake/lib/rake/alt_system.rb +108 -0
- data/vendor/rake/lib/rake/application.rb +579 -0
- data/vendor/rake/lib/rake/classic_namespace.rb +9 -0
- data/vendor/rake/lib/rake/clean.rb +35 -0
- data/vendor/rake/lib/rake/cloneable.rb +25 -0
- data/vendor/rake/lib/rake/contrib/compositepublisher.rb +24 -0
- data/vendor/rake/lib/rake/contrib/ftptools.rb +153 -0
- data/vendor/rake/lib/rake/contrib/publisher.rb +75 -0
- data/vendor/rake/lib/rake/contrib/rubyforgepublisher.rb +18 -0
- data/vendor/rake/lib/rake/contrib/sshpublisher.rb +47 -0
- data/vendor/rake/lib/rake/contrib/sys.rb +209 -0
- data/vendor/rake/lib/rake/default_loader.rb +10 -0
- data/vendor/rake/lib/rake/dsl.rb +136 -0
- data/vendor/rake/lib/rake/early_time.rb +18 -0
- data/vendor/rake/lib/rake/environment.rb +40 -0
- data/vendor/rake/lib/rake/ext/module.rb +60 -0
- data/vendor/rake/lib/rake/ext/string.rb +165 -0
- data/vendor/rake/lib/rake/ext/time.rb +14 -0
- data/vendor/rake/lib/rake/file_creation_task.rb +24 -0
- data/vendor/rake/lib/rake/file_list.rb +395 -0
- data/vendor/rake/lib/rake/file_task.rb +47 -0
- data/vendor/rake/lib/rake/file_utils.rb +108 -0
- data/vendor/rake/lib/rake/gempackagetask.rb +97 -0
- data/vendor/rake/lib/rake/invocation_chain.rb +51 -0
- data/vendor/rake/lib/rake/invocation_exception_mixin.rb +16 -0
- data/vendor/rake/lib/rake/lib/project.rake +24 -0
- data/vendor/rake/lib/rake/loaders/makefile.rb +44 -0
- data/vendor/rake/lib/rake/multi_task.rb +16 -0
- data/vendor/rake/lib/rake/name_space.rb +25 -0
- data/vendor/rake/lib/rake/packagetask.rb +184 -0
- data/vendor/rake/lib/rake/psuedo_status.rb +24 -0
- data/vendor/rake/lib/rake/rake_file_utils.rb +133 -0
- data/vendor/rake/lib/rake/rake_module.rb +25 -0
- data/vendor/rake/lib/rake/rake_test_loader.rb +15 -0
- data/vendor/rake/lib/rake/rdoctask.rb +209 -0
- data/vendor/rake/lib/rake/ruby182_test_unit_fix.rb +25 -0
- data/vendor/rake/lib/rake/rule_recursion_overflow_error.rb +20 -0
- data/vendor/rake/lib/rake/runtest.rb +23 -0
- data/vendor/rake/lib/rake/task.rb +318 -0
- data/vendor/rake/lib/rake/task_argument_error.rb +7 -0
- data/vendor/rake/lib/rake/task_arguments.rb +78 -0
- data/vendor/rake/lib/rake/task_manager.rb +328 -0
- data/vendor/rake/lib/rake/tasklib.rb +24 -0
- data/vendor/rake/lib/rake/testtask.rb +175 -0
- data/vendor/rake/lib/rake/win32.rb +55 -0
- data/vendor/rake/lib/rake.rb +72 -0
- data/vendor/rake/rake.blurb +19 -0
- data/vendor/rake/rake.gemspec +214 -0
- data/vendor/rake/rakelib/extra.rake +8 -0
- data/vendor/rake/rakelib/publish.rake +22 -0
- data/vendor/rake/rakelib/rbx.rake +82 -0
- data/vendor/rake/rakelib/ruby19.rake +88 -0
- data/vendor/rake/rakelib/tags.rake +18 -0
- data/vendor/rake/test/capture_stdout.rb +26 -0
- data/vendor/rake/test/check_expansion.rb +5 -0
- data/vendor/rake/test/check_no_expansion.rb +5 -0
- data/vendor/rake/test/contrib/test_sys.rb +47 -0
- data/vendor/rake/test/data/chains/Rakefile +15 -0
- data/vendor/rake/test/data/comments/Rakefile +18 -0
- data/vendor/rake/test/data/default/Rakefile +19 -0
- data/vendor/rake/test/data/dryrun/Rakefile +22 -0
- data/vendor/rake/test/data/file_creation_task/Rakefile +33 -0
- data/vendor/rake/test/data/imports/Rakefile +19 -0
- data/vendor/rake/test/data/imports/deps.mf +1 -0
- data/vendor/rake/test/data/multidesc/Rakefile +17 -0
- data/vendor/rake/test/data/namespace/Rakefile +66 -0
- data/vendor/rake/test/data/nosearch/dummy +1 -0
- data/vendor/rake/test/data/rakelib/test1.rb +5 -0
- data/vendor/rake/test/data/rakelib/test2.rake +3 -0
- data/vendor/rake/test/data/rbext/rakefile.rb +3 -0
- data/vendor/rake/test/data/sample.mf +14 -0
- data/vendor/rake/test/data/statusreturn/Rakefile +8 -0
- data/vendor/rake/test/data/sys/sys1.rake +3 -0
- data/vendor/rake/test/data/unittest/Rakefile +1 -0
- data/vendor/rake/test/data/unittest/subdir/README +0 -0
- data/vendor/rake/test/data/verbose/Rakefile +34 -0
- data/vendor/rake/test/filecreation.rb +32 -0
- data/vendor/rake/test/functional/functional_test.rb +15 -0
- data/vendor/rake/test/functional/session_based_tests.rb +442 -0
- data/vendor/rake/test/in_environment.rb +32 -0
- data/vendor/rake/test/lib/application_test.rb +769 -0
- data/vendor/rake/test/lib/clean_test.rb +15 -0
- data/vendor/rake/test/lib/definitions_test.rb +85 -0
- data/vendor/rake/test/lib/dsl_test.rb +41 -0
- data/vendor/rake/test/lib/earlytime_test.rb +35 -0
- data/vendor/rake/test/lib/environment_test.rb +18 -0
- data/vendor/rake/test/lib/extension_test.rb +63 -0
- data/vendor/rake/test/lib/file_creation_task_test.rb +62 -0
- data/vendor/rake/test/lib/file_task_test.rb +143 -0
- data/vendor/rake/test/lib/filelist_test.rb +623 -0
- data/vendor/rake/test/lib/fileutils_test.rb +251 -0
- data/vendor/rake/test/lib/ftp_test.rb +59 -0
- data/vendor/rake/test/lib/invocation_chain_test.rb +81 -0
- data/vendor/rake/test/lib/makefile_loader_test.rb +26 -0
- data/vendor/rake/test/lib/multitask_test.rb +53 -0
- data/vendor/rake/test/lib/namespace_test.rb +55 -0
- data/vendor/rake/test/lib/package_task_test.rb +118 -0
- data/vendor/rake/test/lib/pathmap_test.rb +210 -0
- data/vendor/rake/test/lib/pseudo_status_test.rb +26 -0
- data/vendor/rake/test/lib/rake_test.rb +41 -0
- data/vendor/rake/test/lib/rdoc_task_test.rb +88 -0
- data/vendor/rake/test/lib/require_test.rb +35 -0
- data/vendor/rake/test/lib/rules_test.rb +349 -0
- data/vendor/rake/test/lib/task_arguments_test.rb +89 -0
- data/vendor/rake/test/lib/task_manager_test.rb +173 -0
- data/vendor/rake/test/lib/task_test.rb +376 -0
- data/vendor/rake/test/lib/tasklib_test.rb +12 -0
- data/vendor/rake/test/lib/test_task_test.rb +77 -0
- data/vendor/rake/test/lib/testtask_test.rb +49 -0
- data/vendor/rake/test/lib/top_level_functions_test.rb +86 -0
- data/vendor/rake/test/lib/win32_test.rb +72 -0
- data/vendor/rake/test/rake_test_setup.rb +24 -0
- data/vendor/rake/test/reqfile.rb +3 -0
- data/vendor/rake/test/reqfile2.rb +3 -0
- data/vendor/rake/test/reqfile3.rake +3 -0
- data/vendor/rake/test/shellcommand.rb +3 -0
- data/vendor/rake/test/test_helper.rb +13 -0
- metadata +212 -56
- /data/{rush → vendor/rush}/README.rdoc +0 -0
- /data/{rush → vendor/rush}/Rakefile +0 -0
- /data/{rush → vendor/rush}/VERSION +0 -0
- /data/{rush → vendor/rush}/bin/rush +0 -0
- /data/{rush → vendor/rush}/bin/rushd +0 -0
- /data/{rush → vendor/rush}/lib/rush/access.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/array_ext.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/box.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/commands.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/config.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/dir.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/embeddable_shell.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/entry.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/exceptions.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/file.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/find_by.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/fixnum_ext.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/head_tail.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/local.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/process.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/process_set.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/remote.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/search_results.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/server.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/shell.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/ssh_tunnel.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush/string_ext.rb +0 -0
- /data/{rush → vendor/rush}/lib/rush.rb +0 -0
- /data/{rush → vendor/rush}/rush.gemspec +0 -0
- /data/{rush → vendor/rush}/spec/access_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/array_ext_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/base.rb +0 -0
- /data/{rush → vendor/rush}/spec/box_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/commands_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/config_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/dir_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/embeddable_shell_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/entry_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/file_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/find_by_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/fixnum_ext_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/local_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/process_set_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/process_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/remote_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/rush_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/search_results_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/shell_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/ssh_tunnel_spec.rb +0 -0
- /data/{rush → vendor/rush}/spec/string_ext_spec.rb +0 -0
- /data/{session → vendor/session}/lib/session-2.4.0.rb +0 -0
- /data/{session → vendor/session}/lib/session.rb +0 -0
- /data/{session → vendor/session}/test/session.rb +0 -0
data/README.rdoc
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
I use Necktie to setup and upgrade multiple servers.
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
== Dress to impress
|
|
5
|
+
|
|
6
|
+
Necktie runs a set of scripts (or configuration tasks) that can create and edit
|
|
7
|
+
files, install and setup services, mount volumes, and basically anything you
|
|
8
|
+
can script with Ruby and a shell.
|
|
9
|
+
|
|
10
|
+
To use Necktie:
|
|
11
|
+
- Write your Necktie tasks using Ruby
|
|
12
|
+
- Include support files (config, binaries, etc)
|
|
13
|
+
- git push
|
|
14
|
+
- cap necktie
|
|
15
|
+
|
|
16
|
+
I use it to:
|
|
17
|
+
|
|
18
|
+
- gem install, apt-get
|
|
19
|
+
- Configure Nginx, install and setup Unicorn
|
|
20
|
+
- Change memcached configuration from default
|
|
21
|
+
- Setup MySQL to use a mounted (EBS) volume
|
|
22
|
+
- Install and update cron scripts
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
== Tasking
|
|
26
|
+
|
|
27
|
+
Necktie is based on Rake, so if you know Rake you already know most of Necktie.
|
|
28
|
+
At the base of your Necktie project there's a file called necktie (or Necktie,
|
|
29
|
+
or necktie.rb), with a list of task. For example:
|
|
30
|
+
|
|
31
|
+
file "/var/myapp" do
|
|
32
|
+
append "/etc/fstab", "\n/mnt/myapp /var/myapp none bind" unless read("/etc/fstab")["/mnt/myapp"]
|
|
33
|
+
mkdir_p "/var/myapp/"
|
|
34
|
+
sh "mount /var/myapp"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
task :rubygems do
|
|
38
|
+
FileList["gems/*.gem"].each do |gem|
|
|
39
|
+
install_gem gem
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
task :nginx do
|
|
44
|
+
rm_rf "/etc/nginx/sites-enabled/*"
|
|
45
|
+
cp "etc/nginx/unicorn.conf", "/etc/nginx/sites-available/"
|
|
46
|
+
ln_sf "/etc/nginx/sites-available/unicorn.conf", "/etc/nginx/sites-enabled/"
|
|
47
|
+
services.start "nginx"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
task :unicorn=>[:rubygems] do
|
|
51
|
+
cp "etc/init.d/unicorn", "/etc/init.d/"
|
|
52
|
+
chmod 0750, "/etc/init.d/unicorn"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
task :app=>["/var/myapp", :nginx, :unicorn]
|
|
56
|
+
|
|
57
|
+
You then run the app task, which runs all the dependencies necessary to setup
|
|
58
|
+
your application directory, system gems, Nginx and Unicorn configuration. Ready
|
|
59
|
+
for deployment.
|
|
60
|
+
|
|
61
|
+
If you changed one of the configuration files, you can run Necktie again: it
|
|
62
|
+
will pull updates from the Git repository and run these tasks with the new
|
|
63
|
+
configuration files.
|
|
64
|
+
|
|
65
|
+
Note: The nginx and unicorn files will run every time you run the app task, so
|
|
66
|
+
you can use them to push out new configuration. In contrast, the /var/myapp
|
|
67
|
+
directory is mounted by a file task that will only run once (if the directory
|
|
68
|
+
doesn't exist).
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
== cap necktie
|
|
72
|
+
|
|
73
|
+
I use Capistrano to setup new instances and upgrade existing ones. I then run
|
|
74
|
+
deploy:cold on the new instances, or deploy to upgrade running instances.
|
|
75
|
+
|
|
76
|
+
The Capistrano tasks looks something like this (see also:
|
|
77
|
+
extra/capistrano/necktie.rb):
|
|
78
|
+
|
|
79
|
+
# Copy Gem over so not depending on gem server being online, and all servers get
|
|
80
|
+
# to use the same version of Necktie.
|
|
81
|
+
gem_spec = Gem::SourceIndex.from_installed_gems.find_name("necktie").last
|
|
82
|
+
gem_file = File.join(Gem.dir, "cache", spec.file_name)
|
|
83
|
+
upload gem_file, File.basename(gem_file), :via=>:scp
|
|
84
|
+
sudo "gem install #{File.basename(gem_file)}"
|
|
85
|
+
# Run Necktie as sudo.
|
|
86
|
+
sudo "necktie #{necktie_url} #{ENV["ROLES"].to_s.gsub(',', ' ')}"
|
|
87
|
+
|
|
88
|
+
To setup a new server:
|
|
89
|
+
|
|
90
|
+
cap necktie HOSTS=ec2-75-101-239-12.compute-1.amazonaws.com
|
|
91
|
+
|
|
92
|
+
To upgrade instances:
|
|
93
|
+
|
|
94
|
+
git push && cap necktie
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
== Feel the rush
|
|
98
|
+
|
|
99
|
+
Necktie includes Rush, so you can write tasks like this:
|
|
100
|
+
|
|
101
|
+
unless processes.find { |p| p.cmdline[/memcached\s.*-l\s0.0.0.0/] }
|
|
102
|
+
box["/etc/memcached.conf"].replace_contents! /^-l 127.0.0.1/, "-l 0.0.0.0"
|
|
103
|
+
Services.start "memcached"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
You can learn more about Rush here: http://rush.heroku.com
|
|
107
|
+
|
|
108
|
+
Of course, there's also FileUtils, system and sh, so you can just:
|
|
109
|
+
|
|
110
|
+
cp "etc/init.d/unicorn", "/etc/init.d"
|
|
111
|
+
chmod 0755, "/etc/init.d/unicorn"
|
|
112
|
+
sh "service start unicorn"
|
|
113
|
+
|
|
114
|
+
Note: The current directory (launch_dir and Dir.pwd) is the root directory
|
|
115
|
+
of your Necktie repository. You can use relative paths to access files from your
|
|
116
|
+
Necktie repository.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
== Role play
|
|
120
|
+
|
|
121
|
+
If you have different setups, split them into roles and give each role its own
|
|
122
|
+
head task. You can then run Necktie for one or several roles, in the order they
|
|
123
|
+
are listed on the command line.
|
|
124
|
+
|
|
125
|
+
For example:
|
|
126
|
+
|
|
127
|
+
task :app=>["rubygems", "nginx", "unicorn", "/var/myapp"]
|
|
128
|
+
task :db=>["mount", "master", "backup"]
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
I recommend using the same roles for Necktie and Capistrano, then you can:
|
|
132
|
+
|
|
133
|
+
cap necktie ROLES=app,db
|
|
134
|
+
|
|
135
|
+
Note: Command line arguments are either task names (run in order), or
|
|
136
|
+
name=value pairs that set environment variables (e.g. RAILS_ENV=production).
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
== gem install
|
|
140
|
+
|
|
141
|
+
You can use install_gem in one of two ways. You can pass it a gem name and
|
|
142
|
+
(optional, but highly recommended) version requirement. For example:
|
|
143
|
+
|
|
144
|
+
install_gem "unicorn", "~= 0.93"
|
|
145
|
+
|
|
146
|
+
You can store the gem file in your Necktie repository and install it from there:
|
|
147
|
+
|
|
148
|
+
install_gem "gems/unicorn-0.93.3.gem"
|
|
149
|
+
|
|
150
|
+
I prefer the later, so I'm not affected when gem sources go offline just as I
|
|
151
|
+
decide to run my Necktie tasks.
|
|
152
|
+
|
|
153
|
+
Since install_gem will only install the same gem/version once, a run-always
|
|
154
|
+
rubygems.rb task is all you need:
|
|
155
|
+
|
|
156
|
+
launch_dir["gems/*.gem"].each do |gem|
|
|
157
|
+
install_gem gem.to_s
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
== License
|
|
162
|
+
|
|
163
|
+
Necktie, copyright (C) 2009 Assaf Arkin, released under the "Use for good, not
|
|
164
|
+
evil" license (http://www.json.org/license.html)
|
|
165
|
+
|
|
166
|
+
Includes Rake, created by Jim Weirich and released under the MIT license
|
|
167
|
+
http://rake.rubyforge.org/ http://github.com/jimweirich/rake
|
|
168
|
+
|
|
169
|
+
Includes Rush, created by Adam Wiggins and released under the MIT License
|
|
170
|
+
http://rush.heroku.com http://github.com/adamwiggins/rush
|
|
171
|
+
|
|
172
|
+
Includes Session, created by Ara T. Howard and released under the Ruby License
|
|
173
|
+
http://raa.ruby-lang.org/project/session
|
|
174
|
+
http://www.codeforpeople.com/lib/ruby/session
|
data/bin/necktie
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
$LOAD_PATH.unshift File.expand_path("../lib", File.dirname(__FILE__)),
|
|
3
|
-
File.expand_path("../
|
|
3
|
+
File.expand_path("../vendor/rake/lib", File.dirname(__FILE__)), File.expand_path("../vendor/rush/lib", File.dirname(__FILE__)),
|
|
4
|
+
File.expand_path("../vendor/session/lib", File.dirname(__FILE__))
|
|
4
5
|
require "necktie"
|
|
5
6
|
necktie ARGV
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
def read(name)
|
|
2
|
+
File.read(name)
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
def write(name, contents = nil)
|
|
6
|
+
contents ||= yield
|
|
7
|
+
File.open name, "w" do |f|
|
|
8
|
+
f.write contents
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def append(name, contents = nil)
|
|
13
|
+
contents ||= yield
|
|
14
|
+
File.open name, "a" do |f|
|
|
15
|
+
f.write contents
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def update(name, from = nil, to = nil)
|
|
20
|
+
contents = File.read(name)
|
|
21
|
+
if from && to
|
|
22
|
+
contents = contents.sub(from, to)
|
|
23
|
+
else
|
|
24
|
+
contents = yield(contents)
|
|
25
|
+
end
|
|
26
|
+
File.open name, "w" do |f|
|
|
27
|
+
f.write contents
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/necktie/rake.rb
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require "rake"
|
|
2
|
+
|
|
3
|
+
module Necktie
|
|
4
|
+
class Application < Rake::Application
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
@name = "necktie"
|
|
9
|
+
@rakefiles = ["Necktie", "necktie", "Necktie.rb", "necktie.rb"]
|
|
10
|
+
options.nosearch = true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def run
|
|
14
|
+
standard_exception_handling do
|
|
15
|
+
handle_options
|
|
16
|
+
Dir.chdir clone_repo do
|
|
17
|
+
collect_tasks
|
|
18
|
+
load_rakefile
|
|
19
|
+
top_level
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def clone_repo
|
|
25
|
+
@git_url = ARGV.shift or fail "expecting first argument to be a Git repository URL"
|
|
26
|
+
repo = File.expand_path(".necktie")
|
|
27
|
+
if File.exist?(repo)
|
|
28
|
+
puts "Pulling latest updates to #{repo}"
|
|
29
|
+
system "cd #{repo.inspect} && git pull origin #{ENV["BRANCH"] || "master"}" or fail
|
|
30
|
+
else
|
|
31
|
+
puts "Cloning #{@git_url} to #{repo}"
|
|
32
|
+
system "git clone #{@git_url} #{repo.inspect}" or fail
|
|
33
|
+
end
|
|
34
|
+
repo
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def necktie_options
|
|
38
|
+
[
|
|
39
|
+
['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
|
|
40
|
+
lambda { |value|
|
|
41
|
+
options.show_tasks = :describe
|
|
42
|
+
options.show_task_pattern = Regexp.new(value || '')
|
|
43
|
+
TaskManager.record_task_metadata = true
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.",
|
|
47
|
+
lambda { |value|
|
|
48
|
+
puts eval(value)
|
|
49
|
+
exit
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
['--execute-continue', '-E CODE',
|
|
53
|
+
"Execute some Ruby code, then continue with normal task processing.",
|
|
54
|
+
lambda { |value| eval(value) }
|
|
55
|
+
],
|
|
56
|
+
['--prereqs', '-P', "Display the tasks and dependencies, then exit.",
|
|
57
|
+
lambda { |value| options.show_prereqs = true }
|
|
58
|
+
],
|
|
59
|
+
['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.",
|
|
60
|
+
lambda { |value|
|
|
61
|
+
options.show_tasks = :tasks
|
|
62
|
+
options.show_task_pattern = Regexp.new(value || '')
|
|
63
|
+
Rake::TaskManager.record_task_metadata = true
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.",
|
|
67
|
+
lambda { |value|
|
|
68
|
+
options.trace = true
|
|
69
|
+
verbose(true)
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
['--verbose', '-v', "Log message to standard output.",
|
|
73
|
+
lambda { |value| verbose(true) }
|
|
74
|
+
],
|
|
75
|
+
['--version', '-V', "Display the program version.",
|
|
76
|
+
lambda { |value|
|
|
77
|
+
spec = Gem::Specification.load(File.expand_path("../necktie.gemspec", File.dirname(__FILE__)))
|
|
78
|
+
puts "Necktie, version #{spec.version}"
|
|
79
|
+
exit
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
['--where', '-W [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.",
|
|
83
|
+
lambda { |value|
|
|
84
|
+
options.show_tasks = :lines
|
|
85
|
+
options.show_task_pattern = Regexp.new(value || '')
|
|
86
|
+
Rake::TaskManager.record_task_metadata = true
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Read and handle the command line options.
|
|
93
|
+
def handle_options
|
|
94
|
+
options.rakelib = ['necktie']
|
|
95
|
+
options.top_level_dsl = true
|
|
96
|
+
|
|
97
|
+
OptionParser.new do |opts|
|
|
98
|
+
opts.banner = "necktie git_url {options} tasks..."
|
|
99
|
+
opts.separator ""
|
|
100
|
+
opts.separator "Options are ..."
|
|
101
|
+
|
|
102
|
+
opts.on_tail("-h", "--help", "-H", "Display this help message.") do
|
|
103
|
+
puts opts
|
|
104
|
+
exit
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
necktie_options.each { |args| opts.on(*args) }
|
|
108
|
+
opts.environment('RAKEOPT')
|
|
109
|
+
end.parse!
|
|
110
|
+
|
|
111
|
+
Rake::DSL.include_in_top_scope
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def raw_load_rakefile # :nodoc:
|
|
115
|
+
@rakefile = have_rakefile
|
|
116
|
+
fail "No Necktie file found (looking for: #{@rakefiles.join(', ')})" if @rakefile.nil?
|
|
117
|
+
Rake::Environment.load_rakefile(File.expand_path(@rakefile)) if @rakefile && @rakefile != ''
|
|
118
|
+
options.rakelib.each do |rlib|
|
|
119
|
+
glob("necktie/*.rb") do |name|
|
|
120
|
+
add_import name
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
load_imports
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
end
|
data/lib/necktie/services.rb
CHANGED
|
@@ -1,33 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
def
|
|
1
|
+
class Services
|
|
2
|
+
def start(name)
|
|
3
3
|
puts " ** Starting service #{name}"
|
|
4
4
|
system "update-rc.d #{name} defaults" and
|
|
5
5
|
system "service #{name} start" or
|
|
6
6
|
fail "failed to start #{name}"
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def
|
|
9
|
+
def enable(name)
|
|
10
10
|
system "update-rc.d #{name} defaults" or "cannot enable #{name}"
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def
|
|
13
|
+
def stop(name)
|
|
14
14
|
puts " ** Stopping service #{name}"
|
|
15
15
|
system "service #{name} stop" and
|
|
16
16
|
system "update-rc.d -f #{name} remove" or
|
|
17
17
|
fail "failed to stop #{name}"
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def disable(name)
|
|
21
21
|
system "update-rc.d -f #{name} remove" or fail "cannot disable #{name}"
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def
|
|
24
|
+
def restart(name)
|
|
25
25
|
puts " ** Stopping service #{name}"
|
|
26
26
|
system "service #{name} restart" or fail "failed to restart #{name}"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def
|
|
29
|
+
def running?(name)
|
|
30
30
|
status = File.read("|service --status-all 2>&1")[/^ \[ (.) \] #{Regexp.escape name}$/,1]
|
|
31
31
|
status == "+" ? true : status == "-" ? false : nil
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
+
|
|
35
|
+
def services
|
|
36
|
+
@services ||= Services.new
|
|
37
|
+
end
|
data/lib/necktie.rb
CHANGED
|
@@ -1,59 +1,9 @@
|
|
|
1
|
-
require "
|
|
2
|
-
|
|
1
|
+
require "necktie/rake"
|
|
2
|
+
require "necktie/files"
|
|
3
3
|
require "necktie/gems"
|
|
4
4
|
require "necktie/services"
|
|
5
5
|
require "necktie/rush"
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
File.writable?(etc) or File.writable?(File.dirname(etc)) or fail "Can't write to #{etc}. You should be running necktie as sudo."
|
|
11
|
-
|
|
12
|
-
envs, args = args.partition { |a| a[/=/] }
|
|
13
|
-
git_url = args.shift or fail "Usage: necktie git-url role* name=value*"
|
|
14
|
-
roles = args
|
|
15
|
-
# Setup environment variable from name=value arguments.
|
|
16
|
-
envs.each do |env|
|
|
17
|
-
name, value = env.split("=")
|
|
18
|
-
ENV[name] = value
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Default role is app. For all rules, execute setup scripts.
|
|
22
|
-
if roles.empty?
|
|
23
|
-
puts " Default role: app"
|
|
24
|
-
roles = ["app"]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
repo = File.expand_path(".necktie")
|
|
28
|
-
if File.exist?(repo)
|
|
29
|
-
puts " * Pulling latest updates to #{repo}"
|
|
30
|
-
system "cd #{repo.inspect} && git pull origin #{ENV["branch"] || "master"}" or fail
|
|
31
|
-
else
|
|
32
|
-
puts " * Cloning #{git_url} to #{repo}"
|
|
33
|
-
system "git clone #{git_url} #{repo.inspect}" or fail
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
Dir.chdir repo do
|
|
37
|
-
executed = File.exist?(etc) ? File.read(etc).split("\n") : []
|
|
38
|
-
roles.each do |role|
|
|
39
|
-
skip = executed.map { |t| t[/^#{Regexp.escape role}\/(.*)$/, 1] }.reject(&:nil?)
|
|
40
|
-
tasks = Dir["tasks/#{role}/*.rb"].sort.map { |name| File.basename(name).gsub(/\.rb$/, "") }
|
|
41
|
-
todo = tasks - skip
|
|
42
|
-
if tasks.empty?
|
|
43
|
-
puts " * No tasks for role #{role}"
|
|
44
|
-
elsif todo.empty?
|
|
45
|
-
puts " * All tasks completed for role #{role}"
|
|
46
|
-
else
|
|
47
|
-
puts " * Now in role: #{role}"
|
|
48
|
-
File.open etc, "a" do |f|
|
|
49
|
-
todo.each do |task|
|
|
50
|
-
puts " ** Executing #{task}"
|
|
51
|
-
load "tasks/#{role}/#{task}.rb"
|
|
52
|
-
f.puts task if task[/^\d+_/]
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
end
|
|
8
|
+
Rake.application = Necktie::Application.new
|
|
9
|
+
Rake.application.run
|
data/necktie.gemspec
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Gem::Specification.new do |spec|
|
|
2
2
|
spec.name = "necktie"
|
|
3
|
-
spec.version = "0.
|
|
3
|
+
spec.version = "0.3.0"
|
|
4
4
|
spec.author = "Assaf Arkin"
|
|
5
5
|
spec.email = "assaf@labnotes.org"
|
|
6
6
|
spec.homepage = ""
|
|
7
7
|
spec.summary = "Dress to impress"
|
|
8
|
-
spec.description = ""
|
|
8
|
+
spec.description = "Configure your servers remotely using Ruby and Git"
|
|
9
9
|
|
|
10
|
-
spec.files = Dir["{bin,lib,
|
|
10
|
+
spec.files = Dir["{bin,lib,vendor}/**/*", "*.{gemspec,rdoc}"]
|
|
11
11
|
spec.executable = "necktie"
|
|
12
12
|
end
|