lbhrr 1.1.1 → 2.32.1

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: 3f63fcc372df8525489ddf02ca8a023112a031ae24b5306614500022e556ccc8
4
+ data.tar.gz: a94d96eb246401e944fa044950f4e128dbb4cf16bc45e508f274e6879f88d2cc
5
5
  SHA512:
6
- metadata.gz: d7b52bdd9bfb3b0c0c492b621119a613407c5b5266289aa06246e1a86a2cf30f12eefb15693d718e1e0ccc5654f3235cd9aadfa63a7567c33b8a23ef916fd08f
7
- data.tar.gz: 942c57b8f351cadff9ff01366122c53ab30e827b6ac00847fcfac498dbffc2d43e2195491265ccd4276dbade8c9172c98c50b153723299187575551e613ce5a9
6
+ metadata.gz: cec7337f7de060c7b98749195f9b2fe137735ffc88933077f8172c046b1e4867ab3cb76ffa9646de1a14dce3cb3b96469b824eaa94d53d6f35c06dde18921751
7
+ data.tar.gz: 4f62371636aadfb7d53168e1f4631b028c53e73291040c365b2b16fd459ef0270dc5d123af4445d0ed7487381c21bce79ba1d420f8d10b2d6b85e725736976bb
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
- }
166
-
167
- YAML.dump(example_local_config)
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"
231
+
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,247 @@ 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
-
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
271
 
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
- end
232
-
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"]
304
+ desc "assemble", "Build an application using the configuration from config/manifest.yml into a ruby gem"
305
+ def assemble(env = "next", version = nil)
306
+ config = load_configuration
307
+ name = config["name"]
308
+ image = config["image"]
238
309
 
239
- if name.nil?
310
+ containerize
240
311
 
241
- unless manifest?
242
- puts "no manifest found!"
243
- return
244
- end
312
+ # Check if we're in the root directory
313
+ if manifest?
314
+ # Create the build directory if it doesn't exist
315
+ if Dir.exist?("build")
316
+ FileUtils.rm_r("build")
317
+ end
245
318
 
246
- name = config["name"]
247
- end
248
-
249
- puts "Destroying app: #{name}"
250
- `ssh #{user}@#{host} 'harbr destroy #{name}'`
319
+ FileUtils.mkdir_p("build/src")
251
320
 
252
- puts "App #{name} has been successfully destroyed."
253
- end
321
+ # Copy all files and folders to the build directory
322
+ Dir.glob("*").each do |item|
323
+ next if item == "build" # Skip the build directory itself
324
+ next if item == ".git" # Skip the .git directory
325
+ next if item == "tmp" # Skip the config directory
254
326
 
255
- desc "lift", "Deploy an application using the configuration from config/manifest.yml to next"
256
- def lift
257
- if manifest?
327
+ FileUtils.cp_r(item, "build/src/#{item}")
328
+ end
258
329
 
259
- package
330
+ # Parameters for gemspec
331
+ gem_name = config["name"]
332
+ gem_version = version.nil? ? config["version"] : version
260
333
 
334
+ # Ensure the build directory exists
335
+ FileUtils.mkdir_p("build/lib")
261
336
 
262
- config = load_configuration
263
- host = config["host"]
264
- user = config["user"]
265
- raise "Host configuration missing" unless host
337
+ # Define the template files and their target locations
338
+ template_dir = File.expand_path(File.join(File.dirname(__FILE__), "../", "templates"))
266
339
 
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)
340
+ templates = {
341
+ "#{template_dir}/lib/panamax.rb.erb" => "build/lib/#{gem_name}.rb",
342
+ "#{template_dir}/lib/rubygems_plugin.rb.erb" => "build/lib/rubygems_plugin.rb",
343
+ "#{template_dir}/panamax.gemspec.erb" => "build/#{gem_name}.gemspec"
344
+ }
269
345
 
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
346
+ # Process each template
347
+ templates.each do |template, target|
348
+ process_template(template, target, binding)
349
+ end
273
350
 
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}'" : ""
351
+ `cd build && gem build #{gem_name}.gemspec`
352
+ notify_terminal("Assembled #{name}", "Lbhhr")
353
+ else
354
+ puts "config/manifest file not found. Please ensure you are in the root directory of your project."
355
+ end
356
+ end
282
357
 
358
+ end
283
359
 
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}'`
287
360
 
288
- # Rsync files to the new version directory, excluding files as per .gitignore
289
- rsync_command = "rsync -avz #{exclude_option} ./ #{user}@#{host}:#{destination_path}"
361
+ desc "drop", "Destroy an app and remove all traces"
362
+ def drop(name = nil)
363
+ with_error_handling do
364
+ return unless yes?("Are you sure you want to drop this app? This action cannot be undone. (y/n)")
365
+
366
+ # Load configuration and retrieve the name if not provided
367
+ config = load_configuration unless name
368
+ name ||= config["name"]
369
+
370
+ progressing("Drop") do
371
+ if manifest?
372
+ # Check if the LXC container exists
373
+ if `lxc list`.include?(name)
374
+ # Commands to run if the container exists
375
+ `lxc delete #{name} --force`
376
+ `harbr container delete #{name}`
377
+ `harbr commit`
378
+ end
379
+ end
380
+ end
381
+ end
382
+ end
290
383
 
291
- if `#{rsync_command}`
292
- puts "Successfully deployed application version #{version} to #{host}"
293
- deployed(local_manifest_path, version)
384
+ desc "logs", "Show logs for the container"
385
+ method_option :live, type: :boolean, aliases: "-l", desc: "Process in live mode"
386
+ def logs(name = nil)
387
+ with_error_handling do
388
+ config = load_configuration
389
+ name = config["name"]
390
+ if options[:live]
391
+ exec "lxc exec #{name} -- tail -f /var/log/container/live/current"
294
392
  else
295
- puts "Failed to deploy application version #{version} to #{host}"
393
+ exec "lxc exec #{name} -- tail -f /var/log/container/next/current"
296
394
  end
297
-
298
- else
299
- puts "no manifest found!"
300
395
  end
301
-
302
396
  end
303
397
 
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)
308
- config = load_configuration
309
- host = config["host"]
310
- user = config["user"]
311
-
312
- if name.nil?
313
- unless manifest?
314
- puts "no manifest found!"
315
- return
398
+ desc "hoist", "Deploy an application using the configuration from config/manifest.yml to next"
399
+ method_option :major, type: :boolean, aliases: "-ma", desc: "Increment major version"
400
+ method_option :msg, type: :boolean, aliases: "-msg", desc: "set the commit message"
401
+ method_option :minor, type: :boolean, aliases: "-mi", desc: "Increment minor version"
402
+ method_option :feature, type: :boolean, aliases: "-fea", desc: "Increment minor version"
403
+ method_option :fix, type: :boolean, aliases: "-f", desc: "Increment minor version"
404
+ method_option :release, type: :boolean, aliases: "-rel", desc: "Increment minor version"
405
+ method_option :patch, type: :boolean, aliases: "-pa", desc: "Increment minor version"
406
+ def hoist(name = nil)
407
+ with_error_handling do
408
+ config = load_configuration
409
+
410
+ msg =nil
411
+ if options[:msg]
412
+ msg = ask("commit massage: ")
316
413
  end
317
414
 
318
- container_name = config["name"]
415
+ focus = nil
319
416
 
320
- else
321
- container_name = name
322
- end
417
+ focus = if options[:major] || options[:release]
418
+ "major"
419
+ elsif options[:minor] || options[:feature]
420
+ "minor"
421
+ elsif options[:patch] || options[:fix]
422
+ "patch"
423
+ else
424
+ "patch"
425
+ end
323
426
 
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
427
+ version = increment_version(config["version"], focus.to_sym)
330
428
 
429
+ modify_manifest do |config|
430
+ config["version"] = version
431
+ end
331
432
 
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
433
+ progressing("Hoist") do
434
+ name = config["name"]
435
+ gem = "#{name}-#{version}.gem"
436
+ assemble "next", version
437
+ `lxc file push -rp build/#{gem} #{name}/var/gems/`
438
+ `lxc exec #{name} -- /root/.rbenv/shims/gem install /var/gems/#{gem} --no-document`
439
+ `lxc exec #{name} -- /root/.rbenv/shims/gem install /var/gems/#{gem} --no-document`
440
+ `lxc exec #{name} -- sv restart next`
441
+ `lxc exec #{name} -- sv restart next.ws`
340
442
 
443
+ modify_manifest do |config|
444
+ config["next"] = version
445
+ end
341
446
 
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"]
447
+ clean_up(name)
347
448
 
348
- if name.nil?
349
- unless manifest?
350
- puts "no manifest found!"
351
- return
449
+ change = "RELEASE #{version}"
450
+ commit("#{change}\n\n#{msg}\n\n Hoisted #{name} version #{version}")
451
+
452
+ ok("https://next.#{config['host']}/ok",grace: 25) do
453
+ notify_terminal(" #{name} version #{version} is up on next!", "Lbhhr")
454
+ end
352
455
  end
353
- name = config["name"]
354
456
  end
355
- puts `ssh #{user}@#{host} 'harbr deploy #{name}'`
356
- end
357
-
358
- desc "rollback", "rollback an application using the configuration from config/manifest.yml"
359
- def rollback(name=nil)
457
+ end
360
458
 
361
- config = load_configuration
362
- host = config["host"]
363
- user = config["user"]
459
+ desc "deploy", "Deploy an application using the configuration from config/manifest.yml to live"
460
+ def deploy(name = nil)
461
+ with_error_handling do
462
+ progressing("Deploy") do
463
+ config = load_configuration
464
+ name = name.nil? ? config["name"] : name
465
+ if config["next"].nil?
466
+ puts "No deploymnt available"
467
+ else
468
+ `lxc exec #{name} -- bash -c 'if [ -d /var/www/app/container/rollback ]; then rm -rf /var/www/app/container/rollback; fi'`
469
+ `lxc exec #{name} -- mv /var/www/app/container/live /var/www/app/container/rollback`
470
+ `lxc exec #{name} -- cp -r /var/www/app/container/next /var/www/app/container/live`
471
+ `lxc exec #{name} -- sv restart live`
472
+ `lxc exec #{name} -- sv restart ws`
473
+ modify_manifest do |config|
474
+ config["rollback"] = config["live"]
475
+ config["live"] = config["next"]
476
+ config["rolledback"] = false
477
+ end
478
+ end
479
+ commit("Deployed #{name} version #{config["live"]} to live")
480
+
481
+ ok("https://#{config['host']}/ok",grace: 15) do
482
+ notify_terminal(" #{name} version #{version} is up on live!", "Lbhhr")
483
+ end
364
484
 
365
- if name.nil?
366
- unless manifest?
367
- puts "no manifest found!"
368
- return
369
485
  end
370
- name = config["name"]
371
486
  end
372
- puts `ssh #{user}@#{host} 'harbr rollback #{name}'`
373
- end
487
+ end
374
488
 
489
+ desc "version", "Display the version of Lbhrr"
490
+ def version
491
+ with_error_handling do
492
+ puts "lbhrr version #{Lbhrr::VERSION}"
493
+ end
494
+ end
375
495
 
376
- def self.exit_on_failure?
377
- true
496
+ desc "update", "Display the version of Lbhrr"
497
+ def update
498
+ with_error_handling do
499
+ `gem update lbhrr --conservative`
500
+ end
378
501
  end
502
+
379
503
  end
380
504
 
381
505
  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.32.1"
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.32.1
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-26 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