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,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