picobox 0.1.7
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 +7 -0
- data/.gitignore +16 -0
- data/.rspec +5 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/DOCKER_INFO.md +3 -0
- data/Gemfile +5 -0
- data/Guardfile +47 -0
- data/LICENSE.txt +21 -0
- data/README.md +138 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/picobox +5 -0
- data/bin/picobox_dev +10 -0
- data/bin/rake +17 -0
- data/bin/setup +8 -0
- data/docs/demo_script.md +27 -0
- data/docs/testdrive +5658 -0
- data/docs/testdrive.gif +0 -0
- data/lib/picobox.rb +79 -0
- data/lib/picobox/box.rb +37 -0
- data/lib/picobox/boxes/manifest.rb +59 -0
- data/lib/picobox/boxes/packages/elixir/Dockerfile +47 -0
- data/lib/picobox/boxes/packages/elixir/docker-compose.yml +26 -0
- data/lib/picobox/boxes/packages/elixir/info +18 -0
- data/lib/picobox/boxes/packages/elixir/start +3 -0
- data/lib/picobox/boxes/packages/python/Dockerfile +33 -0
- data/lib/picobox/boxes/packages/python/docker-compose.yml +14 -0
- data/lib/picobox/boxes/packages/python/start +3 -0
- data/lib/picobox/boxes/packages/rails/Dockerfile +57 -0
- data/lib/picobox/boxes/packages/rails/docker-compose.yml +50 -0
- data/lib/picobox/boxes/packages/rails/start +9 -0
- data/lib/picobox/boxes/packages/ruby/Dockerfile +5 -0
- data/lib/picobox/boxes/packages/ruby/docker-compose.yml +22 -0
- data/lib/picobox/boxes/packages/ruby/start +3 -0
- data/lib/picobox/boxes/unpacker.rb +55 -0
- data/lib/picobox/cli.rb +163 -0
- data/lib/picobox/commands/add_box.rb +23 -0
- data/lib/picobox/commands/add_service.rb +25 -0
- data/lib/picobox/commands/build_service.rb +16 -0
- data/lib/picobox/commands/download_docker.rb +17 -0
- data/lib/picobox/commands/finish_install.rb +10 -0
- data/lib/picobox/commands/finish_uninstall.rb +9 -0
- data/lib/picobox/commands/initialize_project.rb +35 -0
- data/lib/picobox/commands/install_docker.rb +27 -0
- data/lib/picobox/commands/list_boxes.rb +16 -0
- data/lib/picobox/commands/list_services.rb +16 -0
- data/lib/picobox/commands/open_shell.rb +26 -0
- data/lib/picobox/commands/remove_service.rb +25 -0
- data/lib/picobox/commands/remove_setup_shell.rb +28 -0
- data/lib/picobox/commands/restart.rb +21 -0
- data/lib/picobox/commands/setup_shell.rb +19 -0
- data/lib/picobox/commands/start.rb +22 -0
- data/lib/picobox/commands/start_install.rb +9 -0
- data/lib/picobox/commands/start_uninstall.rb +20 -0
- data/lib/picobox/commands/stop.rb +24 -0
- data/lib/picobox/constants.rb +14 -0
- data/lib/picobox/dns.rb +8 -0
- data/lib/picobox/docker_compose/config.rb +59 -0
- data/lib/picobox/errors/picobox_error.rb +15 -0
- data/lib/picobox/handlers/stdout_handler.rb +142 -0
- data/lib/picobox/os/abstract.rb +29 -0
- data/lib/picobox/os/current_os.rb +14 -0
- data/lib/picobox/os/darwin.rb +15 -0
- data/lib/picobox/os/linux.rb +9 -0
- data/lib/picobox/os/unsupported_os.rb +9 -0
- data/lib/picobox/project.rb +19 -0
- data/lib/picobox/service.rb +64 -0
- data/lib/picobox/services/installer.rb +41 -0
- data/lib/picobox/services/manifest.rb +50 -0
- data/lib/picobox/services/packages/elasticsearch/config.yml +14 -0
- data/lib/picobox/services/packages/memcached/config.yml +9 -0
- data/lib/picobox/services/packages/mongodb/config.yml +13 -0
- data/lib/picobox/services/packages/mysql/config.yml +17 -0
- data/lib/picobox/services/packages/postgres/config.yml +16 -0
- data/lib/picobox/services/packages/redis/config.yml +7 -0
- data/lib/picobox/shell/dot_profile.rb +42 -0
- data/lib/picobox/shell/dot_zshrc.rb +42 -0
- data/lib/picobox/shell/startup_script.rb +18 -0
- data/lib/picobox/system.rb +83 -0
- data/lib/picobox/templates/shell_extensions.bash +125 -0
- data/lib/picobox/utils/domain_event_publisher.rb +11 -0
- data/lib/picobox/utils/output.rb +69 -0
- data/lib/picobox/utils/progress_bar.rb +31 -0
- data/lib/picobox/utils/project.rb +55 -0
- data/lib/picobox/utils/shell.rb +18 -0
- data/lib/picobox/utils/visitable.rb +9 -0
- data/lib/picobox/utils/visitor_by_os.rb +29 -0
- data/lib/runner.rb +51 -0
- data/picobox.gemspec +49 -0
- metadata +386 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
module Os
|
|
3
|
+
class Abstract
|
|
4
|
+
class << self
|
|
5
|
+
def tmp_dir() '/tmp' end
|
|
6
|
+
def home_dir() "#{ENV['HOME']}" end
|
|
7
|
+
def current_dir() `pwd`.strip end
|
|
8
|
+
def config_dir() "#{home_dir}/#{Picobox::CONFIG_DIR}" end
|
|
9
|
+
|
|
10
|
+
def shell_extensions() "#{config_dir}/#{Picobox::SHELL_EXTENSIONS}" end
|
|
11
|
+
|
|
12
|
+
# download and install
|
|
13
|
+
def docker_filename() end
|
|
14
|
+
def docker_url() end
|
|
15
|
+
def docker_installer() end
|
|
16
|
+
def docker_installed?() end
|
|
17
|
+
|
|
18
|
+
def docker_version?() `docker --version` end
|
|
19
|
+
def user_shell() "#{ENV['SHELL']}" end
|
|
20
|
+
|
|
21
|
+
def to_s() raise ::NotImplementedError, 'must override to_s' end
|
|
22
|
+
|
|
23
|
+
def project_root() Utils::Project.new(self).root end
|
|
24
|
+
def reload_shell() system("exec #{user_shell} -l") end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
module Os
|
|
3
|
+
class Darwin < Abstract
|
|
4
|
+
class << self
|
|
5
|
+
# download and install
|
|
6
|
+
def docker_filename() 'Docker.dmg' end
|
|
7
|
+
def docker_url() "https://download.docker.com/mac/stable/#{docker_filename}" end
|
|
8
|
+
def docker_installer() "#{tmp_dir}/#{docker_filename}" end
|
|
9
|
+
def docker_installed?() File.exist?('/Applications/Docker.app') end
|
|
10
|
+
|
|
11
|
+
def to_s() :darwin end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
class Project
|
|
3
|
+
include Utils::Visitable
|
|
4
|
+
include Utils::Output
|
|
5
|
+
|
|
6
|
+
attr_reader :os
|
|
7
|
+
|
|
8
|
+
def initialize(os)
|
|
9
|
+
@os = os
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def init
|
|
13
|
+
accept(Commands::InitializeProject.new)
|
|
14
|
+
rescue Exception => e
|
|
15
|
+
display_info(e, :red)
|
|
16
|
+
exit 1
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
class Service
|
|
3
|
+
include Utils::Visitable
|
|
4
|
+
include Utils::Output
|
|
5
|
+
|
|
6
|
+
attr_reader :os
|
|
7
|
+
|
|
8
|
+
def initialize(os)
|
|
9
|
+
@os = os
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def build(service=nil)
|
|
13
|
+
accept(Commands::BuildService.new(service))
|
|
14
|
+
rescue Exception => e
|
|
15
|
+
display_info(e, :red)
|
|
16
|
+
exit 1
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def add(services)
|
|
20
|
+
services.each { |service| accept(Commands::AddService.new(service)) }
|
|
21
|
+
accept(Commands::Restart.new)
|
|
22
|
+
rescue Errors::ServiceNotImplemented => e
|
|
23
|
+
display_service_not_available e.message
|
|
24
|
+
exit 1
|
|
25
|
+
rescue Errors::ProjectNotInitialized
|
|
26
|
+
display_project_not_initialized
|
|
27
|
+
exit 1
|
|
28
|
+
rescue Picobox::Errors::FileNotFoundError => e
|
|
29
|
+
display_file_not_found e.message
|
|
30
|
+
exit 1
|
|
31
|
+
rescue Exception => e
|
|
32
|
+
display_info(e, :red)
|
|
33
|
+
exit 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def remove(type = nil)
|
|
38
|
+
return if type.nil?
|
|
39
|
+
accept(Commands::RemoveService.new(type))
|
|
40
|
+
accept(Commands::Restart.new)
|
|
41
|
+
rescue Errors::ServiceNotInstalled
|
|
42
|
+
display_service_not_installed type
|
|
43
|
+
rescue Errors::ServiceNotImplemented
|
|
44
|
+
display_service_not_available type
|
|
45
|
+
rescue Errors::ProjectNotInitialized
|
|
46
|
+
display_project_not_initialized
|
|
47
|
+
exit 1
|
|
48
|
+
rescue Picobox::Errors::FileNotFoundError => e
|
|
49
|
+
display_file_not_found e.message
|
|
50
|
+
exit
|
|
51
|
+
rescue Exception => e
|
|
52
|
+
display_info(e, :red)
|
|
53
|
+
exit 1
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def list()
|
|
58
|
+
accept(Commands::ListServices.new)
|
|
59
|
+
rescue Exception => e
|
|
60
|
+
display_info(e, :red)
|
|
61
|
+
exit 1
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
module Services
|
|
3
|
+
class Installer
|
|
4
|
+
include Utils::Output
|
|
5
|
+
|
|
6
|
+
def initialize(os)
|
|
7
|
+
@os = os
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def install(type)
|
|
12
|
+
@manifest = Manifest.new(os, type)
|
|
13
|
+
@manifest.check! # raises an exception if we can't find the type in the manifest
|
|
14
|
+
|
|
15
|
+
config = DockerCompose::Config.new manifest.docker_compose_file
|
|
16
|
+
config.add_service manifest.service, manifest.service_links
|
|
17
|
+
|
|
18
|
+
config.save
|
|
19
|
+
display_status 'modify', manifest.docker_compose_file
|
|
20
|
+
display_status 'info', "hostname '#{manifest.service_name}' is visible to other services", :yellow
|
|
21
|
+
display_status 'info', manifest.post_install_instructions, :yellow
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def uninstall(type)
|
|
26
|
+
@manifest = Manifest.new(os, type)
|
|
27
|
+
|
|
28
|
+
config = DockerCompose::Config.new manifest.docker_compose_file
|
|
29
|
+
config.check!(type) # raises an exception if we can't find the type currently installed
|
|
30
|
+
|
|
31
|
+
config.remove_service manifest.service
|
|
32
|
+
|
|
33
|
+
config.save
|
|
34
|
+
display_status 'modify', manifest.docker_compose_file
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
attr_reader :os, :manifest
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
module Services
|
|
3
|
+
class Manifest
|
|
4
|
+
def initialize(os, type = nil)
|
|
5
|
+
@os, @type = os, type
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def list
|
|
9
|
+
result = Dir.glob("#{Picobox.service_packages_dir}/*").select {|f| File.directory? f}
|
|
10
|
+
result.map {|r| strip_path(r) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def package_contents
|
|
15
|
+
@package_contents ||= Dir.glob(File.join(service, "*"))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def check!
|
|
20
|
+
(raise Errors::ServiceNotImplemented, type) unless list.include?(type)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def docker_compose_file () "#{os.project_root}/docker-compose.yml" end
|
|
24
|
+
def service_name() (package.keys - ['links', 'instructions']).first end
|
|
25
|
+
|
|
26
|
+
def service () slice(package, service_name) end
|
|
27
|
+
def service_links() slice(package, 'links')['links'] end
|
|
28
|
+
def post_install_instructions() slice(package, 'instructions')['instructions'] end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
attr_reader :os, :type
|
|
32
|
+
|
|
33
|
+
def package
|
|
34
|
+
@package ||= YAML.load_file("#{package_dir}/config.yml")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def package_dir
|
|
38
|
+
"#{Picobox.service_packages_dir}/#{type}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def strip_path(file)
|
|
42
|
+
file.split('/').last
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def slice(hash, *keys)
|
|
46
|
+
Hash[ [keys, hash.values_at(*keys)].transpose]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# the service
|
|
2
|
+
elasticsearch:
|
|
3
|
+
image: docker.elastic.co/elasticsearch/elasticsearch:5.5.2
|
|
4
|
+
volumes:
|
|
5
|
+
- db-data:/var/lib/elasticsearch/data
|
|
6
|
+
ports:
|
|
7
|
+
- '9200:9200'
|
|
8
|
+
|
|
9
|
+
# create links to these services
|
|
10
|
+
links:
|
|
11
|
+
- dev
|
|
12
|
+
|
|
13
|
+
# post install instructions
|
|
14
|
+
instructions: elasticsearch exposes 9200 to the public
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# the service
|
|
2
|
+
mysql:
|
|
3
|
+
image: mysql:5.7
|
|
4
|
+
volumes:
|
|
5
|
+
- db-data:/var/lib/mysql
|
|
6
|
+
environment:
|
|
7
|
+
MYSQL_ROOT_PASSWORD: picobox
|
|
8
|
+
MYSQL_USER: picobox
|
|
9
|
+
MYSQL_PASSWORD: picobox
|
|
10
|
+
|
|
11
|
+
# create links to these services
|
|
12
|
+
links:
|
|
13
|
+
- dev
|
|
14
|
+
- test
|
|
15
|
+
|
|
16
|
+
# post install instructions
|
|
17
|
+
instructions: mysql user, password and root password are 'picobox'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# the service
|
|
2
|
+
postgres:
|
|
3
|
+
image: postgres:9.4
|
|
4
|
+
volumes:
|
|
5
|
+
- db-data:/var/lib/postgresql/db-data
|
|
6
|
+
environment:
|
|
7
|
+
POSTGRES_USER: 'picobox'
|
|
8
|
+
POSTGRES_PASSWORD: 'picobox'
|
|
9
|
+
|
|
10
|
+
# create links to these services
|
|
11
|
+
links:
|
|
12
|
+
- dev
|
|
13
|
+
- test
|
|
14
|
+
|
|
15
|
+
# post install instructions
|
|
16
|
+
instructions: postgres user and password are 'picobox'
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
module Shell
|
|
3
|
+
class DotProfile
|
|
4
|
+
attr_reader :os
|
|
5
|
+
|
|
6
|
+
def initialize(os)
|
|
7
|
+
@os = os
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def install_extensions
|
|
11
|
+
source = "#{Picobox.template_dir}/shell_extensions.bash"
|
|
12
|
+
dest = os.shell_extensions
|
|
13
|
+
|
|
14
|
+
TTY::File.copy_file source, dest
|
|
15
|
+
|
|
16
|
+
TTY::File.append_to_file(
|
|
17
|
+
filename,
|
|
18
|
+
"\n#{extension}\n"
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def uninstall_extensions
|
|
23
|
+
TTY::File.gsub_file filename, /#{Regexp.escape(extension)}/ do
|
|
24
|
+
"# picobox removed #{Time.now}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def filename
|
|
29
|
+
"#{os.home_dir}/.profile"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
def source_file
|
|
34
|
+
"~/#{Picobox::CONFIG_DIR}/#{Picobox::SHELL_EXTENSIONS}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def extension
|
|
38
|
+
"# added by picobox\nsource #{source_file}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
module Shell
|
|
3
|
+
class DotZshrc
|
|
4
|
+
attr_reader :os
|
|
5
|
+
|
|
6
|
+
def initialize(os)
|
|
7
|
+
@os = os
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def install_extensions
|
|
11
|
+
source = "#{Picobox.template_dir}/shell_extensions.bash"
|
|
12
|
+
dest = os.shell_extensions
|
|
13
|
+
|
|
14
|
+
TTY::File.copy_file source, dest
|
|
15
|
+
|
|
16
|
+
TTY::File.append_to_file(
|
|
17
|
+
filename,
|
|
18
|
+
"\n#{extension}\n"
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def uninstall_extensions
|
|
23
|
+
TTY::File.gsub_file filename, /#{Regexp.escape(extension)}/ do
|
|
24
|
+
"# picobox removed #{Time.now}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def filename
|
|
29
|
+
"#{os.home_dir}/.zshrc"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
def source_file
|
|
34
|
+
"~/#{Picobox::CONFIG_DIR}/#{Picobox::SHELL_EXTENSIONS}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def extension
|
|
38
|
+
"# added by picobox\nsource #{source_file}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Picobox
|
|
2
|
+
module Shell
|
|
3
|
+
class StartupScript
|
|
4
|
+
class << self
|
|
5
|
+
def get(os)
|
|
6
|
+
case "#{os.user_shell}:#{os.to_s}"
|
|
7
|
+
when '/bin/bash:darwin'
|
|
8
|
+
Shell::DotProfile.new(os)
|
|
9
|
+
when '/bin/zsh:darwin'
|
|
10
|
+
Shell::DotZshrc.new(os)
|
|
11
|
+
else
|
|
12
|
+
raise Errors::ShellNotSupported, "#{os.user_shell}:#{os.to_s}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|