Skip to content

Instantly share code, notes, and snippets.

@dux

dux/_

Last active January 6, 2023 18:20
Show Gist options
  • Save dux/3d68f2301c1823107e9a59700d6cebb4 to your computer and use it in GitHub Desktop.
Save dux/3d68f2301c1823107e9a59700d6cebb4 to your computer and use it in GitHub Desktop.
Capistrano replacement via common rake tasks
you will need
* hash_wia gem https://github.com/dux/hash_wia
* https://github.com/amazing-print/amazing_print
# to fully deploy application
rake remote:deploy
load 'lib/remote_host.rb'
###
RemoteHost.add :app, '[email protected]:/home/user/app', log: 'log/production.log'
RemoteHost.add :db, '[email protected]', config: '/etc/postgresql/12/main/pg_hba.conf', log: '/var/log/postgresql/postgresql-12-main.log.1'
###
# create remote tasks, pass server argument if you want to toogle server
def rtask *args, &block
name = args.shift
desc args.shift if args.first.is_a?(String)
task name, args do |_, argumnets|
RemoteHost.new argumnets, &block
puts ''
end
end
def app_test
run 'bundle exec lux e :ok'
end
###
task :remote do
puts 'Servers'
ap RemoteHost::HOSTS
end
namespace :remote do
rtask :bash, 'bash shell in app root', :server do
run 'bash -i'
end
rtask :console, 'App console (rails or postgre)', :server do
run 'bundle exec lux c' if host? :app
run 'psql "%s"' % postgres_url if host? :db
end
rtask :caddy, 'Edit caddy config' do
run 'sudo vim /etc/caddy/Caddyfile'
run 'sudo systemctl restart web-caddy && sleep 1 && systemctl status web-caddy'
end
rtask :restart, 'restart remote app server', :server, :hard do
host? :app do
if @args.hard
run 'sudo systemctl restart web-puma && sleep 1 && systemctl status web-puma'
else
run 'touch tmp/restart.txt'
end
end
run 'service postgresql restart' if host? :db
end
rtask :config, 'edit main config file', :server do
run 'vim .etc' if host? :app
run "vim #{host.config}; service postgresql restart" if host? :db
end
rtask :htop, 'HTOP on server', :server do
run 'htop'
end
rtask :deploy_app do
rsync '.', ''
upload './config/misc/env_web', './.env'
end
rtask :assets, 'Build and deploy assets' do
invoke 'assets:compile'
rsync './public/assets', '/public'
end
rtask :fdeploy, 'Only deploy ruby code' do
invoke 'remote:deploy_app'
invoke 'remote:restart'
app_test
end
rtask :deploy, 'Deploy app' do
invoke 'assets:compile'
invoke 'remote:deploy_app'
run 'bundle install'
run 'bundle exec rake db:am'
invoke 'remote:restart'
app_test
end
rtask :log, 'Log via lnav', :server do
run 'lnav %s' % host.log
end
end
# uset to run task in remote servers
# configure in Lux.secrets.remote_servers
# rake remote:bash[server_name]
class RemoteHost
HOSTS ||= {}
class << self
def add name, server, opts={}
opts = opts.to_hwia
opts[:user], opts[:ip], opts[:path] = server.split(/[\@:]/)
opts[:path] ||= '~'
opts[:name] = name
HOSTS[name] = opts
end
end
###
attr_reader :host
def initialize opts, &block
server = opts[:server].to_s == '' ? HOSTS.keys.first : opts[:server].to_sym
@host = HOSTS[server]
@args = opts
instance_exec &block
end
# return true or execute block if we are on a right host
def host? name
return false unless host.name == name
yield if block_given?
true
end
def die text
puts text.red
exit
end
def local command
puts command.magenta
system command
end
def invoke name
local 'rake %s' % name
end
# run on remote server
def run command, opts={}
command = command.join('; ') if command.is_a?(Array)
command = command.sub(/^bundle\s/, '/home/deployer/.rbenv/shims/bundle ')
command = command.gsub("'", "\\'")
full = "ssh -t #{@host.user}@#{@host.ip} 'cd #{@host.path}; #{command}';"
puts full.magenta
system full
die 'Error in last command, exiting' unless $?.success?
end
# rsync '/foo/bar', '/foo/bar'
# rsync '/foo/bar', 'foo/'
def rsync source, dest, opts={}
die 'rsync source cant end with "/" - %s' % source if source.end_with?('/')
sync = ['rsync -vrph --executability --delete']
sync.push %w{.env .git/* .gems/* log/* tmp/* public/assets/* node_modules/* cache/*}.map { |it| "--exclude '%s'" % it }.join(' ')
sync.push "#{source} #{@host.user}@#{@host.ip}:#{@host.path}#{dest}"
local sync.join(' ')
end
# copy file
def upload source, dest=nil
dest ||= source
dest = dest.sub(/^\.\//, '%s/' % @host.path)
local "scp #{source} #{@host.user}@#{@host.ip}:#{dest}"
end
def download source, dest=nil
dest ||= source
source = source.sub(/^\.\//, '%s/' % @host.path)
local "scp #{source} #{@host.user}@#{@host.ip}:#{dest}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment