hobo-inviqa 0.0.8 → 0.0.9.pre.alpha
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.
- 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)
|