front 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +87 -0
- data/Rakefile +1 -0
- data/Vagrantfile +3 -0
- data/bin/front +10 -0
- data/front.gemspec +23 -0
- data/lib/front/cli/app.rb +16 -0
- data/lib/front/cli/configuration.rb +75 -0
- data/lib/front/cli/controller.rb +81 -0
- data/lib/front/cli/front_file.rb +51 -0
- data/lib/front/cli/router.rb +12 -0
- data/lib/front/cli/script.rb +38 -0
- data/lib/front/cli/vagrant.rb +125 -0
- data/lib/front/cli/vagrant_pool.rb +193 -0
- data/lib/front/loader.rb +7 -0
- data/lib/front/version.rb +3 -0
- data/lib/front.rb +5 -0
- data/portkey.json +11 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MzAwNTk0OTg0MWE0NjA3YTVhMzM3MmU5ZDVlMTk0OTI5ZTEwODQzMw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YmNlMWMwNDY4MmMxZGUwYzQxNTQzY2YxNzBjMzMzM2M3ODA1NDdmMA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTY0NWZlNzFmNjJmMGIzOGE0MmUwNjU1ZGE1YjZhNzQ0MTExMGVlMWU2ZjZh
|
10
|
+
YjVhOTk0ODliNTlmNWU2OGE0OThhMWVhNjYyZTgzMTgxY2I3YTFmNTRjMTFj
|
11
|
+
YjVjODc5NDU5MGYzZDQ4YmM5NTNlNmZiOTYxMmJkNGY1NzI4ODQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
M2JlZDEzZTMyYmJhMmEyM2QxNGY3ZGNiODlmOTg5NjdkMzgwYTIzNDFhODQx
|
14
|
+
NzRiMzRiNDEyNDBiMTgzODU3ZmQxMmZhYzU3YTBmYjc3NzQ3NTUwYTM3Njg3
|
15
|
+
MjU4YjViZGM1YzIzZDE5NTUzMzdmMzEzNDFjNTY0MzNhMDdlMGM=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Darshan Sawardekar
|
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,87 @@
|
|
1
|
+
# Front
|
2
|
+
|
3
|
+
### Speed up your Vagrant workflow
|
4
|
+
|
5
|
+
Booting up a fresh virtual machine takes time. `Front` speeds up VM boot
|
6
|
+
time by preinitializing a pool of VMs. When you need a fresh instance,
|
7
|
+
use `front next` and you are ready to work instantly. And while you work
|
8
|
+
it rebuilds the old VM for your next refill!
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Install with rubygems:
|
13
|
+
|
14
|
+
$ gem install front
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
When starting a work session, create a new Vagrantfile for your project.
|
19
|
+
Then create a new pool with `create`. Without an inventory file, front
|
20
|
+
uses a default Vagrantfile with a Ubuntu `precise64` box.
|
21
|
+
|
22
|
+
$ front create
|
23
|
+
|
24
|
+
As soon as the 1st VM is ready control is returned to you while the
|
25
|
+
other instances in the pool are being preloaded. You can now login to
|
26
|
+
this VM with,
|
27
|
+
|
28
|
+
$ front ssh
|
29
|
+
|
30
|
+
After you are done with this instance, and need a fresh one, you can
|
31
|
+
fetch it with `front next`.
|
32
|
+
|
33
|
+
$ front next
|
34
|
+
|
35
|
+
An inventory file is maintained with the SSH port every time you switch
|
36
|
+
instances. This can be accessed with the `inventory` action.
|
37
|
+
|
38
|
+
$ front inventory
|
39
|
+
|
40
|
+
Finally when done, dispose of the pool with the `destroy` action.
|
41
|
+
|
42
|
+
$ front destroy
|
43
|
+
|
44
|
+
## Implementation
|
45
|
+
|
46
|
+
`Front` clones your project Vagrantfile into a `.front` directory
|
47
|
+
containing the virtual machine instances. When you access the
|
48
|
+
`front` commands it steps into these subdirectories and calls the
|
49
|
+
corresponding vagrant command. Most actions run in the background
|
50
|
+
allowing you to continue working while they complete.
|
51
|
+
|
52
|
+
## Complete Usage
|
53
|
+
|
54
|
+
$ front [options] [action]
|
55
|
+
|
56
|
+
Actions
|
57
|
+
create : create a new pool
|
58
|
+
destroy : destroy pool
|
59
|
+
next : switch to next instance in pool
|
60
|
+
ssh : ssh to current instance => vagrant ssh
|
61
|
+
ssh_config : print ssh config for current instance
|
62
|
+
inventory : print inventory file
|
63
|
+
|
64
|
+
Options
|
65
|
+
|
66
|
+
-s, --size <size> Size of instance pool
|
67
|
+
-V, --version Print Front version
|
68
|
+
-h, --help Print Front help
|
69
|
+
|
70
|
+
## Caveats
|
71
|
+
|
72
|
+
* Running multiple VMs requires a fast computer with lots of RAM.
|
73
|
+
The actual amount depends on the number of VMs, and their configuration.
|
74
|
+
Eg:- For a Ubuntu box with 512MB ram with a pool of size 4, you need
|
75
|
+
at least 2GB for Virtual Box. Plus additional RAM for the host system.
|
76
|
+
* Default pool size is 2.
|
77
|
+
|
78
|
+
## TODO
|
79
|
+
|
80
|
+
* Needs to handle Vagrant errors better.
|
81
|
+
* Pool size once created should be persistent.
|
82
|
+
* If an instance isn't ready should be able to show it's status.
|
83
|
+
* Allow running of other vagrant subcommands
|
84
|
+
|
85
|
+
## Contributing
|
86
|
+
|
87
|
+
* This project uses the gitflow branching model. PR's go against `develop`.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/Vagrantfile
ADDED
data/bin/front
ADDED
data/front.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'front/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "front"
|
8
|
+
spec.version = Front::VERSION
|
9
|
+
spec.authors = ["Darshan Sawardekar"]
|
10
|
+
spec.email = ["darshan@sawardekar.org"]
|
11
|
+
spec.description = %q{Speed up your Vagrant workflow}
|
12
|
+
spec.summary = %q{Booting up a fresh virtual machine takes time. `Front` speeds up VM boot time by preinitializing a pool of VMs. When you need a fresh instance, use `front next` and you are ready to work instantly. And while you work it rebuilds the old VM for your next refill!}
|
13
|
+
spec.homepage = "https://github.com/dsawardekar/front"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Front
|
2
|
+
module CLI
|
3
|
+
require_relative 'configuration'
|
4
|
+
require_relative 'router'
|
5
|
+
|
6
|
+
class App
|
7
|
+
def start(args)
|
8
|
+
config = Configuration.new
|
9
|
+
options = config.load(args)
|
10
|
+
|
11
|
+
router = Router.new
|
12
|
+
router.route(options)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Front
|
2
|
+
module CLI
|
3
|
+
require 'optparse'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
class Configuration
|
7
|
+
include Loader
|
8
|
+
|
9
|
+
def load(args)
|
10
|
+
options = OpenStruct.new
|
11
|
+
options.action = nil
|
12
|
+
options.error = nil
|
13
|
+
options.pool_size = 2
|
14
|
+
|
15
|
+
parse(args, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_parser(args, options)
|
19
|
+
OptionParser.new do |opts|
|
20
|
+
options.opts = opts
|
21
|
+
opts.banner = 'Usage: front [options] [action]'
|
22
|
+
opts.separator ''
|
23
|
+
opts.separator 'Actions'
|
24
|
+
opts.separator ' create : create a new pool'
|
25
|
+
opts.separator ' destroy : destroy pool'
|
26
|
+
opts.separator ' next : switch to next instance in pool'
|
27
|
+
opts.separator ' ssh : ssh to current instance => vagrant ssh'
|
28
|
+
opts.separator ' ssh_config : print ssh config for current instance'
|
29
|
+
opts.separator ' inventory : print inventory file (for ansible)'
|
30
|
+
opts.separator ''
|
31
|
+
opts.separator 'Options'
|
32
|
+
opts.separator ''
|
33
|
+
|
34
|
+
opts.on('-s', '--size <size>', Integer, 'Size of instance pool') do |pool_size|
|
35
|
+
options.pool_size = pool_size
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on_tail('-V', '--version', 'Print Front version') do
|
39
|
+
options.action = :show_version
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on_tail('-h', '--help', 'Print Front help') do
|
43
|
+
options.action = :show_help
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse(args, options)
|
49
|
+
parser = get_parser(args, options)
|
50
|
+
|
51
|
+
begin
|
52
|
+
parser.parse!(args)
|
53
|
+
if options.action.nil?
|
54
|
+
if args.length == 1
|
55
|
+
options.action = args[0]
|
56
|
+
else
|
57
|
+
raise OptionParser::InvalidOption.new(args)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
rescue OptionParser::InvalidOption => err
|
61
|
+
options.error = err
|
62
|
+
options.action = :show_invalid_option
|
63
|
+
rescue OptionParser::MissingArgument => err
|
64
|
+
options.error = err
|
65
|
+
options.action = :show_missing_args
|
66
|
+
rescue OptionParser::ParseError => err
|
67
|
+
options.error = err
|
68
|
+
options.action = :show_parser_error
|
69
|
+
end
|
70
|
+
|
71
|
+
options
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Front
|
2
|
+
module CLI
|
3
|
+
require 'front/version'
|
4
|
+
require 'front/loader'
|
5
|
+
require_relative 'vagrant'
|
6
|
+
require_relative 'vagrant_pool'
|
7
|
+
|
8
|
+
class Controller
|
9
|
+
include Loader
|
10
|
+
attr_reader :options
|
11
|
+
|
12
|
+
def initialize(options)
|
13
|
+
@options = options
|
14
|
+
@pool = VagrantPool.new(options.pool_size)
|
15
|
+
end
|
16
|
+
|
17
|
+
# actions
|
18
|
+
def create
|
19
|
+
@pool.create
|
20
|
+
@pool.load
|
21
|
+
end
|
22
|
+
|
23
|
+
def destroy
|
24
|
+
@pool.unload
|
25
|
+
end
|
26
|
+
|
27
|
+
def next
|
28
|
+
@pool.next
|
29
|
+
end
|
30
|
+
|
31
|
+
def ssh
|
32
|
+
@pool.ssh
|
33
|
+
end
|
34
|
+
|
35
|
+
def ssh_config
|
36
|
+
puts @pool.ssh_config
|
37
|
+
end
|
38
|
+
|
39
|
+
def inventory
|
40
|
+
puts File.read(@pool.get_inventory_file())
|
41
|
+
end
|
42
|
+
|
43
|
+
def status
|
44
|
+
@pool.status
|
45
|
+
end
|
46
|
+
|
47
|
+
# errors
|
48
|
+
def show_invalid_option
|
49
|
+
show_error @options.error
|
50
|
+
end
|
51
|
+
|
52
|
+
def show_missing_args
|
53
|
+
show_error @options.error
|
54
|
+
end
|
55
|
+
|
56
|
+
def show_parser_error
|
57
|
+
show_error @options.error
|
58
|
+
end
|
59
|
+
|
60
|
+
def show_error(msg = @options.error)
|
61
|
+
puts "Error: #{msg}"
|
62
|
+
puts
|
63
|
+
|
64
|
+
show_help
|
65
|
+
end
|
66
|
+
|
67
|
+
def method_missing(method)
|
68
|
+
show_error "Unknown action: #{method}"
|
69
|
+
end
|
70
|
+
|
71
|
+
# help
|
72
|
+
def show_help
|
73
|
+
puts @options.opts
|
74
|
+
end
|
75
|
+
|
76
|
+
def show_version
|
77
|
+
puts VERSION
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Front
|
2
|
+
module CLI
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Frontfile
|
6
|
+
attr_reader :path
|
7
|
+
attr_reader :data
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def exists?
|
14
|
+
File.exists?(path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(defaults)
|
18
|
+
@data = defaults
|
19
|
+
save()
|
20
|
+
end
|
21
|
+
|
22
|
+
def load
|
23
|
+
file_contents = File.read(path)
|
24
|
+
@data = JSON.parse(file_contents)
|
25
|
+
end
|
26
|
+
|
27
|
+
def save
|
28
|
+
json = @data.to_json
|
29
|
+
File.open(path, 'w') do |file|
|
30
|
+
file.write(json)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_current_id
|
35
|
+
@data['current_id']
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_current_id(current_id)
|
39
|
+
@data['current_id'] = current_id
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_pool_size
|
43
|
+
@data['pool_size']
|
44
|
+
end
|
45
|
+
|
46
|
+
def set_pool_size(pool_size)
|
47
|
+
@data['pool_size'] = pool_size
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Front
|
2
|
+
module CLI
|
3
|
+
class Script
|
4
|
+
def initialize(path)
|
5
|
+
@commands = []
|
6
|
+
@path = path
|
7
|
+
end
|
8
|
+
|
9
|
+
def enqueue(cmd)
|
10
|
+
@commands << cmd
|
11
|
+
end
|
12
|
+
|
13
|
+
def save
|
14
|
+
File.open(@path, 'w') do |file|
|
15
|
+
file.puts("#!/bin/bash")
|
16
|
+
|
17
|
+
@commands.each do |command|
|
18
|
+
file.puts(command)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
File.chmod(0755, @path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
if pending?
|
27
|
+
save()
|
28
|
+
pid = Kernel.spawn(@path)
|
29
|
+
Process.detach pid
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def pending?
|
34
|
+
@commands.length > 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Front
|
2
|
+
module CLI
|
3
|
+
require 'resque'
|
4
|
+
|
5
|
+
class Vagrant
|
6
|
+
attr_reader :id
|
7
|
+
attr_reader :path
|
8
|
+
attr_accessor :wait
|
9
|
+
attr_accessor :script
|
10
|
+
|
11
|
+
def initialize(id, path, script)
|
12
|
+
@id = id
|
13
|
+
@path = path
|
14
|
+
@wait = true
|
15
|
+
@script = script
|
16
|
+
end
|
17
|
+
|
18
|
+
def up
|
19
|
+
run('up')
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
run('destroy -f')
|
24
|
+
end
|
25
|
+
|
26
|
+
def reload
|
27
|
+
run('reload')
|
28
|
+
end
|
29
|
+
|
30
|
+
def ssh
|
31
|
+
run('ssh')
|
32
|
+
end
|
33
|
+
|
34
|
+
def ssh_config
|
35
|
+
capture('ssh-config')
|
36
|
+
end
|
37
|
+
|
38
|
+
def ssh_port
|
39
|
+
output = ssh_config()
|
40
|
+
re = /^\s*Port\s*(\d+)$/m
|
41
|
+
|
42
|
+
matches = output.match(re)
|
43
|
+
return matches[1]
|
44
|
+
end
|
45
|
+
|
46
|
+
def status
|
47
|
+
output = capture('status')
|
48
|
+
re = /^(\w+\s+\w+ \(\w+\))/m
|
49
|
+
matches = output.match(re)
|
50
|
+
if matches
|
51
|
+
return matches[1]
|
52
|
+
else
|
53
|
+
'pending'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_log_file
|
58
|
+
"#{path}/front.log"
|
59
|
+
end
|
60
|
+
|
61
|
+
def run(cmd)
|
62
|
+
cmd = "vagrant #{cmd}"
|
63
|
+
options = {}
|
64
|
+
options[:chdir] = path
|
65
|
+
|
66
|
+
if wait
|
67
|
+
pid = Kernel.spawn(cmd, options)
|
68
|
+
Process.wait pid
|
69
|
+
else
|
70
|
+
cmd = "#{cmd} &>> #{get_log_file()} "
|
71
|
+
script.enqueue "cd #{path} && #{cmd}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def run2(cmd)
|
76
|
+
options = {}
|
77
|
+
options[:chdir] = path
|
78
|
+
unless wait
|
79
|
+
log_file = "#{path}/front.log"
|
80
|
+
options[:out] = log_file
|
81
|
+
options[:err] = log_file
|
82
|
+
end
|
83
|
+
|
84
|
+
pid = Kernel.spawn("vagrant #{cmd}", options)
|
85
|
+
if wait
|
86
|
+
Process.wait pid
|
87
|
+
else
|
88
|
+
Process.detach pid
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def capture(cmd)
|
93
|
+
Dir.chdir(path) do
|
94
|
+
`vagrant #{cmd}`
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class VagrantWorker
|
100
|
+
@queue = :vagrant
|
101
|
+
|
102
|
+
def self.perform(task)
|
103
|
+
cmd = task.cmd
|
104
|
+
options = task.options
|
105
|
+
options[:out] = task.log_file
|
106
|
+
options[:err] = task.log_file
|
107
|
+
|
108
|
+
pid = Kernel.spawn(cmd, options)
|
109
|
+
Process.wait pid
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class VagrantTask
|
114
|
+
attr_accessor :cmd
|
115
|
+
attr_accessor :options
|
116
|
+
attr_accessor :log_file
|
117
|
+
|
118
|
+
def initialize(cmd, options, log_file)
|
119
|
+
@cmd = cmd
|
120
|
+
@options = options
|
121
|
+
@log_file = log_file
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
module Front
|
2
|
+
module CLI
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative 'front_file'
|
5
|
+
require_relative 'script'
|
6
|
+
|
7
|
+
class VagrantPool
|
8
|
+
include Loader
|
9
|
+
|
10
|
+
def initialize(size)
|
11
|
+
@size = size
|
12
|
+
@script = Script.new(get_script_path())
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
front_path = get_front_path()
|
17
|
+
FileUtils.mkdir_p(front_path)
|
18
|
+
|
19
|
+
get_pool_size().times do |index|
|
20
|
+
instance_id = index + 1
|
21
|
+
instance_path = get_instance_path(instance_id)
|
22
|
+
|
23
|
+
FileUtils.mkdir_p(instance_path)
|
24
|
+
FileUtils.cp get_vagrant_file(), instance_path
|
25
|
+
end
|
26
|
+
|
27
|
+
create_front_file
|
28
|
+
end
|
29
|
+
|
30
|
+
def load
|
31
|
+
loaded = false
|
32
|
+
get_pool_size().times do |index|
|
33
|
+
vagrant = get_vagrant(index + 1)
|
34
|
+
vagrant.wait = !loaded
|
35
|
+
vagrant.up
|
36
|
+
|
37
|
+
loaded = true
|
38
|
+
end
|
39
|
+
|
40
|
+
@script.run
|
41
|
+
end
|
42
|
+
|
43
|
+
def unload
|
44
|
+
get_pool_size().times do |index|
|
45
|
+
instance_id = index + 1
|
46
|
+
vagrant = get_vagrant(instance_id)
|
47
|
+
puts "Destroying instance \##{instance_id}"
|
48
|
+
vagrant.destroy
|
49
|
+
end
|
50
|
+
|
51
|
+
FileUtils.rm_rf(get_front_path())
|
52
|
+
end
|
53
|
+
|
54
|
+
def next
|
55
|
+
current_id = get_current_id()
|
56
|
+
vagrant = get_vagrant(current_id)
|
57
|
+
vagrant.wait = false
|
58
|
+
vagrant.destroy
|
59
|
+
vagrant.up
|
60
|
+
|
61
|
+
next_id = get_next_id()
|
62
|
+
vagrant = get_vagrant(next_id)
|
63
|
+
puts "Switched to instance \##{next_id}"
|
64
|
+
|
65
|
+
save_front_file(next_id)
|
66
|
+
update_inventory(vagrant)
|
67
|
+
@script.run()
|
68
|
+
|
69
|
+
next_id
|
70
|
+
end
|
71
|
+
|
72
|
+
def ssh
|
73
|
+
vagrant = get_vagrant(get_current_id())
|
74
|
+
vagrant.ssh
|
75
|
+
end
|
76
|
+
|
77
|
+
def ssh_config
|
78
|
+
vagrant = get_vagrant(get_current_id())
|
79
|
+
vagrant.ssh_config
|
80
|
+
end
|
81
|
+
|
82
|
+
def status
|
83
|
+
current_id = get_current_id()
|
84
|
+
get_pool_size().times do |index|
|
85
|
+
instance_id = index + 1
|
86
|
+
if instance_id == current_id
|
87
|
+
instance_label = "\##{instance_id}*"
|
88
|
+
else
|
89
|
+
instance_label = "\##{instance_id} "
|
90
|
+
end
|
91
|
+
|
92
|
+
vagrant = get_vagrant(instance_id)
|
93
|
+
puts "Instance #{instance_label}: #{vagrant.status}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_vagrant(instance_id)
|
98
|
+
instance_path = get_instance_path(instance_id)
|
99
|
+
Vagrant.new(instance_id, instance_path, @script)
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_inventory_file
|
103
|
+
"#{get_front_path()}/inventory.ini"
|
104
|
+
end
|
105
|
+
|
106
|
+
def get_front_path
|
107
|
+
"#{Dir.pwd}/.front"
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_script_path
|
111
|
+
"#{get_front_path()}/pending.sh"
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_instance_path(id)
|
115
|
+
"#{get_front_path()}/#{id}"
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_vagrant_file
|
119
|
+
custom_path = "#{Dir.pwd}/Vagrantfile"
|
120
|
+
if File.exists?(custom_path)
|
121
|
+
return custom_path
|
122
|
+
else
|
123
|
+
return "#{ROOT_DIR}/Vagrantfile"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def get_frontfile_path
|
128
|
+
"#{get_front_path()}/Frontfile"
|
129
|
+
end
|
130
|
+
|
131
|
+
def get_current_id
|
132
|
+
get_front_file().get_current_id()
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_next_id
|
136
|
+
current_id = get_current_id()
|
137
|
+
if current_id + 1 > get_pool_size()
|
138
|
+
next_id = 1
|
139
|
+
else
|
140
|
+
next_id = current_id + 1
|
141
|
+
end
|
142
|
+
|
143
|
+
next_id
|
144
|
+
end
|
145
|
+
|
146
|
+
def get_pool_size
|
147
|
+
front_file = get_front_file()
|
148
|
+
if front_file.exists?
|
149
|
+
front_file.get_pool_size()
|
150
|
+
else
|
151
|
+
@size
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# helpers
|
156
|
+
def get_front_file
|
157
|
+
if @front_file.nil?
|
158
|
+
@front_file = Frontfile.new(get_frontfile_path())
|
159
|
+
if @front_file.exists?
|
160
|
+
@front_file.load()
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
@front_file
|
165
|
+
end
|
166
|
+
|
167
|
+
def create_front_file
|
168
|
+
defaults = {}
|
169
|
+
defaults['current_id'] = 1
|
170
|
+
defaults['pool_size'] = @size
|
171
|
+
|
172
|
+
front_file = get_front_file()
|
173
|
+
front_file.create(defaults)
|
174
|
+
end
|
175
|
+
|
176
|
+
def save_front_file(current_id)
|
177
|
+
front_file = get_front_file()
|
178
|
+
front_file.set_current_id(current_id)
|
179
|
+
front_file.save()
|
180
|
+
end
|
181
|
+
|
182
|
+
def update_inventory(vagrant)
|
183
|
+
ip_address = "127.0.0.#{get_current_id()}"
|
184
|
+
port = vagrant.ssh_port()
|
185
|
+
|
186
|
+
item = "#{ip_address}:#{port}"
|
187
|
+
File.open(get_inventory_file(), 'w') do |file|
|
188
|
+
file.write(item)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
data/lib/front/loader.rb
ADDED
data/lib/front.rb
ADDED
data/portkey.json
ADDED
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: front
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Darshan Sawardekar
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Speed up your Vagrant workflow
|
42
|
+
email:
|
43
|
+
- darshan@sawardekar.org
|
44
|
+
executables:
|
45
|
+
- front
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- .gitignore
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- Vagrantfile
|
55
|
+
- bin/front
|
56
|
+
- front.gemspec
|
57
|
+
- lib/front.rb
|
58
|
+
- lib/front/cli/app.rb
|
59
|
+
- lib/front/cli/configuration.rb
|
60
|
+
- lib/front/cli/controller.rb
|
61
|
+
- lib/front/cli/front_file.rb
|
62
|
+
- lib/front/cli/router.rb
|
63
|
+
- lib/front/cli/script.rb
|
64
|
+
- lib/front/cli/vagrant.rb
|
65
|
+
- lib/front/cli/vagrant_pool.rb
|
66
|
+
- lib/front/loader.rb
|
67
|
+
- lib/front/version.rb
|
68
|
+
- portkey.json
|
69
|
+
homepage: https://github.com/dsawardekar/front
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata: {}
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 2.0.5
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: Booting up a fresh virtual machine takes time. `Front` speeds up VM boot
|
93
|
+
time by preinitializing a pool of VMs. When you need a fresh instance, use `front
|
94
|
+
next` and you are ready to work instantly. And while you work it rebuilds the old
|
95
|
+
VM for your next refill!
|
96
|
+
test_files: []
|