pixiebox 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +4 -0
  4. data/DOCKER_INFO.md +3 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +47 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +146 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/pixiebox +5 -0
  12. data/bin/pixiebox_dev +10 -0
  13. data/bin/rake +17 -0
  14. data/bin/setup +8 -0
  15. data/lib/pixiebox.rb +88 -0
  16. data/lib/pixiebox/box.rb +31 -0
  17. data/lib/pixiebox/boxes/installer.rb +55 -0
  18. data/lib/pixiebox/boxes/manifest.rb +59 -0
  19. data/lib/pixiebox/cli.rb +214 -0
  20. data/lib/pixiebox/commands/add_box.rb +25 -0
  21. data/lib/pixiebox/commands/add_service.rb +27 -0
  22. data/lib/pixiebox/commands/build_service.rb +23 -0
  23. data/lib/pixiebox/commands/download_docker.rb +35 -0
  24. data/lib/pixiebox/commands/finish_install.rb +16 -0
  25. data/lib/pixiebox/commands/finish_uninstall.rb +14 -0
  26. data/lib/pixiebox/commands/get_root_permission.rb +14 -0
  27. data/lib/pixiebox/commands/initialize_project.rb +32 -0
  28. data/lib/pixiebox/commands/install_config.rb +17 -0
  29. data/lib/pixiebox/commands/install_docker.rb +55 -0
  30. data/lib/pixiebox/commands/list_boxes.rb +16 -0
  31. data/lib/pixiebox/commands/list_services.rb +16 -0
  32. data/lib/pixiebox/commands/reload_shell.rb +15 -0
  33. data/lib/pixiebox/commands/remove_service.rb +27 -0
  34. data/lib/pixiebox/commands/remove_setup_shell.rb +19 -0
  35. data/lib/pixiebox/commands/restart.rb +21 -0
  36. data/lib/pixiebox/commands/setup_shell.rb +18 -0
  37. data/lib/pixiebox/commands/ssh_instance.rb +27 -0
  38. data/lib/pixiebox/commands/start.rb +20 -0
  39. data/lib/pixiebox/commands/start_install.rb +14 -0
  40. data/lib/pixiebox/commands/start_uninstall.rb +16 -0
  41. data/lib/pixiebox/commands/stop.rb +20 -0
  42. data/lib/pixiebox/commands/update_packages.rb +46 -0
  43. data/lib/pixiebox/constants.rb +26 -0
  44. data/lib/pixiebox/dns.rb +8 -0
  45. data/lib/pixiebox/docker_compose/config.rb +59 -0
  46. data/lib/pixiebox/errors/pixiebox_error.rb +17 -0
  47. data/lib/pixiebox/handlers/stdout_handler.rb +179 -0
  48. data/lib/pixiebox/os/abstract.rb +40 -0
  49. data/lib/pixiebox/os/current_os.rb +15 -0
  50. data/lib/pixiebox/os/darwin.rb +20 -0
  51. data/lib/pixiebox/os/distro.rb +45 -0
  52. data/lib/pixiebox/os/linux.rb +21 -0
  53. data/lib/pixiebox/os/unsupported_os.rb +9 -0
  54. data/lib/pixiebox/project.rb +19 -0
  55. data/lib/pixiebox/service.rb +50 -0
  56. data/lib/pixiebox/services/installer.rb +41 -0
  57. data/lib/pixiebox/services/manifest.rb +50 -0
  58. data/lib/pixiebox/shell/bash.rb +18 -0
  59. data/lib/pixiebox/shell/ini_file.rb +38 -0
  60. data/lib/pixiebox/shell/startup_script.rb +53 -0
  61. data/lib/pixiebox/shell/zsh.rb +9 -0
  62. data/lib/pixiebox/system.rb +69 -0
  63. data/lib/pixiebox/utils/domain_event_publisher.rb +11 -0
  64. data/lib/pixiebox/utils/output.rb +105 -0
  65. data/lib/pixiebox/utils/packages.rb +35 -0
  66. data/lib/pixiebox/utils/progress_bar.rb +31 -0
  67. data/lib/pixiebox/utils/project.rb +55 -0
  68. data/lib/pixiebox/utils/shell.rb +18 -0
  69. data/lib/pixiebox/utils/spinner.rb +27 -0
  70. data/lib/pixiebox/utils/visitable.rb +9 -0
  71. data/lib/pixiebox/utils/visitor_by_os.rb +32 -0
  72. data/lib/runner.rb +51 -0
  73. data/pixiebox.gemspec +52 -0
  74. metadata +424 -0
@@ -0,0 +1,9 @@
1
+ module Pixiebox
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 Pixiebox
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 StandardError => e
15
+ display_error e
16
+ exit 1
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,50 @@
1
+ module Pixiebox
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 StandardError => e
15
+ display_error e
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 StandardError => e
23
+ display_error e
24
+ exit 1
25
+ end
26
+
27
+
28
+ def remove(type = nil)
29
+ return if type.nil?
30
+ accept(Commands::RemoveService.new(type))
31
+ accept(Commands::Restart.new)
32
+ rescue Errors::ServiceNotInstalled
33
+ display_service_not_installed type
34
+ rescue Errors::ServiceNotImplemented
35
+ display_service_not_available type
36
+ rescue StandardError => e
37
+ display_error e
38
+ exit 1
39
+ end
40
+
41
+
42
+ def list()
43
+ accept(Commands::UpdatePackages.new)
44
+ accept(Commands::ListServices.new)
45
+ rescue StandardError => e
46
+ display_error e
47
+ exit 1
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,41 @@
1
+ module Pixiebox
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 Pixiebox
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("#{os.service_packages_dir}/*").select {|f| File.directory? f}
10
+ result.map {|r| strip_path(r) }.sort!
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
+ "#{os.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,18 @@
1
+ module Pixiebox
2
+ module Shell
3
+ class Bash < StartupScript
4
+ def filename
5
+ [
6
+ '.bashrc',
7
+ '.bash_profile',
8
+ '.bash_login',
9
+ '.profile'
10
+ ].map do |script|
11
+ Pathname.new("#{os.home_dir}/#{script}")
12
+ end.select do |file|
13
+ file.exist?
14
+ end.first.to_path
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ module Pixiebox
2
+ module Shell
3
+ class IniFile
4
+ class << self
5
+ def get(os)
6
+ self.new(os)
7
+ end
8
+ end
9
+
10
+ def initialize(os)
11
+ @os = os
12
+ end
13
+
14
+ def install
15
+ TTY::File.create_file filename do |content|
16
+ "[packages]\nversion=v0.0\nlast_update=#{Time.now.to_i}\n"
17
+ end unless File.exist? filename
18
+ end
19
+
20
+
21
+ def [](key)
22
+ ini_file[key]
23
+ end
24
+
25
+
26
+ def []=(section, value)
27
+ ini_file[section.to_s] = value
28
+ ini_file.save
29
+ end
30
+
31
+ private
32
+ attr_reader :os
33
+
34
+ def filename() "#{os.config_dir}/#{Pixiebox::PIXIEBOX_INI}" end
35
+ def ini_file() @ini_file ||= ::IniFile.load(filename) end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,53 @@
1
+ module Pixiebox
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/, /\/bin\/bash:linux/
8
+ Shell::Bash.new(os)
9
+ when /\/bin\/zsh:darwin/, /\/bin\/zsh:linux/
10
+ Shell::Zsh.new(os)
11
+ else
12
+ raise Errors::ShellNotSupported, "#{os.user_shell}:#{os.to_s}"
13
+ end
14
+ end
15
+ end
16
+
17
+ attr_reader :os
18
+
19
+ def initialize(os)
20
+ @os = os
21
+ end
22
+
23
+ def install_extensions
24
+ source = "#{os.extensions_dir}/extensions.bash"
25
+ dest = os.shell_extensions
26
+
27
+ TTY::File.copy_file source, dest
28
+
29
+ TTY::File.append_to_file(
30
+ filename,
31
+ "\n#{extension}\n"
32
+ )
33
+ end
34
+
35
+
36
+ def uninstall_extensions
37
+ TTY::File.gsub_file filename, /#{Regexp.escape(extension)}/ do
38
+ "# pixiebox removed #{Time.now}"
39
+ end
40
+ end
41
+
42
+
43
+ def filename
44
+ raise ::NotImplementedError, 'must have filename'
45
+ end
46
+
47
+ private
48
+ def extension
49
+ "# added by pixiebox\nsource #{os.shell_extensions}"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,9 @@
1
+ module Pixiebox
2
+ module Shell
3
+ class Zsh < StartupScript
4
+ def filename
5
+ "#{os.home_dir}/.zshrc"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,69 @@
1
+ module Pixiebox
2
+ class System
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 install
13
+ accept(Commands::StartInstall.new)
14
+ accept(Commands::GetRootPermission.new)
15
+ accept(Commands::DownloadDocker.new)
16
+ accept(Commands::InstallDocker.new)
17
+ accept(Commands::InstallConfig.new)
18
+ accept(Commands::UpdatePackages.new)
19
+ accept(Commands::SetupShell.new)
20
+ accept(Commands::FinishInstall.new)
21
+ accept(Commands::ReloadShell.new)
22
+ rescue StandardError => e
23
+ display_error e
24
+ exit 1
25
+ end
26
+
27
+
28
+ def uninstall
29
+ accept(Commands::StartUninstall.new)
30
+ accept(Commands::RemoveSetupShell.new)
31
+ accept(Commands::FinishUninstall.new)
32
+ rescue StandardError => e
33
+ display_error e
34
+ exit 1
35
+ end
36
+
37
+
38
+ def start
39
+ accept(Commands::Start.new)
40
+ rescue StandardError => e
41
+ display_error e
42
+ exit 1
43
+ end
44
+
45
+
46
+ def stop
47
+ accept(Commands::Stop.new)
48
+ rescue StandardError => e
49
+ display_error e
50
+ exit 1
51
+ end
52
+
53
+
54
+ def restart
55
+ accept(Commands::Restart.new)
56
+ rescue StandardError => e
57
+ display_error e
58
+ exit 1
59
+ end
60
+
61
+
62
+ def ssh(service)
63
+ accept(Commands::SshInstance.new(service))
64
+ rescue StandardError => e
65
+ display_error e
66
+ exit 1
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ module Pixiebox
2
+ module Utils
3
+ module DomainEventPublisher
4
+ include Wisper::Publisher
5
+
6
+ def publish_event(event_name, *event_params)
7
+ broadcast(event_name, *event_params)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,105 @@
1
+ module Pixiebox
2
+ module Utils
3
+ module Output
4
+ def display_line(line)
5
+ thor.say line
6
+ end
7
+
8
+
9
+ def display_info(info, color=nil)
10
+ thor.say " #{info}", color
11
+ end
12
+
13
+
14
+ def display_status(status, line, log_status=true)
15
+ return if line.nil? || line.strip == ""
16
+ thor.say_status status, line, log_status
17
+ end
18
+
19
+
20
+ def display_error(e)
21
+ case e
22
+ when Errors::ProjectNotInitialized
23
+ display_project_not_initialized
24
+ when Errors::DockerError
25
+ display_docker_error
26
+ when Errors::SystemDownError
27
+ display_system_down
28
+ when Errors::ShellNotSupported
29
+ display_shell_not_supported e.message
30
+ when Errors::DistroNotSupported
31
+ display_distro_not_supported
32
+ when Errors::PixieboxNotInstalled
33
+ display_pixiebox_not_installed
34
+ when Errors::ServiceNotImplemented
35
+ display_service_not_available e.message
36
+ when Pixiebox::Errors::FileNotFoundError
37
+ display_file_not_found e.message
38
+ else
39
+ display_info(e, :red)
40
+ end
41
+ end
42
+
43
+ private
44
+ def display_project_not_initialized
45
+ display_status('error', 'no project found', :red)
46
+ display_info("Run 'pixiebox init [BOX]'", :yellow)
47
+ end
48
+
49
+
50
+ def display_box_not_available(type)
51
+ display_status('error', "#{type.capitalize} boxes are not available...yet", :red)
52
+ end
53
+
54
+
55
+ def display_service_not_available(type)
56
+ display_status('error', "#{type} service is not available...yet", :red)
57
+ end
58
+
59
+
60
+ def display_file_not_found(message)
61
+ display_status('error', message, :red)
62
+ end
63
+
64
+
65
+ def display_system_down
66
+ display_info("Pixiebox is not running!", :red)
67
+ end
68
+
69
+
70
+ def display_service_not_installed(type)
71
+ display_status('info', "#{type} not installed", :yellow)
72
+ end
73
+
74
+ def display_shell_not_supported(type)
75
+ display_status('error', "shell not supported #{type}", :red)
76
+ display_line ''
77
+
78
+ display_line "You can file a request at: #{Pixiebox::HOMEPAGE}"
79
+ display_line "and we'll get right on it!"
80
+ display_line ''
81
+ end
82
+
83
+ def display_pixiebox_not_installed
84
+ display_info "Pixiebox not installed!", :red
85
+ display_info "Run: pixiebox install", :yellow
86
+ end
87
+
88
+
89
+ def display_distro_not_supported
90
+ display_info('distro is not yet supported :(', :red)
91
+ end
92
+
93
+ def display_docker_error
94
+ display_info "Docker gave an error", :red
95
+ display_info "Check to see if docker is running", :red
96
+ display_info("Try running 'docker ps'", :yellow)
97
+ end
98
+
99
+ private
100
+ def thor
101
+ @thor ||= Thor::Shell::Color.new
102
+ end
103
+ end
104
+ end
105
+ end