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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +5 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/DOCKER_INFO.md +3 -0
  7. data/Gemfile +5 -0
  8. data/Guardfile +47 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +138 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +14 -0
  13. data/bin/picobox +5 -0
  14. data/bin/picobox_dev +10 -0
  15. data/bin/rake +17 -0
  16. data/bin/setup +8 -0
  17. data/docs/demo_script.md +27 -0
  18. data/docs/testdrive +5658 -0
  19. data/docs/testdrive.gif +0 -0
  20. data/lib/picobox.rb +79 -0
  21. data/lib/picobox/box.rb +37 -0
  22. data/lib/picobox/boxes/manifest.rb +59 -0
  23. data/lib/picobox/boxes/packages/elixir/Dockerfile +47 -0
  24. data/lib/picobox/boxes/packages/elixir/docker-compose.yml +26 -0
  25. data/lib/picobox/boxes/packages/elixir/info +18 -0
  26. data/lib/picobox/boxes/packages/elixir/start +3 -0
  27. data/lib/picobox/boxes/packages/python/Dockerfile +33 -0
  28. data/lib/picobox/boxes/packages/python/docker-compose.yml +14 -0
  29. data/lib/picobox/boxes/packages/python/start +3 -0
  30. data/lib/picobox/boxes/packages/rails/Dockerfile +57 -0
  31. data/lib/picobox/boxes/packages/rails/docker-compose.yml +50 -0
  32. data/lib/picobox/boxes/packages/rails/start +9 -0
  33. data/lib/picobox/boxes/packages/ruby/Dockerfile +5 -0
  34. data/lib/picobox/boxes/packages/ruby/docker-compose.yml +22 -0
  35. data/lib/picobox/boxes/packages/ruby/start +3 -0
  36. data/lib/picobox/boxes/unpacker.rb +55 -0
  37. data/lib/picobox/cli.rb +163 -0
  38. data/lib/picobox/commands/add_box.rb +23 -0
  39. data/lib/picobox/commands/add_service.rb +25 -0
  40. data/lib/picobox/commands/build_service.rb +16 -0
  41. data/lib/picobox/commands/download_docker.rb +17 -0
  42. data/lib/picobox/commands/finish_install.rb +10 -0
  43. data/lib/picobox/commands/finish_uninstall.rb +9 -0
  44. data/lib/picobox/commands/initialize_project.rb +35 -0
  45. data/lib/picobox/commands/install_docker.rb +27 -0
  46. data/lib/picobox/commands/list_boxes.rb +16 -0
  47. data/lib/picobox/commands/list_services.rb +16 -0
  48. data/lib/picobox/commands/open_shell.rb +26 -0
  49. data/lib/picobox/commands/remove_service.rb +25 -0
  50. data/lib/picobox/commands/remove_setup_shell.rb +28 -0
  51. data/lib/picobox/commands/restart.rb +21 -0
  52. data/lib/picobox/commands/setup_shell.rb +19 -0
  53. data/lib/picobox/commands/start.rb +22 -0
  54. data/lib/picobox/commands/start_install.rb +9 -0
  55. data/lib/picobox/commands/start_uninstall.rb +20 -0
  56. data/lib/picobox/commands/stop.rb +24 -0
  57. data/lib/picobox/constants.rb +14 -0
  58. data/lib/picobox/dns.rb +8 -0
  59. data/lib/picobox/docker_compose/config.rb +59 -0
  60. data/lib/picobox/errors/picobox_error.rb +15 -0
  61. data/lib/picobox/handlers/stdout_handler.rb +142 -0
  62. data/lib/picobox/os/abstract.rb +29 -0
  63. data/lib/picobox/os/current_os.rb +14 -0
  64. data/lib/picobox/os/darwin.rb +15 -0
  65. data/lib/picobox/os/linux.rb +9 -0
  66. data/lib/picobox/os/unsupported_os.rb +9 -0
  67. data/lib/picobox/project.rb +19 -0
  68. data/lib/picobox/service.rb +64 -0
  69. data/lib/picobox/services/installer.rb +41 -0
  70. data/lib/picobox/services/manifest.rb +50 -0
  71. data/lib/picobox/services/packages/elasticsearch/config.yml +14 -0
  72. data/lib/picobox/services/packages/memcached/config.yml +9 -0
  73. data/lib/picobox/services/packages/mongodb/config.yml +13 -0
  74. data/lib/picobox/services/packages/mysql/config.yml +17 -0
  75. data/lib/picobox/services/packages/postgres/config.yml +16 -0
  76. data/lib/picobox/services/packages/redis/config.yml +7 -0
  77. data/lib/picobox/shell/dot_profile.rb +42 -0
  78. data/lib/picobox/shell/dot_zshrc.rb +42 -0
  79. data/lib/picobox/shell/startup_script.rb +18 -0
  80. data/lib/picobox/system.rb +83 -0
  81. data/lib/picobox/templates/shell_extensions.bash +125 -0
  82. data/lib/picobox/utils/domain_event_publisher.rb +11 -0
  83. data/lib/picobox/utils/output.rb +69 -0
  84. data/lib/picobox/utils/progress_bar.rb +31 -0
  85. data/lib/picobox/utils/project.rb +55 -0
  86. data/lib/picobox/utils/shell.rb +18 -0
  87. data/lib/picobox/utils/visitable.rb +9 -0
  88. data/lib/picobox/utils/visitor_by_os.rb +29 -0
  89. data/lib/runner.rb +51 -0
  90. data/picobox.gemspec +49 -0
  91. 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,14 @@
1
+ module Picobox
2
+ module Os
3
+ class CurrentOs
4
+ class << self
5
+ def get
6
+ os = TTY::Platform.new.os
7
+ case os
8
+ when 'darwin' then Darwin
9
+ else UnsupportedOs end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ 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,9 @@
1
+ module Picobox
2
+ module Os
3
+ class Linux < Abstract
4
+ class << self
5
+ def to_s() :linux end
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Picobox
2
+ module Os
3
+ class UnsupportedOs < Abstract
4
+ class << self
5
+ def to_s() :unsupported end
6
+ end
7
+ end
8
+ end
9
+ 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,9 @@
1
+ # the service
2
+ memcached:
3
+ image: sameersbn/memcached:latest
4
+ environment:
5
+ CACHE_SIZE: '64'
6
+
7
+ # create links to these services
8
+ links:
9
+ - dev
@@ -0,0 +1,13 @@
1
+ # the service
2
+ mongodb:
3
+ image: mongo
4
+ ports:
5
+ - '27017:27017'
6
+
7
+ # create links to these services
8
+ links:
9
+ - dev
10
+ - test
11
+
12
+ # post install instructions
13
+ instructions: mongodb exposes 27017 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,7 @@
1
+ # the service
2
+ redis:
3
+ image: redis
4
+
5
+ # create links to these services
6
+ links:
7
+ - dev
@@ -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