lbhrr 1.1.1 → 2.33.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d227165ee1807a1d93fa79f40934df7b04738dd33ee5d1e052e15570862218af
4
- data.tar.gz: 31ff59aadaa7d98b6a8e1e6a52496f444902bb87910a9f818d713efc8b7bfda4
3
+ metadata.gz: 5a5a72e033c32aae92732521d690ca1bb95db44ffbea53d9be161f183e83b2bd
4
+ data.tar.gz: d063d071b65b6a56d29774185d5a3f975cecd7d491e90344d3adf8e5c8fc2286
5
5
  SHA512:
6
- metadata.gz: d7b52bdd9bfb3b0c0c492b621119a613407c5b5266289aa06246e1a86a2cf30f12eefb15693d718e1e0ccc5654f3235cd9aadfa63a7567c33b8a23ef916fd08f
7
- data.tar.gz: 942c57b8f351cadff9ff01366122c53ab30e827b6ac00847fcfac498dbffc2d43e2195491265ccd4276dbade8c9172c98c50b153723299187575551e613ce5a9
6
+ metadata.gz: a4b0ec574e5d44c09db1ed6b91ea3267bf22a8d4dc382692f9984e53b63a095f216c2ec8c99be737299cc4e84a9791298d57af1e5d1f2c845b814e703e237ea1
7
+ data.tar.gz: d174498ec46033204e0685b279b1e801b1812c3db81999d8bb732256caad47399b491abb7f3aa5d3408f30eaa3060b5767686beacd0728971b4d970d90e4eb9d
data/.DS_Store ADDED
Binary file
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.2
data/crane.png ADDED
Binary file
data/exe/lbhrr CHANGED
@@ -1,177 +1,243 @@
1
1
  #!/usr/bin/env ruby
2
+
3
+ require "fileutils"
4
+ require "logger"
5
+ require "erb"
6
+ require "open3"
7
+ require "io/console"
2
8
  require_relative "../lib/lbhrr"
3
9
 
4
10
  class LbhrrCLI < Thor
11
+ include Thor::Actions
12
+
13
+ # Error handling
14
+ def self.exit_on_failure?
15
+ true
16
+ end
17
+
5
18
  no_commands do
19
+ require 'net/http'
20
+ require 'uri'
6
21
 
7
- def manifest?
8
- File.exist? File.join(Dir.pwd, "config","manifest.yml")
22
+ def fibonacci(n)
23
+ [21,34,55][n]
9
24
  end
10
25
 
11
- def package
12
- # Load configuration
13
- config = load_configuration
14
- host = config["host"]
15
- user = config["user"]
16
- port = config["port"]
17
- version = config["version"].to_i
18
-
19
- # Check for a git repository
20
- unless `git rev-parse --is-inside-work-tree > /dev/null 2>&1`
21
- raise "No Git repository found in the current directory"
26
+ def ok(url,grace: 0)
27
+ retries = 2
28
+ sleep(grace)
29
+ (0..retries).each do |i|
30
+ uri = URI(url)
31
+ response = Net::HTTP.get_response(uri)
32
+
33
+ if response.is_a?(Net::HTTPSuccess)
34
+ yield if block_given?
35
+ break
36
+ else
37
+ puts "Response was not 200, it was #{response.code}., check logs gor website"
38
+ end
39
+
40
+ delay = fibonacci(i)
41
+ sleep(delay)
42
+
43
+
22
44
  end
45
+ end
23
46
 
24
- if File.exist? "Gemfile"
25
- vendor_path = File.join(Dir.pwd, "vendor")
26
- FileUtils.rm_rf(vendor_path) if Dir.exist?(vendor_path)
27
- `bundle config set --local path 'vendor/bundle'`
28
- system "bundle install" or raise "Bundle install failed"
47
+ # Example usage:
48
+ def with_error_handling
49
+ # Ensure the ~/.lbhrr directory exists
50
+ log_dir = File.expand_path("~/.lbhrr")
51
+ FileUtils.mkdir_p(log_dir) unless Dir.exist?(log_dir)
52
+
53
+ # Setup logger
54
+ logger = Logger.new("#{log_dir}/error.log")
55
+
56
+ begin
57
+ yield
58
+ rescue Interrupt
59
+ #logger.error("Operation interrupted by Ctrl+C")
60
+ rescue => e
61
+ logger.error("Error occurred: #{e.class}: #{e.message}")
62
+ raise
29
63
  end
64
+ end
30
65
 
31
- # Check if the repository is clean
32
- puts "Git repository is dirty, committing changes..."
33
- system("git add .") or raise "Failed to add changes to Git"
34
- system("git commit -m 'packaged #{version}'")
35
- puts "Packaging completed successfully."
66
+ def increment_version(version, focus = :minor)
67
+ major, minor, patch = version.split(".").map(&:to_i)
68
+
69
+ case focus
70
+ when :major
71
+ major += 1
72
+ # Reset minor and patch to 0 when major version increments
73
+ minor = 0
74
+ patch = 0
75
+ when :minor
76
+ minor += 1
77
+ # Reset patch to 0 when minor version increments
78
+ patch = 0
79
+ when :patch
80
+ patch += 1
81
+ else
82
+ raise ArgumentError, "Invalid focus: #{focus}. Valid options are :major, :minor, :patch."
83
+ end
36
84
 
85
+ "#{major}.#{minor}.#{patch}"
37
86
  end
38
87
 
39
- def amend_last_commit(new_message)
40
- # Ensure we are in a git repository
41
- system("git rev-parse --git-dir > /dev/null 2>&1") or raise "Not a git repository"
88
+ def progressing(name = "Task")
89
+ # Start the long-running task in a separate thread, yielding to the given block
90
+ task_thread = Thread.new do
91
+ yield if block_given? # Execute the block representing the long-running task
92
+ end
42
93
 
43
- # Amend the last commit with the new message
44
- system("git commit --amend -m \"#{new_message}\"") or raise "Failed to amend the last commit"
94
+ spinner = Enumerator.new do |e|
95
+ rectangles = ["[ ]","[=]", "[==]", "[===]", "[===]", "[==","[=]","[ ]"]
96
+ loop do
97
+ rectangles.each { |rect| e.yield rect }
98
+ rectangles.reverse.each { |rect| e.yield rect }
99
+ end
100
+ end
45
101
 
46
- puts "Successfully amended the last commit."
47
- rescue => e
48
- puts "Error during commit amend: #{e.message}"
49
- end
102
+ until task_thread.join(0.1)
103
+ print "#{name} is in progress.. \r#{spinner.next}"
104
+ $stdout.flush
105
+ sleep(0.1)
106
+ end
50
107
 
51
- def create_gitignore
52
- gitignore_path = File.join(Dir.pwd, ".gitignore")
53
- return if File.exist?(gitignore_path)
54
-
55
- gitignore_content = '
56
- # Ignore bundler config and installed gems.
57
- /.bundle
58
- # Ignore all logfiles and tempfiles.
59
- /log/*
60
- /tmp/*
61
- !/log/.keep
62
- !/tmp/.keep
63
-
64
- # Ignore other unneeded files.
65
- *.pid
66
- *.swap
67
- *.gem
68
- *.rbc
69
- .DS_Store
70
- .idea
71
- .byebug_history
72
- '
73
-
74
- File.write(gitignore_path, gitignore_content.strip)
75
- puts ".gitignore created for Rack project."
76
- rescue => e
77
- puts "Error creating .gitignore: #{e.message}"
108
+ # Clear the progress line
109
+ print "#{name} is in progress.. #{spinner.peek}\r"
110
+ nil
78
111
  end
79
112
 
80
- def deployed(local_manifest_path, version)
81
- # Git add all changes
82
- increment_version(local_manifest_path, version)
83
- system("git add .") or raise "Failed to add changes to Git"
84
- # Commit changes with a message
85
- commit_message = "Deployed version #{version}"
86
- amend_last_commit commit_message
87
- # Create a Git tag for the version
88
- tag_message = "Deployment for version #{version}"
89
- system("git tag -a 'v#{version}' -m '#{tag_message}'") or raise "Failed to create Git tag"
90
-
91
- puts "Deployment changes committed and tagged as v#{version}."
92
- rescue => e
93
- puts "Error during post-deployment process: #{e.message}"
113
+ def find_container_ip(container_name)
114
+ initial_backoff_intervals = [5, 8, 13, 21]
115
+ ip_backoff_intervals = [1, 2, 3, 5, 8]
116
+ ip_address = nil
117
+
118
+ # First, check if the container is running
119
+ container_running = false
120
+ initial_backoff_intervals.each do |interval|
121
+ output, status = Open3.capture2("lxc list -f csv | grep #{container_name}")
122
+ if status.success? && !output.empty? && output.split(",")[1].strip == "RUNNING"
123
+ container_running = true
124
+ break
125
+ end
126
+ sleep(interval)
127
+ end
128
+
129
+ # If container is running, look for the IP address
130
+ if container_running
131
+ ip_backoff_intervals.each do |interval|
132
+ output, status = Open3.capture2("lxc list -f csv | grep #{container_name}")
133
+ if status.success? && !output.empty?
134
+ data = output.split(",")
135
+ ip_address = data[2].split(" ").first
136
+ if !ip_address.nil? && !ip_address.empty?
137
+ yield(ip_address) if block_given?
138
+ break
139
+ end
140
+ end
141
+ sleep(interval)
142
+ end
143
+ end
144
+
145
+ ip_address
94
146
  end
95
147
 
96
- def create_example_global_config
97
- example_global_config = {
98
- "user" => "root",
99
- "host" => "harbr.zero2one.ee"
100
- }
101
- YAML.dump(example_global_config)
148
+ def clean_up(name = nil)
149
+ # Remove the build directory
150
+ if Dir.exist?("build")
151
+ FileUtils.rm_r("build")
152
+ end
153
+ # Remove gems on the container
154
+ `lxc exec #{name} -- rm -rf /var/gems/*`
102
155
  end
103
156
 
104
- def create_run_file(type)
157
+ def modify_manifest
158
+ file_path = "config/manifest.yml" # Update the path if necessary
105
159
 
106
- service_content = <<-RUBY
107
- #!/usr/bin/env ruby
160
+ # Read the YAML file
161
+ if File.exist?(file_path)
162
+ yaml_content = YAML.load_file(file_path)
108
163
 
109
- require 'bundler/inline'
164
+ # Yield the hash to the block for modification
165
+ yield(yaml_content) if block_given?
110
166
 
111
- gemfile do
112
- source 'https://rubygems.org'
113
- #gem 'kafkr', require: true
114
- end
167
+ # Write the changes back to the YAML file
168
+ File.write(file_path, yaml_content.to_yaml)
169
+ else
170
+ puts "File not found: #{file_path}"
171
+ end
172
+ end
115
173
 
116
- puts 'Gems installed and loaded!'
174
+ def notify_terminal(message, title)
175
+ `terminal-notifier -message "#{message}" -title "#{title}" -contentImage "crane.png"`
176
+ end
117
177
 
118
- loop do
119
- puts 'ok!'
120
- sleep 1
121
- end
122
- RUBY
178
+ def containerized?(name)
179
+ `lxc list -c n -f csv`.include? name
180
+ end
123
181
 
124
- if type == "web"
125
- run_file_path = File.join(Dir.pwd, "exe", "run")
126
- web_run_file_content = "#!/bin/sh\n HARBR_ENV=$2 bundle exec puma -p $1"
127
- exe_directory = File.join(Dir.pwd, "exe")
182
+ def create_container(name, image = "panamax")
183
+ return if containerized? name
184
+ config = load_configuration
128
185
 
129
- Dir.mkdir(exe_directory) unless Dir.exist?(exe_directory)
130
- File.write(run_file_path, web_run_file_content)
131
- File.chmod(0o755, run_file_path) # Set executable permission
132
- puts "Created ./exe/run file."
133
- end
186
+ # Set default image if not specified
187
+ image = config["image"].nil? ? "panamax" : config["image"]
134
188
 
135
- if type == "service"
136
- run_file_path = File.join(Dir.pwd, "exe", "run")
137
- service_run_file_content = "#!/bin/sh\n HARBR_ENV=$2 ruby service"
138
- exe_directory = File.join(Dir.pwd, "exe")
189
+ `lxc launch #{image} #{name}` unless containerized? name
139
190
 
140
- Dir.mkdir(exe_directory) unless Dir.exist?(exe_directory)
141
- File.write(run_file_path, service_run_file_content)
142
- File.chmod(0o755, run_file_path) # Set executable permission
143
- puts "Created ./exe/run file."
191
+ find_container_ip(name) do |ip_address|
192
+ `harbr container add #{name} #{ip_address}`
144
193
 
145
- File.write("service", service_content)
146
- File.chmod(0o755, "service") # Set executable permission
147
- puts "Created ./service file."
194
+ if config["host"].nil?
195
+ `harbr host add #{name} 9292 #{name}.harbr.zero2one.ee`
196
+ `harbr host add #{name} 9393 next.#{name}.harbr.zero2one.ee`
197
+ else
198
+ `harbr host add #{name} 9292 #{config["host"]}`
199
+ `harbr host add #{name} 9393 next.#{config["host"]}`
200
+ end
148
201
 
202
+ `harbr commit`
149
203
  end
204
+ end
150
205
 
206
+ # Method to process ERB templates and write to build directory
207
+ def process_template(template_path, target_path, binding)
208
+ content = ERB.new(File.read(template_path)).result(binding)
209
+ File.write(target_path, content)
210
+ end
151
211
 
212
+ def manifest?
213
+ File.exist? File.join(Dir.pwd, "config", "manifest.yml")
214
+ end
152
215
 
216
+ def commit(new_message)
217
+ # Ensure we are in a git repository
218
+ system("git rev-parse --git-dir > /dev/null 2>&1") or raise "Not a git repository"
219
+ # commit changes with the new message
220
+ `git commit -am '#{new_message}'`
153
221
  rescue => e
154
- puts "Error creating ./exe/run file: #{e.message}"
222
+ puts "Error during commit amend: #{e.message}"
155
223
  end
156
224
 
157
- def create_example_local_config(type)
158
- example_local_config = {
159
- "name" => File.basename(Dir.pwd),
160
- "version" => "0",
161
- "type" => type,
162
- "port" => "#{File.basename(Dir.pwd)}.app",
163
- "host" => "#{File.basename(Dir.pwd)}.harbr.zero2one.ee",
164
- "host_aliases" => []
165
- }
225
+ def amend_last_commit(new_message)
226
+ # Ensure we are in a git repository
227
+ system("git rev-parse --git-dir > /dev/null 2>&1") or raise "Not a git repository"
228
+
229
+ # Amend the last commit with the new message
230
+ system("git commit --amend -m \"#{new_message}\"") or raise "Failed to amend the last commit"
166
231
 
167
- YAML.dump(example_local_config)
232
+ puts "Successfully amended the last commit."
233
+ rescue => e
234
+ puts "Error during commit amend: #{e.message}"
168
235
  end
169
236
 
170
237
  def load_configuration
171
238
  global_config_dir = File.expand_path("~/.config/harbr")
172
239
  global_config_path = File.join(global_config_dir, "manifest.yml")
173
240
  local_config_path = File.join(Dir.pwd, "config", "manifest.yml")
174
-
175
241
  # Ensure global configuration exists
176
242
  unless File.exist?(global_config_path)
177
243
  FileUtils.mkdir_p(global_config_dir) unless Dir.exist?(global_config_dir)
@@ -193,189 +259,248 @@ RUBY
193
259
  global_config
194
260
  end
195
261
 
196
- def increment_version(manifest_path, current_version)
197
- new_version = current_version + 1
198
-
199
- manifest = YAML.load_file(manifest_path)
200
- manifest["version"] = new_version
201
- File.write(manifest_path, manifest.to_yaml)
202
- puts "Version incremented to #{new_version}"
262
+ desc "containerize", "Create a container for an app"
263
+ def containerize
264
+ config = load_configuration
265
+ name = config["name"]
266
+ image = config["image"]
267
+ if manifest?
268
+ create_container(name, image)
269
+ end
203
270
  end
204
- end
205
271
 
206
- desc "init", "Initialize project with .gitignore"
207
- method_option :type, type: :string, enum: ['web', 'service'], default: 'web', desc: "Specify the type of process"
208
- def init
209
- local_config_path = File.join(Dir.pwd, "config", "manifest.yml")
210
-
211
- unless File.exist?(local_config_path)
212
- FileUtils.mkdir_p(File.dirname(local_config_path)) unless Dir.exist?(File.dirname(local_config_path))
213
- File.write(local_config_path, create_example_local_config(options[:type]))
272
+ desc "rollback", "rollback an application using the configuration from config/manifest.yml"
273
+ def rollback(name = nil)
274
+ with_error_handling do
275
+ progressing("Roll back") do
276
+ config = load_configuration
277
+ name = name.nil? ? config["name"] : name
278
+ rolled_back = config["rolledback"]
279
+
280
+ if config["rolledback"] == true
281
+ puts "No rollback available"
282
+ else
283
+ `lxc exec #{name} -- bash -c 'if [ -d /var/www/app/container/live ]; then rm /var/www/app/container/live; fi'`
284
+
285
+ `lxc exec #{name} -- mv /var/www/app/container/rollback /var/www/app/container/live`
286
+ `lxc exec #{name} -- bash -c 'if [ -d /var/www/app/container/rollback ]; then rm /var/www/app/container/rollback; fi'`
287
+ `lxc exec #{name} -- sv restart live`
288
+ modify_manifest do |config|
289
+ config["live"] = config["rollback"]
290
+ config["rolledback"] = true
291
+ end
292
+ end
293
+ commit("Rolled back #{name} to version #{config["rollback"]} on live")
294
+ ok("https://#{config['host']}/ok",grace: 15) do
295
+ notify_terminal("#{name} version #{config['rollback']} is up on live!", "Lbhhr")
296
+ end
297
+ end
298
+ end
214
299
  end
215
- # Load and merge configurations
216
- local_config = YAML.load_file(local_config_path) || {}
217
- create_gitignore
218
- create_run_file(options[:type])
219
300
 
220
301
 
221
302
 
222
- # Include other initialization tasks if necessary
223
- end
224
303
 
225
- desc "containers", "list all containers"
226
- def containers
227
- config = load_configuration
228
- host = config["host"]
229
- user = config["user"]
230
- puts `ssh #{user}@#{host} 'harbr containers'`
231
304
  end
232
305
 
233
- desc "drop", "Destroy an app and remove all traces"
234
- def drop(name=nil)
235
- config = load_configuration
236
- host = config["host"]
237
- user = config["user"]
238
-
239
- if name.nil?
240
306
 
241
- unless manifest?
242
- puts "no manifest found!"
243
- return
307
+ desc "drop", "Destroy an app and remove all traces"
308
+ def drop(name = nil)
309
+ with_error_handling do
310
+ return unless yes?("Are you sure you want to drop this app? This action cannot be undone. (y/n)")
311
+
312
+ # Load configuration and retrieve the name if not provided
313
+ config = load_configuration unless name
314
+ name ||= config["name"]
315
+
316
+ progressing("Drop") do
317
+ if manifest?
318
+ # Check if the LXC container exists
319
+ if `lxc list`.include?(name)
320
+ # Commands to run if the container exists
321
+ `lxc delete #{name} --force`
322
+ `harbr container delete #{name}`
323
+ `harbr commit`
324
+ end
325
+ end
244
326
  end
327
+ end
328
+ end
245
329
 
330
+ desc "logs", "Show logs for the container"
331
+ method_option :live, type: :boolean, aliases: "-l", desc: "Process in live mode"
332
+ def logs(name = nil)
333
+ with_error_handling do
334
+ config = load_configuration
246
335
  name = config["name"]
336
+ if options[:live]
337
+ exec "lxc exec #{name} -- tail -f /var/log/container/live/current"
338
+ else
339
+ exec "lxc exec #{name} -- tail -f /var/log/container/next/current"
340
+ end
247
341
  end
248
-
249
- puts "Destroying app: #{name}"
250
- `ssh #{user}@#{host} 'harbr destroy #{name}'`
251
-
252
- puts "App #{name} has been successfully destroyed."
253
342
  end
254
343
 
255
- desc "lift", "Deploy an application using the configuration from config/manifest.yml to next"
256
- def lift
257
- if manifest?
344
+ desc "hoist", "Deploy an application using the configuration from config/manifest.yml to next"
345
+ method_option :major, type: :boolean, aliases: "-ma", desc: "Increment major version"
346
+ method_option :msg, type: :boolean, aliases: "-msg", desc: "set the commit message"
347
+ method_option :minor, type: :boolean, aliases: "-mi", desc: "Increment minor version"
348
+ method_option :feature, type: :boolean, aliases: "-fea", desc: "Increment minor version"
349
+ method_option :fix, type: :boolean, aliases: "-f", desc: "Increment minor version"
350
+ method_option :release, type: :boolean, aliases: "-rel", desc: "Increment minor version"
351
+ method_option :patch, type: :boolean, aliases: "-pa", desc: "Increment minor version"
352
+ def hoist(name = nil)
353
+ with_error_handling do
354
+ config = load_configuration
258
355
 
259
- package
356
+ msg =nil
357
+ if options[:msg]
358
+ msg = ask("commit massage: ")
359
+ end
260
360
 
361
+ focus = nil
261
362
 
262
- config = load_configuration
263
- host = config["host"]
264
- user = config["user"]
265
- raise "Host configuration missing" unless host
363
+ focus = if options[:major] || options[:release]
364
+ "major"
365
+ elsif options[:minor] || options[:feature]
366
+ "minor"
367
+ elsif options[:patch] || options[:fix]
368
+ "patch"
369
+ else
370
+ "patch"
371
+ end
266
372
 
267
- local_manifest_path = File.join(Dir.pwd, "config", "manifest.yml")
268
- raise "Local manifest file not found at #{local_manifest_path}" unless File.exist?(local_manifest_path)
373
+ version = increment_version(config["version"], focus.to_sym)
269
374
 
270
- local_config = YAML.load_file(local_manifest_path) || {}
271
- version = local_config["version"].to_i
272
- raise "Version not specified in manifest.yml" unless version
375
+ modify_manifest do |config|
376
+ config["version"] = version
377
+ end
273
378
 
274
- basename = File.basename(Dir.pwd)
275
- base_directory = "/var/harbr/containers/#{basename}"
276
- versions_directory = "#{base_directory}/versions"
277
- data_directory = "/var/dddr/#{basename}/"
278
- destination_path = "#{versions_directory}/#{version}"
279
- # Prepare the rsync exclude option using .gitignore
280
- gitignore_path = File.join(Dir.pwd, ".gitignore")
281
- exclude_option = File.exist?(gitignore_path) ? "--exclude='.git' --exclude-from='#{gitignore_path}'" : ""
379
+ progressing("Hoist") do
380
+ name = config["name"]
381
+ gem = "#{name}-#{version}.gem"
382
+ assemble "next", version
383
+ `lxc file push -rp build/#{gem} #{name}/var/gems/`
384
+ `lxc exec #{name} -- /root/.rbenv/shims/gem install /var/gems/#{gem} --no-document`
385
+ `lxc exec #{name} -- /root/.rbenv/shims/gem install /var/gems/#{gem} --no-document`
386
+ `lxc exec #{name} -- sv restart next`
387
+ `lxc exec #{name} -- sv restart next.ws`
282
388
 
389
+ modify_manifest do |config|
390
+ config["next"] = version
391
+ end
283
392
 
284
- # Check and create the versions directory on the server
285
- `ssh #{user}@#{host} 'mkdir -p #{versions_directory}'`
286
- `ssh #{user}@#{host} 'mkdir -p #{data_directory}'`
393
+ clean_up(name)
287
394
 
288
- # Rsync files to the new version directory, excluding files as per .gitignore
289
- rsync_command = "rsync -avz #{exclude_option} ./ #{user}@#{host}:#{destination_path}"
395
+ change = "RELEASE #{version}"
396
+ commit("#{change}\n\n#{msg}\n\n Hoisted #{name} version #{version}")
290
397
 
291
- if `#{rsync_command}`
292
- puts "Successfully deployed application version #{version} to #{host}"
293
- deployed(local_manifest_path, version)
294
- else
295
- puts "Failed to deploy application version #{version} to #{host}"
398
+ ok("https://next.#{config['host']}/ok",grace: 25) do
399
+ notify_terminal(" #{name} version #{version} is up on next!", "Lbhhr")
400
+ end
296
401
  end
297
-
298
- else
299
- puts "no manifest found!"
300
402
  end
403
+ end
404
+
405
+ desc "deploy", "Deploy an application using the configuration from config/manifest.yml to live"
406
+ def deploy(name = nil)
407
+ with_error_handling do
408
+ progressing("Deploy") do
409
+ config = load_configuration
410
+ name = name.nil? ? config["name"] : name
411
+ if config["next"].nil?
412
+ puts "No deploymnt available"
413
+ else
414
+ `lxc exec #{name} -- bash -c 'if [ -d /var/www/app/container/rollback ]; then rm -rf /var/www/app/container/rollback; fi'`
415
+ `lxc exec #{name} -- mv /var/www/app/container/live /var/www/app/container/rollback`
416
+ `lxc exec #{name} -- cp -r /var/www/app/container/next /var/www/app/container/live`
417
+ `lxc exec #{name} -- sv restart live`
418
+ `lxc exec #{name} -- sv restart ws`
419
+ modify_manifest do |config|
420
+ config["rollback"] = config["live"]
421
+ config["live"] = config["next"]
422
+ config["rolledback"] = false
423
+ end
424
+ end
425
+ commit("Deployed #{name} version #{config["live"]} to live")
426
+
427
+ ok("https://#{config['host']}/ok",grace: 15) do
428
+ notify_terminal(" #{name} version #{version} is up on live!", "Lbhhr")
429
+ end
301
430
 
431
+ end
432
+ end
302
433
  end
303
434
 
304
- desc "logs", "Show logs for a container"
305
- method_option :live, type: :boolean, aliases: "-l", desc: "Process in live mode"
306
- method_option :next, type: :boolean, default: true, aliases: "-n", desc: "Process in next mode"
307
- def logs(name=nil)
435
+ desc "assemble", "Build an application using the configuration from config/manifest.yml into a ruby gem"
436
+ def assemble(env = "next", version = nil)
308
437
  config = load_configuration
309
- host = config["host"]
310
- user = config["user"]
438
+ name = config["name"]
439
+ image = config["image"]
440
+
441
+ containerize
311
442
 
312
- if name.nil?
313
- unless manifest?
314
- puts "no manifest found!"
315
- return
443
+ # Check if we're in the root directory
444
+ if manifest?
445
+ # Create the build directory if it doesn't exist
446
+ if Dir.exist?("build")
447
+ FileUtils.rm_r("build")
316
448
  end
317
449
 
318
- container_name = config["name"]
450
+ FileUtils.mkdir_p("build/src")
319
451
 
320
- else
321
- container_name = name
322
- end
452
+ # Copy all files and folders to the build directory
453
+ Dir.glob("*").each do |item|
454
+ next if item == "build" # Skip the build directory itself
455
+ next if item == ".git" # Skip the .git directory
456
+ next if item == "tmp" # Skip the config directory
323
457
 
324
- if options[:live]
325
- exec "ssh #{user}@#{host} 'harbr peek #{container_name} --live'"
326
- else
327
- exec "ssh #{user}@#{host} 'harbr peek #{container_name} --next'"
328
- end
329
- end
458
+ FileUtils.cp_r(item, "build/src/#{item}")
459
+ end
330
460
 
461
+ # Parameters for gemspec
462
+ gem_name = config["name"]
463
+ gem_version = version.nil? ? config["version"] : version
331
464
 
332
- desc "activity", "harbr logs "
333
- def activity
334
- container_name = File.basename(Dir.pwd)
335
- config = load_configuration
336
- host = config["host"]
337
- user = config["user"]
338
- exec "ssh #{user}@#{host} 'harbr logs'"
339
- end
465
+ # Ensure the build directory exists
466
+ FileUtils.mkdir_p("build/lib")
340
467
 
468
+ # Define the template files and their target locations
469
+ template_dir = File.expand_path(File.join(File.dirname(__FILE__), "../", "templates"))
341
470
 
342
- desc "hoist", "Deploy an application using the configuration from config/manifest.yml to live"
343
- def hoist(name=nil)
344
- config = load_configuration
345
- host = config["host"]
346
- user = config["user"]
471
+ templates = {
472
+ "#{template_dir}/lib/panamax.rb.erb" => "build/lib/#{gem_name}.rb",
473
+ "#{template_dir}/lib/rubygems_plugin.rb.erb" => "build/lib/rubygems_plugin.rb",
474
+ "#{template_dir}/panamax.gemspec.erb" => "build/#{gem_name}.gemspec"
475
+ }
347
476
 
348
- if name.nil?
349
- unless manifest?
350
- puts "no manifest found!"
351
- return
477
+ # Process each template
478
+ templates.each do |template, target|
479
+ process_template(template, target, binding)
352
480
  end
353
- name = config["name"]
354
- end
355
- puts `ssh #{user}@#{host} 'harbr deploy #{name}'`
356
- end
357
481
 
358
- desc "rollback", "rollback an application using the configuration from config/manifest.yml"
359
- def rollback(name=nil)
482
+ `cd build && gem build #{gem_name}.gemspec`
483
+ notify_terminal("Assembled #{name}", "Lbhhr")
484
+ else
485
+ puts "config/manifest file not found. Please ensure you are in the root directory of your project."
486
+ end
487
+ end
360
488
 
361
- config = load_configuration
362
- host = config["host"]
363
- user = config["user"]
364
489
 
365
- if name.nil?
366
- unless manifest?
367
- puts "no manifest found!"
368
- return
369
- end
370
- name = config["name"]
490
+ desc "version", "Display the version of Lbhrr"
491
+ def version
492
+ with_error_handling do
493
+ puts "lbhrr version #{Lbhrr::VERSION}"
371
494
  end
372
- puts `ssh #{user}@#{host} 'harbr rollback #{name}'`
373
- end
374
-
495
+ end
375
496
 
376
- def self.exit_on_failure?
377
- true
497
+ desc "update", "Display the version of Lbhrr"
498
+ def update
499
+ with_error_handling do
500
+ `gem update lbhrr --conservative`
501
+ end
378
502
  end
503
+
379
504
  end
380
505
 
381
506
  LbhrrCLI.start(ARGV)
@@ -0,0 +1 @@
1
+ d2914e65-5f28-492f-9615-4f00fb29e437
@@ -0,0 +1,5 @@
1
+ L9l8YThIoCo83pL/5hZ5mrNTzRRCdUBuxXFYZxe5ZUSC0yeKn3tq11znnEaWXrWFiqaV62V8xhpHWBJo1B9gLA==
2
+ 5cmFh3rph/f/5dJr8MK8do6VyW44B5naEQg8iTHMaE1eXbLaS5lrZ9Co+VuybfQPkocGkPeYT4b55Ii7jzvDtw==
3
+ vk/l4x1F9rcoJXdZoF3XIod68atgQZ9LeS3VRkZOmgQkA77FhqtZqXjPEo9/dVlz7CiS1P50jhg1SkdeFO5e5A==
4
+ S7phDwdvAtXd4h6sjr/W+9uhGakSwObf3kAdyA30wQeajXY2d1oAygDXtr6bMEv5F5WfgbD0nz4vlPyO+e4Tuw==
5
+ XanoLNMHjZM9LirLNYxnmFRZNDcWB7FqP1/MvE7Wxwa362mQi3wTwsvFsIE6c3yOv7WcokzgSMlmseD/BBX/Yg==
data/lib/lbhrr/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lbhrr
4
- VERSION = "1.1.1"
4
+ VERSION = "2.33.0"
5
5
  end
@@ -0,0 +1,4 @@
1
+ class <%= gem_name.capitalize %>
2
+ DESTINATION = ENV.fetch("DEPLOYMENT_DESTINATION", "/var/www/app/container/")
3
+ ENV=ENV.fetch("DEPLOYMENT_ENV", "<%= env %>")
4
+ end
@@ -0,0 +1,41 @@
1
+ require 'prettyprint'
2
+
3
+ Gem.pre_install do |installer|
4
+ if installer.spec.metadata.dig("container") == "panamax"
5
+ env = installer.spec.metadata.dig("env")
6
+ destination = File.join(installer.spec.metadata.dig("destination"), env)
7
+ src = File.expand_path(File.join(File.dirname(__FILE__), '..', 'src'))
8
+ system("rm -rf #{destination}")
9
+ puts "deploying #{installer.spec.name} to #{destination}"
10
+ end
11
+
12
+ end
13
+
14
+ Gem.post_install do |installer|
15
+ if installer.spec.metadata.dig("container") == "panamax"
16
+ env = installer.spec.metadata.dig("env")
17
+ destination = File.join(installer.spec.metadata.dig("destination"), env)
18
+ src = File.expand_path(File.join(File.dirname(__FILE__), '..', 'src'))
19
+
20
+
21
+ if env == "live"
22
+ puts "symlink files to #{destination}"
23
+ system("ln -sf #{src} #{destination}")
24
+ else
25
+ puts "copy files #{destination}"
26
+ system("cp -rf #{src} #{destination}")
27
+ puts "copy uploads"
28
+ live = File.join(installer.spec.metadata.dig("destination"), "live")
29
+ system("cp -rf #{live}/public/uploads/ #{destination}/public/uploads/")
30
+ puts "uploads synced"
31
+ end
32
+
33
+ if File.exist?("#{destination}/bin/hoisted")
34
+ system("chmod +x #{destination}/bin/hoisted")
35
+ system("cd #{destination} && ./bin/hoisted")
36
+ end
37
+
38
+ puts "deployed #{installer.spec.name} to #{destination}"
39
+ end
40
+
41
+ end
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+
3
+ require_relative 'lib/<%= gem_name%>'
4
+ Gem::Specification.new do |s|
5
+ s.name = '<%= gem_name %>'
6
+ s.version = '<%= gem_version %>'
7
+ s.authors = ["Delaney Burke"]
8
+ s.email = "delaney@zero2one.ee"
9
+ s.homepage = "http://zero2one.ee/gems/<%= gem_name%>"
10
+ s.summary = "<%= gem_name %> container desscripton"
11
+ s.description = "<%= gem_name %> container"
12
+ s.required_rubygems_version = ">= 1.3.6"
13
+ s.files = Dir['lib/**/*', 'src/**/*'].reject { |f| File.directory?(f) }
14
+ # s.add_dependency 'some-gem'
15
+ # s.extra_rdoc_files = ['README.md', 'LICENSE']
16
+ s.license = 'MIT'
17
+ s.metadata = {
18
+ "container" => "panamax",
19
+ "env" => <%= gem_name.capitalize %>::ENV,
20
+ "destination" => <%= gem_name.capitalize %>::DESTINATION
21
+ }
22
+ end
23
+
24
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lbhrr
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 2.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delaney Kuldvee Burke
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-03 00:00:00.000000000 Z
11
+ date: 2024-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ssh
@@ -34,9 +34,10 @@ executables:
34
34
  extensions: []
35
35
  extra_rdoc_files: []
36
36
  files:
37
+ - ".DS_Store"
37
38
  - ".gitignore"
38
- - ".gitlab-ci.yml"
39
39
  - ".rspec"
40
+ - ".ruby-version"
40
41
  - ".standard.yml"
41
42
  - CHANGELOG.md
42
43
  - CODE_OF_CONDUCT.md
@@ -47,13 +48,18 @@ files:
47
48
  - Rakefile
48
49
  - bin/console
49
50
  - bin/setup
50
- - config/manifest.yml
51
+ - crane.png
51
52
  - exe/lbhrr
52
53
  - hero.png
53
54
  - lbhrr.gemspec
55
+ - lib/.kafkr/acknowledged_messages.txt
56
+ - lib/.kafkr/message_queue.txt
54
57
  - lib/lbhrr.rb
55
58
  - lib/lbhrr/version.rb
56
59
  - sig/lbhrr.rbs
60
+ - templates/lib/panamax.rb.erb
61
+ - templates/lib/rubygems_plugin.rb.erb
62
+ - templates/panamax.gemspec.erb
57
63
  homepage: https://github.com/dekubu/lbhrr
58
64
  licenses:
59
65
  - MIT
@@ -76,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
82
  - !ruby/object:Gem::Version
77
83
  version: '0'
78
84
  requirements: []
79
- rubygems_version: 3.5.3
85
+ rubygems_version: 3.5.5
80
86
  signing_key:
81
87
  specification_version: 4
82
88
  summary: A CLI tool for deploying and managing Rack applications.
data/.gitlab-ci.yml DELETED
@@ -1,10 +0,0 @@
1
- default:
2
- image: ruby:3.2.2
3
-
4
- before_script:
5
- - gem install bundler -v 2.4.21
6
- - bundle install
7
-
8
- example_job:
9
- script:
10
- - bundle exec rake
data/config/manifest.yml DELETED
@@ -1,5 +0,0 @@
1
- ---
2
- name: lbhrr
3
- version: 1
4
- port:
5
- host: lbhrr.harbr.zero2one.ee