hobo-inviqa 0.0.8 → 0.0.9.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile.lock +4 -4
- data/README.md +1 -1
- data/Rakefile +4 -1
- data/bin/hobo +5 -0
- data/lib/hobo.rb +16 -3
- data/lib/hobo/asset_applicators/files.rb +5 -0
- data/lib/hobo/asset_applicators/sqldump.rb +15 -0
- data/lib/hobo/cli.rb +8 -3
- data/lib/hobo/helper/shell.rb +4 -1
- data/lib/hobo/helper/vm_command.rb +3 -254
- data/lib/hobo/lib/host_check.rb +4 -6
- data/lib/hobo/lib/host_check/deps.rb +2 -2
- data/lib/hobo/lib/host_check/git.rb +4 -4
- data/lib/hobo/lib/host_check/hobo.rb +51 -0
- data/lib/hobo/lib/host_check/ruby.rb +2 -2
- data/lib/hobo/lib/host_check/vagrant.rb +1 -1
- data/lib/hobo/lib/s3/local/file.rb +36 -0
- data/lib/hobo/lib/s3/local/iohandler.rb +36 -0
- data/lib/hobo/lib/s3/remote/file.rb +45 -0
- data/lib/hobo/lib/s3/remote/iohandler.rb +38 -0
- data/lib/hobo/lib/s3/sync.rb +116 -0
- data/lib/hobo/lib/seed/project.rb +3 -0
- data/lib/hobo/lib/vm/command.rb +125 -0
- data/lib/hobo/lib/vm/inspector.rb +73 -0
- data/lib/hobo/tasks/assets.rb +7 -56
- data/lib/hobo/tasks/deps.rb +1 -1
- data/lib/hobo/tasks/magento.rb +75 -0
- data/lib/hobo/tasks/system.rb +5 -2
- data/lib/hobo/util.rb +11 -0
- data/lib/hobo/version.rb +1 -1
- metadata +15 -5
- data/lib/hobo/lib/s3sync.rb +0 -216
data/lib/hobo/lib/host_check.rb
CHANGED
@@ -15,16 +15,14 @@ module Hobo
|
|
15
15
|
methods.each do |method|
|
16
16
|
next if opts[:filter] && !method.match(opts[:filter])
|
17
17
|
|
18
|
-
name = method.to_s.gsub('_', ' ')
|
19
|
-
name[0] = name[0].upcase
|
20
18
|
if opts[:raise]
|
21
|
-
self.send method
|
19
|
+
self.send method, opts
|
22
20
|
else
|
23
21
|
begin
|
24
|
-
self.send method
|
25
|
-
results[
|
22
|
+
self.send method, opts
|
23
|
+
results[method] = :ok
|
26
24
|
rescue Hobo::Error => error
|
27
|
-
results[
|
25
|
+
results[method] = error
|
28
26
|
end
|
29
27
|
end
|
30
28
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Hobo
|
2
2
|
module Lib
|
3
3
|
module HostCheck
|
4
|
-
def ssh_present
|
4
|
+
def ssh_present opts
|
5
5
|
advice = "The SSH command could not be located on your system.\n\n"
|
6
6
|
|
7
7
|
if OS.windows?
|
@@ -17,7 +17,7 @@ module Hobo
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def php_present
|
20
|
+
def php_present opts
|
21
21
|
advice = <<-EOF
|
22
22
|
The PHP command could not be located on your system.
|
23
23
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Hobo
|
2
2
|
module Lib
|
3
3
|
module HostCheck
|
4
|
-
def git_present
|
4
|
+
def git_present opts
|
5
5
|
advice = "The Git command could not be detected on your system.\n\n"
|
6
6
|
if OS.windows?
|
7
7
|
advice += "Please install it from http://git-scm.com/downloads ensuring you select the 'Use git and unix tools everywhere' option."
|
@@ -16,7 +16,7 @@ module Hobo
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def git_config_name_set
|
19
|
+
def git_config_name_set opts
|
20
20
|
advice = <<-EOF
|
21
21
|
You have not set your name in git config!
|
22
22
|
|
@@ -30,7 +30,7 @@ EOF
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def git_config_email_set
|
33
|
+
def git_config_email_set opts
|
34
34
|
advice = <<-EOF
|
35
35
|
You have not set your email in git config!
|
36
36
|
|
@@ -45,7 +45,7 @@ EOF
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def git_autocrlf_disabled
|
48
|
+
def git_autocrlf_disabled opts
|
49
49
|
return unless OS.windows?
|
50
50
|
|
51
51
|
advice = <<-EOF
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'semantic'
|
3
|
+
|
4
|
+
module Hobo
|
5
|
+
module Lib
|
6
|
+
module HostCheck
|
7
|
+
def latest_hobo_version opts
|
8
|
+
|
9
|
+
installed = ::Semantic::Version.new Hobo::VERSION
|
10
|
+
|
11
|
+
return if installed >= get_latest_hobo_version
|
12
|
+
|
13
|
+
if opts[:raise]
|
14
|
+
answer = Hobo.ui.ask("A new version of hobo is available. Would you like to install it?", :default => 'y')
|
15
|
+
|
16
|
+
if answer =~ /^[yY](es)?/
|
17
|
+
shell "gem install hobo-inviqa", :realtime => true
|
18
|
+
Hobo.relaunch!
|
19
|
+
end
|
20
|
+
else
|
21
|
+
raise Hobo::HostCheckError.new("A new version of hobo is available", "Install it with `gem install hobo-inviqa`")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def get_latest_hobo_version
|
28
|
+
one_day = 3600 * 24
|
29
|
+
file = File.join(Hobo.config_path, 'latest')
|
30
|
+
if !File.exists? file or File.mtime(file) < Time.now - one_day
|
31
|
+
Hobo.ui.success "Checking for new hobo version..."
|
32
|
+
uri = URI.parse('http://s3-eu-west-1.amazonaws.com/inviqa-hobo/version.txt')
|
33
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
34
|
+
http.open_timeout = 5
|
35
|
+
http.read_timeout = 5
|
36
|
+
|
37
|
+
response = http.get(uri.path)
|
38
|
+
|
39
|
+
if response.is_a? Net::HTTPOK
|
40
|
+
File.write(
|
41
|
+
file,
|
42
|
+
response.body
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
latest = File.read(file).strip if File.exists?(file)
|
47
|
+
::Semantic::Version.new(latest || Hobo::VERSION)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Hobo
|
2
2
|
module Lib
|
3
3
|
module HostCheck
|
4
|
-
def not_using_system_ruby
|
4
|
+
def not_using_system_ruby opts
|
5
5
|
return if OS.windows?
|
6
6
|
advice = <<-EOF
|
7
7
|
You're using a system ruby install which can cause issues with installing Gems and running some older projects.
|
@@ -20,7 +20,7 @@ EOF
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def system_paths_for_ruby
|
23
|
+
def system_paths_for_ruby opts
|
24
24
|
return if OS.windows?
|
25
25
|
|
26
26
|
advice = <<-EOF
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Hobo
|
2
|
+
module Lib
|
3
|
+
module S3
|
4
|
+
module Local
|
5
|
+
class File
|
6
|
+
def initialize file
|
7
|
+
@file = file
|
8
|
+
end
|
9
|
+
|
10
|
+
def buffer
|
11
|
+
# NOP
|
12
|
+
end
|
13
|
+
|
14
|
+
def read bytes
|
15
|
+
@file.read bytes
|
16
|
+
end
|
17
|
+
|
18
|
+
def write opts = {}
|
19
|
+
opts = { :chunk_size => 4096 }.merge(opts)
|
20
|
+
while @file.size < opts[:size] do
|
21
|
+
yield @file, opts[:chunk_size]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def size
|
26
|
+
@file.size
|
27
|
+
end
|
28
|
+
|
29
|
+
def close
|
30
|
+
@file.close
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Hobo
|
2
|
+
module Lib
|
3
|
+
module S3
|
4
|
+
module Local
|
5
|
+
class IoHandler
|
6
|
+
include Hobo::Logging
|
7
|
+
|
8
|
+
def initialize path
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
|
12
|
+
def ls
|
13
|
+
logger.debug("s3sync: Listing local directory: #{@path}")
|
14
|
+
out = {}
|
15
|
+
dir = "#{@path.chomp('/')}/"
|
16
|
+
files = Dir.glob("#{dir}**/*")
|
17
|
+
files.each do |file|
|
18
|
+
out[file.gsub(/^#{dir}/, '')] = Digest::MD5.file(file).hexdigest
|
19
|
+
end
|
20
|
+
return out
|
21
|
+
end
|
22
|
+
|
23
|
+
def open file, mode
|
24
|
+
file_path = ::File.join(@path, file)
|
25
|
+
FileUtils.mkdir_p ::File.dirname(file_path)
|
26
|
+
File.new ::File.open(file_path, mode)
|
27
|
+
end
|
28
|
+
|
29
|
+
def rm file
|
30
|
+
::File.unlink ::File.join(@path, file)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Hobo
|
2
|
+
module Lib
|
3
|
+
module S3
|
4
|
+
module Remote
|
5
|
+
class File
|
6
|
+
def initialize object, prefix
|
7
|
+
@object = object
|
8
|
+
@prefix = prefix
|
9
|
+
@r_buffer, @w_buffer = IO.pipe
|
10
|
+
@buffer_thread = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def buffer
|
14
|
+
@buffer_thread = Thread.new do
|
15
|
+
@object.read do |chunk|
|
16
|
+
@w_buffer.write chunk
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def read bytes
|
22
|
+
@r_buffer.readpartial(bytes)
|
23
|
+
end
|
24
|
+
|
25
|
+
def write opts = {}
|
26
|
+
s3_opts = { :single_request => true, :content_length => opts[:size] }
|
27
|
+
@object.write s3_opts do |buffer, bytes|
|
28
|
+
yield buffer, bytes
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def size
|
33
|
+
@object.content_length
|
34
|
+
end
|
35
|
+
|
36
|
+
def close
|
37
|
+
@r_buffer.close
|
38
|
+
@w_buffer.close
|
39
|
+
@buffer_thread.exit if @buffer_thread
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Hobo
|
2
|
+
module Lib
|
3
|
+
module S3
|
4
|
+
module Remote
|
5
|
+
class IoHandler
|
6
|
+
include Hobo::Logging
|
7
|
+
|
8
|
+
def initialize s3, bucket, prefix
|
9
|
+
@s3 = s3
|
10
|
+
@bucket = bucket
|
11
|
+
@prefix = prefix ? "#{prefix.gsub(/^\//, '').chomp('/')}/" : ""
|
12
|
+
end
|
13
|
+
|
14
|
+
def ls
|
15
|
+
out = {}
|
16
|
+
logger.debug("s3sync: Listing remote bucket: #{@bucket} w/ prefix #{@prefix}")
|
17
|
+
@s3.buckets[@bucket].objects.with_prefix(@prefix).each do |file|
|
18
|
+
filename = file.key.gsub(/^#{@prefix}/, '')
|
19
|
+
next if filename == ""
|
20
|
+
out[filename] = file.etag.gsub('"', '')
|
21
|
+
end
|
22
|
+
return out
|
23
|
+
end
|
24
|
+
|
25
|
+
def open file, mode
|
26
|
+
s3_key = ::File.join(@prefix, file)
|
27
|
+
File.new @s3.buckets[@bucket].objects[s3_key], @prefix
|
28
|
+
end
|
29
|
+
|
30
|
+
def rm file
|
31
|
+
s3_key = ::File.join(@prefix, file)
|
32
|
+
@s3.buckets[@bucket].objects[s3_key].delete
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Hobo
|
5
|
+
module Lib
|
6
|
+
module S3
|
7
|
+
class Sync
|
8
|
+
include Hobo::Logging
|
9
|
+
|
10
|
+
def initialize opts = {}
|
11
|
+
@opts = {
|
12
|
+
:access_key_id => nil,
|
13
|
+
:secret_access_key => nil,
|
14
|
+
:verify_response_body_content_length => false,
|
15
|
+
:max_retries => 15
|
16
|
+
}.merge(opts)
|
17
|
+
|
18
|
+
# AWS::S3 is flakey about actually raising this error when nil is provided
|
19
|
+
[:access_key_id, :secret_access_key].each do |k|
|
20
|
+
raise AWS::Errors::MissingCredentialsError if @opts[k].nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
logger.debug("s3sync: Options #{@opts}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def sync source, dest, opts = {}
|
27
|
+
delta = {:add => [], :remove => []}
|
28
|
+
|
29
|
+
handle_s3_error do
|
30
|
+
opts = { :progress => Hobo.method(:progress) }.merge(opts)
|
31
|
+
|
32
|
+
source_io = io_handler(source)
|
33
|
+
destination_io = io_handler(dest)
|
34
|
+
|
35
|
+
logger.debug("s3sync: Synchronzing (#{source_io.class.name} -> #{destination_io.class.name}")
|
36
|
+
|
37
|
+
raise "S3 -> S3 synchronisation not supported" if source_io.is_a? Remote and destination_io.is_a? Remote
|
38
|
+
|
39
|
+
source_listing = source_io.ls
|
40
|
+
destination_listing = destination_io.ls
|
41
|
+
logger.debug("s3sync: Source listing - #{source_listing}")
|
42
|
+
logger.debug("s3sync: Destination listing - #{destination_listing}")
|
43
|
+
|
44
|
+
delta = delta(source_listing, destination_listing)
|
45
|
+
logger.debug("s3sync: Delta #{delta}")
|
46
|
+
|
47
|
+
delta[:add].each do |file|
|
48
|
+
logger.debug("s3sync: Synchronizing #{file}")
|
49
|
+
source_file = source_io.open(file, "r")
|
50
|
+
destination_file = destination_io.open(file, "wb+")
|
51
|
+
|
52
|
+
source_file.buffer
|
53
|
+
|
54
|
+
size = source_file.size
|
55
|
+
destination_file.write({ :size => source_file.size }) do |buffer, bytes|
|
56
|
+
chunk = source_file.read(bytes)
|
57
|
+
buffer.write(chunk)
|
58
|
+
opts[:progress].call(file, chunk.length, size, :update)
|
59
|
+
end
|
60
|
+
|
61
|
+
destination_file.close
|
62
|
+
source_file.close
|
63
|
+
|
64
|
+
opts[:progress].call(file, 0, size, :finish)
|
65
|
+
end
|
66
|
+
|
67
|
+
delta[:remove].each do |file|
|
68
|
+
logger.debug("s3sync: Removing #{file}")
|
69
|
+
destination_io.rm(file)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
return delta
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def s3
|
79
|
+
@s3 ||= AWS::S3.new @opts
|
80
|
+
end
|
81
|
+
|
82
|
+
def handle_s3_error
|
83
|
+
begin
|
84
|
+
yield
|
85
|
+
rescue Errno::ENETUNREACH
|
86
|
+
Hobo.ui.error " Could not contact Amazon servers."
|
87
|
+
Hobo.ui.error " This can sometimes be caused by missing AWS credentials"
|
88
|
+
rescue AWS::S3::Errors::NoSuchBucket
|
89
|
+
Hobo.ui.error " Asset bucket #{Hobo.project_config.asset_bucket} does not exist!"
|
90
|
+
rescue AWS::Errors::MissingCredentialsError
|
91
|
+
Hobo.ui.warning " AWS credentials not set!"
|
92
|
+
Hobo.ui.warning " Either set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY env vars or run `hobo config` to set them jsut for hobo."
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def delta source, dest
|
97
|
+
to_add = (source.sort - dest.sort).map(&:first)
|
98
|
+
to_remove = (dest.sort - source.sort).map(&:first)
|
99
|
+
to_remove = to_remove - to_add
|
100
|
+
|
101
|
+
{
|
102
|
+
:add => to_add,
|
103
|
+
:remove => to_remove
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def io_handler uri
|
108
|
+
parsed = URI.parse(uri)
|
109
|
+
parsed.scheme == 's3' ?
|
110
|
+
Remote::IoHandler.new(s3, parsed.host, parsed.path) :
|
111
|
+
Local::IoHandler.new(uri)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -16,6 +16,9 @@ module Hobo
|
|
16
16
|
config[:seed][:version] = seed.version
|
17
17
|
config[:hostname] = "#{config[:name]}.dev"
|
18
18
|
config[:asset_bucket] = "inviqa-assets-#{config[:name]}"
|
19
|
+
config[:vm] = {
|
20
|
+
:project_mount_path => "/vagrant"
|
21
|
+
}
|
19
22
|
|
20
23
|
@opts[:replacer].replace(config[:project_path], config)
|
21
24
|
load_seed_init(config)
|