metacon 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ # Just a fancy way to run rake against exactly the right Rakefile, with a
3
+ # default WORKER_ENV always of development, and more easily pass in
4
+ # command-line parameters to the task, etc. Meant to be symlinked to.
5
+ #
6
+ # ex:
7
+ # $ do-something production blah
8
+ # (becomes, more or less)
9
+ # $ WORKER_ENV=production rake do-something[blah]
10
+
11
+ set -e # Exit on error
12
+ #------------------------------------------------------------------------------
13
+ # Make sure we know exactly where the real script is so we can run from
14
+ # anywhere. (follows sym-links etc.)
15
+ SCRIPT_PATH="${BASH_SOURCE[0]}";
16
+ if [ -h "${SCRIPT_PATH}" ]; then
17
+ while([ -h "${SCRIPT_PATH}" ]) do
18
+ if [[ `uname -s` == 'Darwin' ]]; then
19
+ SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`
20
+ else
21
+ SCRIPT_PATH=`readlink -f "${SCRIPT_PATH}"`
22
+ fi
23
+ done
24
+ fi
25
+ pushd . > /dev/null
26
+ cd `dirname ${SCRIPT_PATH}` > /dev/null
27
+ SCRIPT_PATH=`pwd`;
28
+ popd > /dev/null
29
+ #------------------------------------------------------------------------------
30
+
31
+ RAKEFILE="${SCRIPT_PATH}/Rakefile" # Explicit to this Rakefile
32
+
33
+ pushd . > /dev/null # Save cwd & go to that rakefile's directory
34
+ cd "${SCRIPT_PATH}"
35
+
36
+ task=`basename ${BASH_SOURCE[0]}`
37
+ if [[ "$#" > 0 ]]; then
38
+ worker_env=$1
39
+ shift
40
+ else
41
+ worker_env=development
42
+ fi
43
+ WORKER_ENV=$worker_env rake --nosearch -f "${RAKEFILE}" ${task}[$@]
44
+ popd > /dev/null # Restore old cwd
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ # Just a fancy way to run rake against exactly the right Rakefile, with a
3
+ # default WORKER_ENV always of development, and more easily pass in
4
+ # command-line parameters to the task, etc. Meant to be symlinked to.
5
+ #
6
+ # ex:
7
+ # $ do-something production blah
8
+ # (becomes, more or less)
9
+ # $ WORKER_ENV=production rake do-something[blah]
10
+
11
+ set -e # Exit on error
12
+ #------------------------------------------------------------------------------
13
+ # Make sure we know exactly where the real script is so we can run from
14
+ # anywhere. (follows sym-links etc.)
15
+ SCRIPT_PATH="${BASH_SOURCE[0]}";
16
+ if [ -h "${SCRIPT_PATH}" ]; then
17
+ while([ -h "${SCRIPT_PATH}" ]) do
18
+ if [[ `uname -s` == 'Darwin' ]]; then
19
+ SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`
20
+ else
21
+ SCRIPT_PATH=`readlink -f "${SCRIPT_PATH}"`
22
+ fi
23
+ done
24
+ fi
25
+ pushd . > /dev/null
26
+ cd `dirname ${SCRIPT_PATH}` > /dev/null
27
+ SCRIPT_PATH=`pwd`;
28
+ popd > /dev/null
29
+ #------------------------------------------------------------------------------
30
+
31
+ RAKEFILE="${SCRIPT_PATH}/Rakefile" # Explicit to this Rakefile
32
+
33
+ pushd . > /dev/null # Save cwd & go to that rakefile's directory
34
+ cd "${SCRIPT_PATH}"
35
+
36
+ task=`basename ${BASH_SOURCE[0]}`
37
+ if [[ "$#" > 0 ]]; then
38
+ worker_env=$1
39
+ shift
40
+ else
41
+ worker_env=development
42
+ fi
43
+ WORKER_ENV=$worker_env rake --nosearch -f "${RAKEFILE}" ${task}[$@]
44
+ popd > /dev/null # Restore old cwd
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ # Just a fancy way to run rake against exactly the right Rakefile, with a
3
+ # default WORKER_ENV always of development, and more easily pass in
4
+ # command-line parameters to the task, etc. Meant to be symlinked to.
5
+ #
6
+ # ex:
7
+ # $ do-something production blah
8
+ # (becomes, more or less)
9
+ # $ WORKER_ENV=production rake do-something[blah]
10
+
11
+ set -e # Exit on error
12
+ #------------------------------------------------------------------------------
13
+ # Make sure we know exactly where the real script is so we can run from
14
+ # anywhere. (follows sym-links etc.)
15
+ SCRIPT_PATH="${BASH_SOURCE[0]}";
16
+ if [ -h "${SCRIPT_PATH}" ]; then
17
+ while([ -h "${SCRIPT_PATH}" ]) do
18
+ if [[ `uname -s` == 'Darwin' ]]; then
19
+ SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`
20
+ else
21
+ SCRIPT_PATH=`readlink -f "${SCRIPT_PATH}"`
22
+ fi
23
+ done
24
+ fi
25
+ pushd . > /dev/null
26
+ cd `dirname ${SCRIPT_PATH}` > /dev/null
27
+ SCRIPT_PATH=`pwd`;
28
+ popd > /dev/null
29
+ #------------------------------------------------------------------------------
30
+
31
+ RAKEFILE="${SCRIPT_PATH}/Rakefile" # Explicit to this Rakefile
32
+
33
+ pushd . > /dev/null # Save cwd & go to that rakefile's directory
34
+ cd "${SCRIPT_PATH}"
35
+
36
+ task=`basename ${BASH_SOURCE[0]}`
37
+ if [[ "$#" > 0 ]]; then
38
+ worker_env=$1
39
+ shift
40
+ else
41
+ worker_env=development
42
+ fi
43
+ WORKER_ENV=$worker_env rake --nosearch -f "${RAKEFILE}" ${task}[$@]
44
+ popd > /dev/null # Restore old cwd
@@ -0,0 +1,22 @@
1
+ #/usr/bin/env bash
2
+
3
+ # TODO:
4
+ # - cd()
5
+ # - adjust prompt
6
+ # - autocomplete
7
+
8
+ export VIRTUAL_ENV_DISABLE_PROMPT=true
9
+
10
+
11
+ function __worker_ps1() {
12
+ rnd=`od -N1 -A n -b /dev/random`
13
+ worker_type="gamer_transcode"${rnd/ /}
14
+ worker_env="d"
15
+ status="c"
16
+ printf "${1:-(%s/%s/%s)}" "$worker_type" "$worker_env" "$status"
17
+ }
18
+
19
+
20
+
21
+ __WORKER_PS1='$(__worker_ps1)'"$PS1"
22
+ PS1=$__WORKER_PS1
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+ gem "god", "~> 0.11.0"
3
+
4
+ # Development dependencies
5
+ # Including everything needed to run rake, tests, features, etc.
6
+ group :development do
7
+ gem "minitest", ">= 0"
8
+ gem "yard", "~> 0.6.0"
9
+ gem "bundler", "~> 1.0.0"
10
+ gem "jeweler", "~> 1.6.4"
11
+ gem "rcov", ">= 0"
12
+ end
@@ -0,0 +1,24 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ god (0.11.0)
6
+ jeweler (1.6.4)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ minitest (2.5.1)
11
+ rake (0.9.2)
12
+ rcov (0.9.10)
13
+ yard (0.6.8)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ bundler (~> 1.0.0)
20
+ god (~> 0.11.0)
21
+ jeweler (~> 1.6.4)
22
+ minitest
23
+ rcov
24
+ yard (~> 0.6.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Joseph Wecker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,166 @@
1
+ = metacon
2
+ === (i.e., metacontroller)
3
+ At the moment a very specialized ruby gem for some justin.tv / twitch.tv
4
+ development work but might be more generalizable later. For controlling a
5
+ complex project repository. (Where controlling = developing, deploying,
6
+ running/supervising, branching, aggregating, etc.)
7
+
8
+ == Description
9
+ === Context: A random walk through changing your project environment
10
+ (while iterating/working on a single project, using mostly ruby and python as
11
+ examples)
12
+
13
+ ==== - rails, etc.
14
+ Rails (etc.) has the concept of environments - set by the RAILS_ENV environment
15
+ variable. When you set it to development or production etc. it starts up
16
+ servers and consoles differently - different configuration variables and
17
+ initialization scripts etc.
18
+
19
+ ==== - rvm, pythonbrew, etc.
20
+ Often one adds a .rvmrc to the root directory to control the ruby version and
21
+ keep the local gem repository pristine (which helps it avoid any conflicts with
22
+ other rails projects etc.). Tools like pythonbrew allow for the same thing with
23
+ python - using environment variables and some easy commands you can have easy
24
+ control over virtualenv for installed python modules and even custom
25
+ non-conflicting versions of python.
26
+
27
+ ==== - bundler, pip-requirements, etc.
28
+ A quick way to specify gems / python-modules including specific versions that
29
+ this project depends on. Especially useful when combined with rvm/pythonbrew,
30
+ etc. Usually before you're allowed to run anything like test servers it'll
31
+ check to make sure the environment has the dependencies and tell you to install
32
+ them if not.
33
+
34
+
35
+ ==== - git branches and submodules
36
+ Obviously changing your scm branch very quickly and automatically changes the
37
+ files in your project. Thus you can quickly switch between "topical" branches,
38
+ bug-fix branches, authoritative branches, etc.
39
+
40
+ Submodules offer an aggregation method for more complex projects that depend on
41
+ separate git repositories. These allow you to:
42
+ 1. Modify the submodule's code at the same time you're iterating on the project that uses it - so especially useful if you want greater modularization of code that you're working on.
43
+ 2. Have your repository/branch "pointing" to a specific commit of the submodule. This gives you a kind of very fine-grained dependency control. You could have a feature branch pointing to a newer commit of a submodule (which could be a local clone of any git repository whether you have "push" access or not) - and thus just by switching branches you're also changing the version of the submodules you're depending on.
44
+
45
+ ==== - development vs. server-env: deployment
46
+ (i.e., capistrano, fabric, etc. etc.)
47
+
48
+ Deployment is essentially a slightly more complex way of adjusting the project
49
+ for a (sometimes very) different environment... Sometimes very different, yet
50
+ often the most important- the one you're targeting in the first place...
51
+
52
+ Included here are continuous deployment tools (we use Brigade internally at
53
+ Justin tv, written by Emmett Shear [and modified by several employees]. It
54
+ rocks. One day it will be opensourced) and things as simple as scripts that
55
+ do a git-push to servers and issue a SIGHUP.
56
+
57
+ ==== - puppet
58
+ Then there's good ol' puppet. In big systems it's often used to declaratively
59
+ say what software is required on what machines (and it figures out how to get
60
+ them installed in the most appropriate manner for that OS/configuration) and
61
+ sometimes even how to startup and supervise processes on those machines. I have
62
+ to include it here because there's a bunch of stuff that metacon does that we
63
+ have done w/ puppet in the past, plus it's declarative nature is a very, very
64
+ good standard for any similar tools to aspire to. Metacon cannot replace
65
+ puppet- just some stuff that people are sometimes driven to hijack puppet to do
66
+ for them. (that's pretty much true of all tools listed above).
67
+
68
+ === Description (finally)
69
+ _metacon_ is for easily organizing and developing any project that may consist
70
+ of multiple:
71
+ - runtime environments (development/staging/production/testing...)
72
+ - os environments (mac and linux)
73
+ - specific-machine environments (server82 vs cluster3)
74
+ - roles (possibly no one else may need this- when a project can run as
75
+ different roles / essentially multiple different projects combined into one)
76
+
77
+ and that needs to be easily developed, integrated, and deployed without
78
+ interuption of existing services. Or, stated differently, the goals as follows.
79
+
80
+ (Aside, Quick redefinition of 'environment')
81
+
82
+ Since I keep using the term, when I say "environment" I'm not referring here to
83
+ the normal bash/shell environment. I'm referring specifically to the
84
+ combination above: runtime-context & os & machine & role
85
+
86
+ ==== 1. Develop against the environment union, abstract out divergences
87
+ Develop for the different environment combinations at the same time - with the
88
+ assumption that much of the development is not environment sensitive or that
89
+ the environment-sensitive parts can be factored away. Easily abstract the
90
+ environment stuff away.
91
+
92
+ ==== 2. Easy way to run/iterate in isolated environments.
93
+
94
+ Keep them ISOLATED - so if you wanted to pristinely run several different
95
+ projects on a server with different needs as far as ruby/python versions and
96
+ packages, binary dependencies, etc., you can (up to a point). Stated another
97
+ way- take the isolation and orthoganality that something like RAILS_ENV /
98
+ .rvmrc provide and extend it pretty much automatically to the following:
99
+
100
+ - Ruby version/build
101
+ - Ruby gems / packages
102
+ - Python version/build
103
+ - Python modules / packages
104
+ - Anything you can have as a git submodule including but not limited to:
105
+ - More ruby or python packages that you iterate on or deploy with where the
106
+ version/branch may change.
107
+ - Patched or internally developed code that would normally be compiled and
108
+ installed globally on the target machine.
109
+ - Other projects that represent loose dependencies that may be getting work
110
+ done on them orthogonally to this repo (yes, that's mostly a restatement of
111
+ the last item).
112
+ - Supervisor processes / running contexts
113
+
114
+ Extending it further. So, you may wonder, why not just go "all the way" and
115
+ actually completely change your PATH or segregate by user or even have
116
+ virtual-machines or something? Because, at least with current technologies,
117
+ that would violate goal #1 and goal #3.
118
+
119
+ ==== 3. Fast environment switching
120
+ Very fast switching between the environments and even running certain tasks on
121
+ environments concurrently within the current file and change-set context. In
122
+ other words, I modify a script and can immediately test it against my "staging"
123
+ and "test" environments for my "responder" role. Switching ideally
124
+ instantaneous, at least after the first time in that environment (when lots of
125
+ downloading / installing needs to happen).
126
+
127
+ ==== RESULTS EXPECTED
128
+ * *Developer-Platform-Agnosticism*. That is, a large degree of cross-platform
129
+ commutativity: develop on mac, deploy on linux, etc.
130
+ * *Easy-Continual-Integration*. Dependency conflicts - even needing a
131
+ different binary usually installed on the target, is revealed in such a way
132
+ that is very easy to resolve.
133
+ * *Easy-Continual-Deployment*. Environmental concerns built in and coded
134
+ against from the beginning with very little pain. Complex projects that are
135
+ already huge and complex and in desparate need of continual deployment should
136
+ be able to migrate to metacon easily and enjoy all the benefits. (This is why
137
+ we needed it).
138
+ * *Easy-Scaling*. At least at the meta level. Application-specific scaling
139
+ concerns are of course your problem, but at least with metacon it's easy to
140
+ say "this worker needs to use 4 processors on servers 70 - 94, but only one
141
+ processor when running on my ancient netbook."
142
+
143
+
144
+ * Main goal in the end is *Fast/Agile-Development* on complex projects that are
145
+ aggregates of several projects.
146
+
147
+
148
+ == Contributing to metacon
149
+
150
+ * Check out the latest master to make sure the feature hasn't been implemented
151
+ or the bug hasn't been fixed yet Check out the issue tracker to make sure
152
+ someone already hasn't requested it and/or contributed it
153
+ * Fork the project
154
+ * Start a feature/bugfix branch
155
+ * Commit and push until you are happy with your contribution
156
+ * Make sure to add tests for it. This is important so I don't break it in a
157
+ future version unintentionally.
158
+ * Please try not to mess with the Rakefile, version, or history. If you want to
159
+ have your own version, or is otherwise necessary, that is fine, but please
160
+ isolate to its own commit so I can cherry-pick around it.
161
+
162
+ == License
163
+
164
+ MIT License.
165
+ Copyright (c) 2011 Joseph Wecker.
166
+ See LICENSE.txt for further details.
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = 'metacon'
18
+ gem.homepage = 'http://github.com/josephwecker/metacon'
19
+ gem.license = 'MIT'
20
+ gem.summary = %Q{Metacontroller for organizing aggregate projects}
21
+ gem.description = %Q{Tool with some similarities to puppet but specializing in fast development iteration and continuous deployment. Specifically initially for use with justin.tv / twitch.tv project clusters.}
22
+ gem.email = 'jwecker@justin.tv'
23
+ gem.authors = ['Joseph Wecker']
24
+ gem.requirements << 'git, v1.7.4.1 or greater'
25
+ gem.requirements << 'rvm, v1.8.2 or greater'
26
+ gem.requirements << 'pythonbrew, v1.1 or greater'
27
+
28
+ gem.post_install_message = "\n\n\e[1;32m\e[40m--- Please run \e[1;37mmetacon-install\e[1;32m to check dependencies & finish the installation --- \e[0m\n\n"
29
+ # dependencies defined in Gemfile
30
+ end
31
+ Jeweler::RubygemsDotOrgTasks.new
32
+
33
+ require 'rake/testtask'
34
+ Rake::TestTask.new(:test) do |test|
35
+ test.libs << 'lib' << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ end
39
+
40
+ require 'rcov/rcovtask'
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/test_*.rb'
44
+ test.verbose = true
45
+ test.rcov_opts << '--exclude "gems/*"'
46
+ end
47
+
48
+ task :default => :test
49
+
50
+ require 'yard'
51
+ YARD::Rake::YardocTask.new
data/TODO.md ADDED
@@ -0,0 +1,44 @@
1
+
2
+
3
+ # Installation
4
+ (gem -> basic libraries used by commands)
5
+ (installer ->
6
+ - Basic install-script (similar to rvm installation procedure)
7
+ - Install/ensure dependencies
8
+ - git
9
+ - rvm
10
+ - god
11
+ - pythonbrew
12
+ - Install shell shim
13
+
14
+ # Components
15
+ ## General Commandline
16
+ - Figure out how to load various dependency tools?
17
+ ## Commands
18
+ - st / stat -> environment + versions of dependencies, state of submodules,
19
+ current git state, running state, etc.
20
+ - env [-l[ist] || new\_env]
21
+ - role [-l[ist] || new\_role]
22
+ - machine [-l[ist] || impersonate\_machine]
23
+ - os (shows current only?)
24
+ - br / branch [...] -> alias for git-branch so its clear it's an intergral part of
25
+ the current operating environment
26
+
27
+ - run/start [@as-options] [cmd...options...]
28
+ - stop
29
+ - restart (gracefully)
30
+ - hard-restart (ungracefully)
31
+ - test (starts supervisord in non-daemon mode if it's not already running for
32
+ additional feedback)
33
+
34
+ ## Config
35
+ - Allow a ~/.metacon-config for filling in general things not specified in
36
+ project directory.
37
+ - project.config > home.config > default.config
38
+ - Make sure there is general (sane) config stuff for supervisord
39
+
40
+ ## Shell Prompt (PS1) for Bash/ZSH
41
+
42
+ ## Autocomplete
43
+
44
+