bork 0.1.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/.gitignore +17 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/bin/bork +10 -0
- data/bork.gemspec +21 -0
- data/lib/bork.rb +61 -0
- data/lib/bork/cli.rb +33 -0
- data/lib/bork/core/array.rb +17 -0
- data/lib/bork/environment.rb +52 -0
- data/lib/bork/errors.rb +4 -0
- data/lib/bork/server.rb +115 -0
- data/lib/bork/version.rb +3 -0
- data/templates/config/bork.rb.erb +39 -0
- metadata +110 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create 1.9.3@bork
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Corey Woodcox
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Bork
|
2
|
+
|
3
|
+
Bork bork bork! For server management so simple, even [this guy](http://youtu.be/B7UmUX68KtE) can do it.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'bork'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install bork
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Okay, nothing really works at all. I take pull requests!
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/bork
ADDED
data/bork.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/bork/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Corey Woodcox"]
|
6
|
+
gem.email = ["corey.woodcox@gmail.com"]
|
7
|
+
gem.description = %q{Bork is my attempt at server bootstrapping.}
|
8
|
+
gem.summary = %q{Maybe one day it will be cooler.}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "bork"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Bork::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'thor', '~>0.14'
|
19
|
+
gem.add_dependency 'fog', '~>1.3.0'
|
20
|
+
gem.add_dependency 'net-ssh', '~>2.3.0'
|
21
|
+
end
|
data/lib/bork.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'bork/version'
|
2
|
+
require 'bork/core/array'
|
3
|
+
require 'bork/errors'
|
4
|
+
require 'logger'
|
5
|
+
require 'fog'
|
6
|
+
|
7
|
+
module Bork
|
8
|
+
class << self
|
9
|
+
attr_reader :environments
|
10
|
+
|
11
|
+
Fog.credentials[:public_key_path] = "~/.ssh/id_rsa.pub"
|
12
|
+
|
13
|
+
def logger
|
14
|
+
return @logger if @logger
|
15
|
+
@logger = ::Logger.new(STDOUT)
|
16
|
+
@logger.level = ::Logger::INFO
|
17
|
+
@logger
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure(&block)
|
21
|
+
@environments = {}
|
22
|
+
instance_eval &block
|
23
|
+
end
|
24
|
+
|
25
|
+
def application(*args)
|
26
|
+
return @application unless args.length > 0
|
27
|
+
options = args.extract_options!
|
28
|
+
@application = args.first
|
29
|
+
end
|
30
|
+
|
31
|
+
def environment(name, &block)
|
32
|
+
require 'bork/environment'
|
33
|
+
|
34
|
+
@environments[name.to_sym] = Bork::Environment.new(name.to_sym, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def provider(*args)
|
38
|
+
return @provider unless args.length > 1
|
39
|
+
options = args.extract_options!
|
40
|
+
@provider = Fog::Compute.new(options.merge(:provider => args.first))
|
41
|
+
end
|
42
|
+
|
43
|
+
def bootstrap!
|
44
|
+
@environments.each do |name,env|
|
45
|
+
env.build!
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def restore!
|
50
|
+
@environments.each do |name,env|
|
51
|
+
env.restore!
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def setup!
|
56
|
+
@environments.each do |name,env|
|
57
|
+
env.setup!
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/bork/cli.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Bork
|
4
|
+
class CLI < Thor
|
5
|
+
include Thor::Actions
|
6
|
+
check_unknown_options!
|
7
|
+
|
8
|
+
source_root File.join(File.dirname(__FILE__), '..', '..', 'templates')
|
9
|
+
|
10
|
+
desc "init", "Create a bork configuration in the current project/directory"
|
11
|
+
def init
|
12
|
+
empty_directory "config"
|
13
|
+
template "config/bork.rb.erb", "config/bork.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "bootstrap", "Read the bork file and fire up some servers."
|
17
|
+
def bootstrap
|
18
|
+
load_config
|
19
|
+
Bork.bootstrap!
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "setup", "Start up the servers if they don't exist and set up the softwares"
|
23
|
+
def setup
|
24
|
+
load_config
|
25
|
+
Bork.setup!
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def load_config
|
30
|
+
load "#{Dir.pwd}/config/bork.rb"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Bork
|
2
|
+
class Environment
|
3
|
+
attr_accessor :servers, :name
|
4
|
+
|
5
|
+
def initialize(name, *options, &block)
|
6
|
+
@name = name.to_sym
|
7
|
+
@servers = {}
|
8
|
+
|
9
|
+
instance_eval &block
|
10
|
+
end
|
11
|
+
|
12
|
+
# DSL Method
|
13
|
+
def server(role, &block)
|
14
|
+
require 'bork/server'
|
15
|
+
|
16
|
+
@servers[role] = Bork::Server.new(role, :environment => self, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def build!
|
20
|
+
@servers.each do |role,server|
|
21
|
+
server.bootstrap!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def restore!
|
26
|
+
link_provider
|
27
|
+
@servers.select { |role,server| !server.linked? }.each do |role,server|
|
28
|
+
raise Bork::ServerNotFoundError
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup!
|
33
|
+
link_provider
|
34
|
+
@servers.select { |role,server| !server.linked? }.each do |role,server|
|
35
|
+
Bork.logger.info(role.to_s) { "Existing instance not found, bootstrapping" }
|
36
|
+
server.bootstrap!
|
37
|
+
end
|
38
|
+
|
39
|
+
@servers.each do |role, server|
|
40
|
+
server.setup!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def link_provider
|
46
|
+
@servers.each do |role,server|
|
47
|
+
Bork.logger.info(role.to_s) { "Searching Rackspace for existing instance" }
|
48
|
+
server.instance
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/bork/errors.rb
ADDED
data/lib/bork/server.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
module Bork
|
2
|
+
class Server
|
3
|
+
attr_accessor :name, :role, :image_id, :flavor_id, :packages, :environment, :metadata
|
4
|
+
|
5
|
+
def initialize(role, *options, &block)
|
6
|
+
options = options.extract_options!
|
7
|
+
|
8
|
+
@role = role.to_sym
|
9
|
+
@packages = %w( build-essential zlib1g-dev libpcre3-dev git-core libxml2-dev libxslt-dev openssl libssl-dev curl )
|
10
|
+
@after_install = []
|
11
|
+
|
12
|
+
@environment = options.delete(:environment)
|
13
|
+
@name = "#{@environment.name}.#{@role}.#{Bork.application}.saxtonhorne.net" # TODO: Don't do this.
|
14
|
+
|
15
|
+
@metadata = {
|
16
|
+
'application' => Bork.application,
|
17
|
+
'role' => role.to_s,
|
18
|
+
'environment' => environment.name.to_s
|
19
|
+
}
|
20
|
+
|
21
|
+
if block.arity == 1
|
22
|
+
block[self]
|
23
|
+
else
|
24
|
+
instance_eval &block
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def image(id)
|
29
|
+
@image_id = id.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
def flavor(id)
|
33
|
+
@flavor_id = id.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def packages(package_list)
|
37
|
+
@packages += package_list
|
38
|
+
end
|
39
|
+
|
40
|
+
def after_install(*args)
|
41
|
+
options = args.extract_options!
|
42
|
+
return @after_install if args.length == 0
|
43
|
+
|
44
|
+
args.each do |arg|
|
45
|
+
arg.split("\n").each do |cmd|
|
46
|
+
@after_install << cmd.strip
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
def bootstrap!
|
51
|
+
@instance = do_bootstrap # We're providing our own bootstrap because I want some reporting
|
52
|
+
@linked = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def linked?
|
56
|
+
@linked
|
57
|
+
end
|
58
|
+
|
59
|
+
def instance
|
60
|
+
return @instance if linked?
|
61
|
+
@linked = false
|
62
|
+
|
63
|
+
@instance = Bork.provider.servers.find do |server|
|
64
|
+
@linked = true if server.metadata == metadata
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def install_packages
|
69
|
+
log "Updating apt"
|
70
|
+
instance.ssh('apt-get -qq update')
|
71
|
+
|
72
|
+
log "Installing packages"
|
73
|
+
instance.ssh("apt-get -qqy install #{@packages.join(" ")}")
|
74
|
+
end
|
75
|
+
|
76
|
+
def setup!
|
77
|
+
install_packages
|
78
|
+
log "Running post-install hooks"
|
79
|
+
|
80
|
+
@after_install.each do |cmd|
|
81
|
+
log cmd
|
82
|
+
instance.ssh cmd do |output|
|
83
|
+
log output
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
private
|
88
|
+
def do_bootstrap
|
89
|
+
log "Creating server"
|
90
|
+
server = Bork.provider.servers.create(to_params)
|
91
|
+
|
92
|
+
log "Waiting for server to become ready"
|
93
|
+
server.wait_for { ready? }
|
94
|
+
|
95
|
+
log "Setting up keypairs and stuff"
|
96
|
+
server.setup(:password => server.password)
|
97
|
+
|
98
|
+
log "Bootstrapped!"
|
99
|
+
server
|
100
|
+
end
|
101
|
+
|
102
|
+
def log(message)
|
103
|
+
Bork.logger.info(role) { message }
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_params
|
107
|
+
{
|
108
|
+
:name => name,
|
109
|
+
:image_id => image_id,
|
110
|
+
:flavor_id => flavor_id,
|
111
|
+
:metadata => metadata
|
112
|
+
}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/bork/version.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'bork'
|
2
|
+
|
3
|
+
# This is the config file for bork, which will set up a bunch of cloud instances and
|
4
|
+
# install crap on them to make them useful for hosting apps and crap. Maybe one day it
|
5
|
+
# will be useful for more than me.
|
6
|
+
|
7
|
+
# Define your servers here. Example follows
|
8
|
+
# Bork.configure do
|
9
|
+
# application 'myapp'
|
10
|
+
# provider :rackspace, :rackspace_api_key => 'YOUR_API_KEY', :rackspace_username => 'YOUR_USERNAME'
|
11
|
+
|
12
|
+
# environment :staging do
|
13
|
+
# server :app do
|
14
|
+
# image 119
|
15
|
+
# flavor 2
|
16
|
+
|
17
|
+
# packages %w( nginx-common mysql-client libmysqlclient-dev nodejs-dev libsqlite3-dev )
|
18
|
+
# after_install %q(curl http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz | tar -xz
|
19
|
+
# sh -c "cd yaml-0.1.4 && ./configure --prefix=/usr/local && make && make install")
|
20
|
+
|
21
|
+
# after_install %q(curl http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p0.tar.gz | tar -xz
|
22
|
+
# sh -c "cd ruby-1.9.3-p0 && ./configure --disable-install-doc && make && make install"
|
23
|
+
# gem install bundler --no-rdoc --no-ri)
|
24
|
+
|
25
|
+
# after_install %q(useradd -mUG www-data,sudo deploy
|
26
|
+
# cp -R ~/.ssh/ /home/deploy/
|
27
|
+
# chown -R deploy:deploy /home/deploy
|
28
|
+
# chmod -R 0700 /home/deploy/.ssh)
|
29
|
+
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
|
33
|
+
# environment :production do
|
34
|
+
# server :app do
|
35
|
+
# image_id 119
|
36
|
+
# flavor_id 2
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bork
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Corey Woodcox
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.14'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.14'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: fog
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.3.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.3.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: net-ssh
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.3.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.3.0
|
62
|
+
description: Bork is my attempt at server bootstrapping.
|
63
|
+
email:
|
64
|
+
- corey.woodcox@gmail.com
|
65
|
+
executables:
|
66
|
+
- bork
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- .rvmrc
|
72
|
+
- Gemfile
|
73
|
+
- LICENSE
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- bin/bork
|
77
|
+
- bork.gemspec
|
78
|
+
- lib/bork.rb
|
79
|
+
- lib/bork/cli.rb
|
80
|
+
- lib/bork/core/array.rb
|
81
|
+
- lib/bork/environment.rb
|
82
|
+
- lib/bork/errors.rb
|
83
|
+
- lib/bork/server.rb
|
84
|
+
- lib/bork/version.rb
|
85
|
+
- templates/config/bork.rb.erb
|
86
|
+
homepage: ''
|
87
|
+
licenses: []
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 1.8.24
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Maybe one day it will be cooler.
|
110
|
+
test_files: []
|