lbhrr 1.0.27 → 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: d9316b3555eea12d2403c4b53f2294a09652458267b803938f725667b27b1ac4
4
- data.tar.gz: aecf3fa3443f1ee16c92e59ae8936631e4e6d489194edad83fdfe316240c40ae
3
+ metadata.gz: 3f63fcc372df8525489ddf02ca8a023112a031ae24b5306614500022e556ccc8
4
+ data.tar.gz: a94d96eb246401e944fa044950f4e128dbb4cf16bc45e508f274e6879f88d2cc
5
5
  SHA512:
6
- metadata.gz: 032ad826d862ae97d42e9ab573ce72ff00d985c3492931513b3de411e431ed08e5a6e0ea7e63d555c85c0d338b13c78907c584835ef9e9ed961f7141682a03e3
7
- data.tar.gz: 6be6169070b182d3f54d254c81aa53391f49bee00d45e3d9a0c6fca6b08e0299c84ae714635793366dbfe93b4a5703ccf78271fe1450de66cd84b84a041ded21
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,175 +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
- raise "Configuration error: Host, User, or Version missing" unless host && port && user && version > 0
19
-
20
- # Check for a git repository
21
- unless `git rev-parse --is-inside-work-tree > /dev/null 2>&1`
22
- raise "No Git repository found in the current directory"
23
- end
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
24
39
 
25
- # Delete vendor directory if it exists
26
- vendor_path = File.join(Dir.pwd, "vendor")
27
- FileUtils.rm_rf(vendor_path) if Dir.exist?(vendor_path)
28
- `bundle config set --local path 'vendor/bundle'`
29
- system "bundle install" or raise "Bundle install failed"
30
- # Check if the repository is clean
31
- puts "Git repository is dirty, committing changes..."
32
- system("git add .") or raise "Failed to add changes to Git"
33
- system("git commit -m 'packaged #{version}'") or raise "Failed to commit changes to Git"
34
- puts "Packaging completed successfully."
40
+ delay = fibonacci(i)
41
+ sleep(delay)
35
42
 
43
+
44
+ end
36
45
  end
37
46
 
38
- def amend_last_commit(new_message)
39
- # Ensure we are in a git repository
40
- system("git rev-parse --git-dir > /dev/null 2>&1") or raise "Not a git repository"
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
63
+ end
64
+ end
41
65
 
42
- # Amend the last commit with the new message
43
- system("git commit --amend -m \"#{new_message}\"") or raise "Failed to amend the last commit"
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
44
84
 
45
- puts "Successfully amended the last commit."
46
- rescue => e
47
- puts "Error during commit amend: #{e.message}"
85
+ "#{major}.#{minor}.#{patch}"
48
86
  end
49
87
 
50
- def create_gitignore
51
- gitignore_path = File.join(Dir.pwd, ".gitignore")
52
- return if File.exist?(gitignore_path)
53
-
54
- gitignore_content = '
55
- # Ignore bundler config and installed gems.
56
- /.bundle
57
- # Ignore all logfiles and tempfiles.
58
- /log/*
59
- /tmp/*
60
- !/log/.keep
61
- !/tmp/.keep
62
-
63
- # Ignore other unneeded files.
64
- *.pid
65
- *.swap
66
- *.gem
67
- *.rbc
68
- .DS_Store
69
- .idea
70
- .byebug_history
71
- '
72
-
73
- File.write(gitignore_path, gitignore_content.strip)
74
- puts ".gitignore created for Rack project."
75
- rescue => e
76
- puts "Error creating .gitignore: #{e.message}"
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
93
+
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
101
+
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
107
+
108
+ # Clear the progress line
109
+ print "#{name} is in progress.. #{spinner.peek}\r"
110
+ nil
77
111
  end
78
112
 
79
- def deployed(local_manifest_path, version)
80
- # Git add all changes
81
- increment_version(local_manifest_path, version)
82
- system("git add .") or raise "Failed to add changes to Git"
83
- # Commit changes with a message
84
- commit_message = "Deployed version #{version}"
85
- amend_last_commit commit_message
86
- # Create a Git tag for the version
87
- tag_message = "Deployment for version #{version}"
88
- system("git tag -a 'v#{version}' -m '#{tag_message}'") or raise "Failed to create Git tag"
89
-
90
- puts "Deployment changes committed and tagged as v#{version}."
91
- rescue => e
92
- 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
93
146
  end
94
147
 
95
- def create_example_global_config
96
- example_global_config = {
97
- "user" => "root",
98
- "host" => "harbr.zero2one.ee"
99
- }
100
- 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/*`
101
155
  end
102
156
 
103
- def create_run_file(type)
157
+ def modify_manifest
158
+ file_path = "config/manifest.yml" # Update the path if necessary
159
+
160
+ # Read the YAML file
161
+ if File.exist?(file_path)
162
+ yaml_content = YAML.load_file(file_path)
104
163
 
105
- service_content = <<-RUBY
106
- #!/usr/bin/env ruby
107
- require 'bundler/inline'
164
+ # Yield the hash to the block for modification
165
+ yield(yaml_content) if block_given?
108
166
 
109
- gemfile do
110
- source 'https://rubygems.org'
111
- #gem 'kafkr', require: true
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}"
112
171
  end
172
+ end
113
173
 
114
- puts 'Gems installed and loaded!'
174
+ def notify_terminal(message, title)
175
+ `terminal-notifier -message "#{message}" -title "#{title}" -contentImage "crane.png"`
176
+ end
115
177
 
116
- loop do
117
- puts 'ok!'
118
- sleep 1
119
- end
178
+ def containerized?(name)
179
+ `lxc list -c n -f csv`.include? name
180
+ end
120
181
 
121
- RUBY
182
+ def create_container(name, image = "panamax")
183
+ return if containerized? name
184
+ config = load_configuration
122
185
 
123
- if type == "web"
124
- run_file_path = File.join(Dir.pwd, "exe", "run")
125
- web_run_file_content = "#!/bin/sh\n HARBR_ENV=$2 bundle exec puma -p $1"
126
- exe_directory = File.join(Dir.pwd, "exe")
186
+ # Set default image if not specified
187
+ image = config["image"].nil? ? "panamax" : config["image"]
127
188
 
128
- Dir.mkdir(exe_directory) unless Dir.exist?(exe_directory)
129
- File.write(run_file_path, web_run_file_content)
130
- File.chmod(0o755, run_file_path) # Set executable permission
131
- puts "Created ./exe/run file."
132
- end
189
+ `lxc launch #{image} #{name}` unless containerized? name
133
190
 
134
- if type == "service"
135
- run_file_path = File.join(Dir.pwd, "exe", "run")
136
- service_run_file_content = "#!/bin/sh\n HARBR_ENV=$2 ruby service"
137
- exe_directory = File.join(Dir.pwd, "exe")
138
-
139
- Dir.mkdir(exe_directory) unless Dir.exist?(exe_directory)
140
- File.write(run_file_path, service_run_file_content)
141
- File.chmod(0o755, run_file_path) # Set executable permission
142
- puts "Created ./exe/run file."
143
-
144
- File.write("service", service_content)
145
- File.chmod(0o755, "service") # Set executable permission
146
- puts "Created ./service file."
147
-
191
+ find_container_ip(name) do |ip_address|
192
+ `harbr container add #{name} #{ip_address}`
193
+
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
201
+
202
+ `harbr commit`
148
203
  end
204
+ end
149
205
 
150
-
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
211
+
212
+ def manifest?
213
+ File.exist? File.join(Dir.pwd, "config", "manifest.yml")
214
+ end
151
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}'`
152
221
  rescue => e
153
- puts "Error creating ./exe/run file: #{e.message}"
222
+ puts "Error during commit amend: #{e.message}"
154
223
  end
155
224
 
156
- def create_example_local_config(type)
157
- example_local_config = {
158
- "name" => File.basename(Dir.pwd),
159
- "version" => "0",
160
- "type" => type,
161
- "port" => "#{File.basename(Dir.pwd)}.app",
162
- "host" => "#{File.basename(Dir.pwd)}.harbr.zero2one.ee"
163
- }
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"
164
231
 
165
- YAML.dump(example_local_config)
232
+ puts "Successfully amended the last commit."
233
+ rescue => e
234
+ puts "Error during commit amend: #{e.message}"
166
235
  end
167
236
 
168
237
  def load_configuration
169
238
  global_config_dir = File.expand_path("~/.config/harbr")
170
- global_config_path = File.join(global_config_dir, "harbr.manifest.yml")
239
+ global_config_path = File.join(global_config_dir, "manifest.yml")
171
240
  local_config_path = File.join(Dir.pwd, "config", "manifest.yml")
172
-
173
241
  # Ensure global configuration exists
174
242
  unless File.exist?(global_config_path)
175
243
  FileUtils.mkdir_p(global_config_dir) unless Dir.exist?(global_config_dir)
@@ -185,195 +253,253 @@ class LbhrrCLI < Thor
185
253
 
186
254
  if File.exist? local_config_path
187
255
  local_config = YAML.load_file(local_config_path) || {}
188
- global_config.merge(local_config)
256
+ global_config.merge!(local_config)
189
257
  end
190
258
 
191
259
  global_config
192
260
  end
193
261
 
194
- def increment_version(manifest_path, current_version)
195
- new_version = current_version + 1
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
270
+ end
196
271
 
197
- manifest = YAML.load_file(manifest_path)
198
- manifest["version"] = new_version
199
- File.write(manifest_path, manifest.to_yaml)
200
- puts "Version incremented to #{new_version}"
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
201
299
  end
202
- end
203
300
 
204
- desc "init", "Initialize project with .gitignore"
205
- method_option :type, type: :string, enum: ['web', 'service'], default: 'web', desc: "Specify the type of process"
206
- def init
207
- local_config_path = File.join(Dir.pwd, "config", "manifest.yml")
208
301
 
209
- unless File.exist?(local_config_path)
210
- FileUtils.mkdir_p(File.dirname(local_config_path)) unless Dir.exist?(File.dirname(local_config_path))
211
- File.write(local_config_path, create_example_local_config(options[:type]))
212
- end
213
- # Load and merge configurations
214
- local_config = YAML.load_file(local_config_path) || {}
215
- create_gitignore
216
- create_run_file(options[:type])
217
302
 
218
303
 
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"]
309
+
310
+ containerize
219
311
 
220
- # Include other initialization tasks if necessary
221
- 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
222
318
 
223
- desc "containers", "list all containers"
224
- def containers
225
- config = load_configuration
226
- host = config["host"]
227
- user = config["user"]
228
- puts `ssh #{user}@#{host} 'harbr containers'`
229
- end
319
+ FileUtils.mkdir_p("build/src")
230
320
 
231
- desc "drop", "Destroy an app and remove all traces"
232
- def drop(name=nil)
233
- config = load_configuration
234
- host = config["host"]
235
- user = config["user"]
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
236
326
 
237
- if name.nil?
327
+ FileUtils.cp_r(item, "build/src/#{item}")
328
+ end
238
329
 
239
- unless manifest?
240
- puts "no manifest found!"
241
- return
242
- end
330
+ # Parameters for gemspec
331
+ gem_name = config["name"]
332
+ gem_version = version.nil? ? config["version"] : version
243
333
 
244
- name = config["name"]
245
- end
334
+ # Ensure the build directory exists
335
+ FileUtils.mkdir_p("build/lib")
246
336
 
247
- puts "Destroying app: #{name}"
248
- `ssh #{user}@#{host} 'harbr destroy #{name}'`
337
+ # Define the template files and their target locations
338
+ template_dir = File.expand_path(File.join(File.dirname(__FILE__), "../", "templates"))
249
339
 
250
- puts "App #{name} has been successfully destroyed."
251
- end
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
+ }
252
345
 
253
- desc "lift", "Deploy an application using the configuration from config/manifest.yml to next"
254
- def lift
255
- if manifest?
256
-
257
- package
258
-
346
+ # Process each template
347
+ templates.each do |template, target|
348
+ process_template(template, target, binding)
349
+ end
259
350
 
260
- config = load_configuration
261
- host = config["host"]
262
- user = config["user"]
263
- raise "Host configuration missing" unless host
264
-
265
- local_manifest_path = File.join(Dir.pwd, "config", "manifest.yml")
266
- raise "Local manifest file not found at #{local_manifest_path}" unless File.exist?(local_manifest_path)
267
-
268
- local_config = YAML.load_file(local_manifest_path) || {}
269
- version = local_config["version"].to_i
270
- raise "Version not specified in manifest.yml" unless version
271
-
272
- basename = File.basename(Dir.pwd)
273
- base_directory = "/var/harbr/containers/#{basename}"
274
- versions_directory = "#{base_directory}/versions"
275
- data_directory = "/var/dddr/#{basename}/"
276
- destination_path = "#{versions_directory}/#{version}"
277
- # Prepare the rsync exclude option using .gitignore
278
- gitignore_path = File.join(Dir.pwd, ".gitignore")
279
- exclude_option = File.exist?(gitignore_path) ? "--exclude='.git' --exclude-from='#{gitignore_path}'" : ""
280
-
281
-
282
- # Check and create the versions directory on the server
283
- `ssh #{user}@#{host} 'mkdir -p #{versions_directory}'`
284
- `ssh #{user}@#{host} 'mkdir -p #{data_directory}'`
285
-
286
- # Rsync files to the new version directory, excluding files as per .gitignore
287
- rsync_command = "rsync -avz #{exclude_option} ./ #{user}@#{host}:#{destination_path}"
288
-
289
- if `#{rsync_command}`
290
- puts "Successfully deployed application version #{version} to #{host}"
291
- deployed(local_manifest_path, version)
351
+ `cd build && gem build #{gem_name}.gemspec`
352
+ notify_terminal("Assembled #{name}", "Lbhhr")
292
353
  else
293
- puts "Failed to deploy application version #{version} to #{host}"
354
+ puts "config/manifest file not found. Please ensure you are in the root directory of your project."
294
355
  end
295
-
296
- else
297
- puts "no manifest found!"
298
356
  end
299
357
 
300
358
  end
301
359
 
302
- desc "logs", "Show logs for a container"
303
- method_option :live, type: :boolean, aliases: "-l", desc: "Process in live mode"
304
- method_option :next, type: :boolean, default: true, aliases: "-n", desc: "Process in next mode"
305
- def logs(name=nil)
306
- config = load_configuration
307
- host = config["host"]
308
- user = config["user"]
309
-
310
- if name.nil?
311
- unless manifest?
312
- puts "no manifest found!"
313
- return
314
- end
315
-
316
- container_name = config["name"]
317
360
 
318
- else
319
- container_name = name
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
320
381
  end
382
+ end
321
383
 
322
- if options[:live]
323
- exec "ssh #{user}@#{host} 'harbr peek #{container_name} --live'"
324
- else
325
- exec "ssh #{user}@#{host} 'harbr peek #{container_name} --next'"
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"
392
+ else
393
+ exec "lxc exec #{name} -- tail -f /var/log/container/next/current"
394
+ end
326
395
  end
327
396
  end
328
397
 
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
329
409
 
330
- desc "activity", "harbr logs "
331
- def activity
332
- container_name = File.basename(Dir.pwd)
333
- config = load_configuration
334
- host = config["host"]
335
- user = config["user"]
336
- exec "ssh #{user}@#{host} 'harbr logs'"
337
- end
410
+ msg =nil
411
+ if options[:msg]
412
+ msg = ask("commit massage: ")
413
+ end
338
414
 
415
+ focus = nil
339
416
 
340
- desc "hoist", "Deploy an application using the configuration from config/manifest.yml to live"
341
- def hoist(name=nil)
342
- config = load_configuration
343
- host = config["host"]
344
- user = config["user"]
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
345
426
 
346
- if name.nil?
347
- unless manifest?
348
- puts "no manifest found!"
349
- return
427
+ version = increment_version(config["version"], focus.to_sym)
428
+
429
+ modify_manifest do |config|
430
+ config["version"] = version
431
+ end
432
+
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`
442
+
443
+ modify_manifest do |config|
444
+ config["next"] = version
445
+ end
446
+
447
+ clean_up(name)
448
+
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
350
455
  end
351
- name = config["name"]
352
456
  end
353
- puts `ssh #{user}@#{host} 'harbr deploy #{name}'`
354
- end
355
-
356
- desc "rollback", "rollback an application using the configuration from config/manifest.yml"
357
- def rollback(name=nil)
358
-
359
- config = load_configuration
360
- host = config["host"]
361
- user = config["user"]
362
-
363
- if name.nil?
364
- unless manifest?
365
- puts "no manifest found!"
366
- return
457
+ end
458
+
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
484
+
367
485
  end
368
- name = config["name"]
369
486
  end
370
- puts `ssh #{user}@#{host} 'harbr rollback #{name}'`
371
- end
487
+ end
372
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
373
495
 
374
- def self.exit_on_failure?
375
- true
496
+ desc "update", "Display the version of Lbhrr"
497
+ def update
498
+ with_error_handling do
499
+ `gem update lbhrr --conservative`
500
+ end
376
501
  end
502
+
377
503
  end
378
504
 
379
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.0.27"
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.0.27
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: 2023-12-23 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.4.21
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