picobox 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
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