pixiebox 0.1.0

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 (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,55 @@
1
+ module Pixiebox
2
+ module Boxes
3
+ class Installer
4
+ def initialize(os)
5
+ @os = os
6
+ end
7
+
8
+ def install(type)
9
+ @manifest = Manifest.new(os, type)
10
+ @manifest.check! # raises an exception if we can't find the type in the manifest
11
+
12
+ unpack_start_script
13
+ unpack_docker_files
14
+ unpack_additional_files
15
+ end
16
+
17
+ private
18
+ attr_reader :os, :manifest
19
+
20
+ def unpack_start_script
21
+ # start script
22
+ TTY::File.copy_file(
23
+ manifest.source.start_script,
24
+ manifest.dest.start_script
25
+ )
26
+
27
+ TTY::File.chmod(manifest.dest.start_script, 0777)
28
+ end
29
+
30
+ def unpack_docker_files
31
+ # docker-compose.yml
32
+ TTY::File.copy_file(
33
+ manifest.source.docker_compose,
34
+ manifest.dest.docker_compose
35
+ )
36
+
37
+ # Dockerfile
38
+ TTY::File.copy_file(
39
+ manifest.source.dockerfile,
40
+ manifest.dest.dockerfile
41
+ )
42
+ end
43
+
44
+ def unpack_additional_files
45
+ # unpack remaining in project root director
46
+ manifest.additional_files.each do |file|
47
+ TTY::File.copy_file(
48
+ file[:source],
49
+ file[:dest]
50
+ )
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ module Pixiebox
2
+ module Boxes
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.box_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(package_dir, "*"))
16
+ end
17
+
18
+
19
+ def check!
20
+ raise Errors::BoxNotImplemented unless list.include?(type)
21
+ end
22
+
23
+
24
+ def source
25
+ @source ||= OpenStruct.new(
26
+ start_script: "#{package_dir}/start",
27
+ docker_compose: "#{package_dir}/docker-compose.yml",
28
+ dockerfile: "#{package_dir}/Dockerfile"
29
+ )
30
+ end
31
+
32
+
33
+ def dest
34
+ @dest ||= OpenStruct.new(
35
+ start_script: "#{os.project_root}/#{Pixiebox::CONFIG_DIR}/start",
36
+ docker_compose: "#{os.project_root}/docker-compose.yml",
37
+ dockerfile: "#{os.project_root}/Dockerfile"
38
+ )
39
+ end
40
+
41
+ def additional_files
42
+ (package_contents - source.to_h.values).map do |file|
43
+ { source: file, dest: "#{os.project_root}/#{strip_path(file)}" }
44
+ end
45
+ end
46
+
47
+ private
48
+ attr_reader :os, :type
49
+
50
+ def package_dir
51
+ "#{os.box_packages_dir}/#{type}"
52
+ end
53
+
54
+ def strip_path(file)
55
+ file.split('/').last
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,214 @@
1
+ module Pixiebox
2
+ class ServiceSubCommands < Thor
3
+ desc 'build [SERVICE] optional', 'builds the pixiebox'
4
+ long_desc <<-LONGDESC
5
+ LONGDESC
6
+ def build(service = nil)
7
+ Pixiebox.set_verbosity !options[:silent]
8
+
9
+ Service.new(Os::CurrentOs.get).build service
10
+ rescue SignalException
11
+ exit 1
12
+ end
13
+
14
+
15
+ desc 'add [SERVICE]', 'adds a service to your box'
16
+ long_desc <<-LONGDESC
17
+ LONGDESC
18
+ def add(*services)
19
+ Pixiebox.set_verbosity !options[:silent]
20
+
21
+ Service.new(Os::CurrentOs.get).add services
22
+ rescue SignalException
23
+ exit 1
24
+ end
25
+
26
+
27
+ desc 'remove [SERVICE]', 'removes a service from your box'
28
+ long_desc <<-LONGDESC
29
+ LONGDESC
30
+ def remove(service)
31
+ Pixiebox.set_verbosity !options[:silent]
32
+
33
+ Service.new(Os::CurrentOs.get).remove service
34
+ rescue SignalException
35
+ exit 1
36
+ end
37
+
38
+
39
+ desc 'list', 'list available services'
40
+ long_desc <<-LONGDESC
41
+ LONGDESC
42
+ def list()
43
+ Service.new(Os::CurrentOs.get).list
44
+ rescue SignalException
45
+ exit 1
46
+ end
47
+ end
48
+
49
+ class DnsSubCommands < Thor
50
+ desc 'add', 'add entry to DNS'
51
+ long_desc <<-LONGDESC
52
+ LONGDESC
53
+ method_option :port, default: '3000'
54
+ def add(entry)
55
+ puts "coming soon"
56
+ end
57
+ end
58
+
59
+ class CLI < Thor
60
+ include Utils::Output
61
+
62
+ def self.exit_on_failure?
63
+ true
64
+ end
65
+
66
+ class_option :silent, desc: 'Silence output', type: :boolean
67
+
68
+ #desc 'dns SUBCOMMAND', 'do things with the DNS'
69
+ #long_desc <<-LONGDESC
70
+ #LONGDESC
71
+ #subcommand 'dns', Pixiebox::DnsSubCommands
72
+
73
+
74
+ desc 'service SUBCOMMAND', 'do things with the SERVICES'
75
+ long_desc <<-LONGDESC
76
+ LONGDESC
77
+ subcommand 'service', Pixiebox::ServiceSubCommands
78
+
79
+
80
+ desc 'version', 'displays current version'
81
+ def version
82
+ say "Pixiebox: #{Pixiebox::VERSION}"
83
+ say "Packages: #{Pixiebox::Utils::Packages.new(Os::CurrentOs.get).installed_version[1..-1]}"
84
+ rescue SignalException
85
+ exit 1
86
+ end
87
+
88
+
89
+ desc 'install', 'installs pixiebox'
90
+ long_desc <<-LONGDESC
91
+ LONGDESC
92
+ def install
93
+ Pixiebox.set_verbosity !options[:silent]
94
+ System.new(Os::CurrentOs.get).install
95
+ rescue SignalException
96
+ exit 1
97
+ end
98
+
99
+
100
+ desc 'update', 'udpates pixiebox'
101
+ long_desc <<-LONGDESC
102
+ LONGDESC
103
+ def update
104
+ Pixiebox.set_verbosity !options[:silent]
105
+ System.new(Os::CurrentOs.get).install
106
+ rescue SignalException
107
+ exit 1
108
+ end
109
+
110
+
111
+ desc 'uninstall', 'removes pixiebox'
112
+ long_desc <<-LONGDESC
113
+ LONGDESC
114
+ def uninstall
115
+ Pixiebox.set_verbosity !options[:silent]
116
+ System.new(Os::CurrentOs.get).uninstall
117
+ rescue SignalException
118
+ exit 1
119
+ end
120
+
121
+
122
+ desc 'init [BOX]', 'initialize directory for use with pixiebox'
123
+ long_desc <<-LONGDESC
124
+ LONGDESC
125
+ def init(box)
126
+ Pixiebox.set_verbosity !options[:silent]
127
+
128
+ os = Os::CurrentOs.get
129
+
130
+ Project.new(os).init
131
+ Box.new(os).install box
132
+ Service.new(os).build
133
+ System.new(os).start
134
+ rescue SignalException
135
+ exit 1
136
+ end
137
+
138
+
139
+ desc 'start', 'start pixiebox'
140
+ long_desc <<-LONGDESC
141
+ LONGDESC
142
+ def start()
143
+ Pixiebox.set_verbosity !options[:silent]
144
+ System.new(Os::CurrentOs.get).start
145
+ rescue SignalException
146
+ exit 1
147
+ end
148
+
149
+
150
+ desc 'stop', 'stop pixiebox'
151
+ long_desc <<-LONGDESC
152
+ LONGDESC
153
+ def stop()
154
+ Pixiebox.set_verbosity !options[:silent]
155
+ System.new(Os::CurrentOs.get).stop
156
+ rescue SignalException
157
+ exit 1
158
+ end
159
+
160
+
161
+ desc 'restart', 'restart pixiebox'
162
+ long_desc <<-LONGDESC
163
+ LONGDESC
164
+ def restart()
165
+ Pixiebox.set_verbosity !options[:silent]
166
+ System.new(Os::CurrentOs.get).restart
167
+ rescue SignalException
168
+ exit 1
169
+ end
170
+
171
+
172
+ desc 'ssh [SERVICE]', 'open shell to service'
173
+ long_desc <<-LONGDESC
174
+ LONGDESC
175
+ def ssh(service)
176
+ System.new(Os::CurrentOs.get).ssh service
177
+ rescue SignalException
178
+ exit 1
179
+ end
180
+
181
+
182
+ desc 'boxes', 'list of available boxes'
183
+ long_desc <<-LONGDESC
184
+ LONGDESC
185
+ def boxes()
186
+ Box.new(Os::CurrentOs.get).list
187
+ rescue SignalException
188
+ exit 1
189
+ end
190
+
191
+
192
+ desc 'status', 'current status of containers'
193
+ long_desc <<-LONGDESC
194
+ LONGDESC
195
+ def status()
196
+ system "docker-compose ps"
197
+ rescue SignalException
198
+ exit 1
199
+ end
200
+
201
+
202
+ desc 'reset', 'reset pixiebox containers'
203
+ long_desc <<-LONGDESC
204
+ LONGDESC
205
+ def reset()
206
+ display_info('Cleaning stopped containers', :green)
207
+ display_status('execute', 'container prune')
208
+ system "docker container prune"
209
+ system "docker volume prune"
210
+ rescue SignalException
211
+ exit 1
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,25 @@
1
+ module Pixiebox
2
+ module Commands
3
+ class AddBox < Pixiebox::Utils::VisitorByOs
4
+ def initialize(type)
5
+ @type = type
6
+ end
7
+
8
+ def visit_darwin subject
9
+ publish_event :add_box_start, type
10
+
11
+ raise Errors::ProjectNotInitialized unless os.project_initialized?
12
+
13
+ Boxes::Installer.new(os).install(type)
14
+ end
15
+
16
+
17
+ def visit_linux subject
18
+ visit_darwin subject
19
+ end
20
+
21
+ private
22
+ attr_reader :type
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ module Pixiebox
2
+ module Commands
3
+ class AddService < Pixiebox::Utils::VisitorByOs
4
+ def initialize(service)
5
+ @service = service
6
+ end
7
+
8
+ def visit_darwin subject
9
+ publish_event :add_service_start, service
10
+
11
+ raise Errors::ProjectNotInitialized unless os.project_initialized?
12
+
13
+ Services::Installer.new(os).install(service)
14
+
15
+ publish_event :add_service_completed, service
16
+ end
17
+
18
+
19
+ def visit_linux subject
20
+ visit_darwin subject
21
+ end
22
+
23
+ private
24
+ attr_reader :service
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ module Pixiebox
2
+ module Commands
3
+ class BuildService < Pixiebox::Utils::VisitorByOs
4
+ def initialize(service)
5
+ @service = service
6
+ end
7
+
8
+ def visit_darwin subject
9
+ publish_event :build_service_start, service
10
+ system "docker-compose build #{service} #{Pixiebox.output}"
11
+ publish_event :build_service_stop
12
+ end
13
+
14
+
15
+ def visit_linux subject
16
+ visit_darwin subject
17
+ end
18
+
19
+ private
20
+ attr_reader :service
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module Pixiebox
2
+ module Commands
3
+ class DownloadDocker < Pixiebox::Utils::VisitorByOs
4
+ def visit_darwin subject
5
+ unless os.docker_installed?
6
+ stream = open(os.docker_url,
7
+ content_length_proc: lambda { |total| publish_event :download_docker_start, total },
8
+ progress_proc: lambda { |step| publish_event :download_progress, step }
9
+ )
10
+
11
+ IO.copy_stream( stream, os.docker_installer )
12
+ publish_event :download_docker_complete
13
+ end
14
+ end
15
+
16
+
17
+ def visit_linux subject
18
+ unless os.docker_compose_installed?
19
+ stream = open(os.docker_compose_url,
20
+ content_length_proc: lambda { |total| publish_event :download_docker_compose_start, total },
21
+ progress_proc: lambda { |step| publish_event :download_progress, step }
22
+ )
23
+
24
+ IO.copy_stream( stream, "#{os.tmp_dir}/docker_compose" )
25
+ publish_event :download_docker_compose_complete
26
+
27
+ system("#{os.su} 'mv #{os.tmp_dir}/docker_compose #{os.docker_compose}'")
28
+ TTY::File.chmod(os.docker_compose, 'u=x')
29
+ else
30
+ publish_event :docker_present, os.docker_compose_version?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end