Top Level Namespace

Defined Under Namespace

Modules: LabdbManager Classes: ShellCommand, String

Constant Summary collapse

COMMAND_PREFIX =
"--> "
CONFIRM_PREFIX =
"--? "
BR_DEPLOY_STAGING =

git parameters

'deploy_staging'
BR_DEPLOY =
'deploy'
BR_REMOTE =
'master'
REM_NAME =
'origin'
PROJECT_URL =
'https://github.com/cjfuller/labdb.git'
DEFAULT_REPO_PATH =
'~/labdb'
DEFAULT_BACKUP_DIR =
'~/backups'
AUTO_MERGE_MESSAGE =
'"auto merge by manage.py"'
PG_DUMP_PATH =

database backend

`which pg_dump`.strip
HOSTNAME_CFG_FILE =

paths to config files

'config/full_hostname.txt'
SECRET_CFG_FILE =
'config/secret_token.txt'
COLORS =
{
  green: "\033[92m",
  yellow: "\033[93m",
  red: "\033[91m",
  off: "\033[0m"
}
SHELL_COMMAND_LIST =
[]

Instance Method Summary collapse

Instance Method Details

#backupObject



249
250
251
# File 'lib/labdb_manager.rb', line 249

def backup
  queue_command {create_backup}
end

#bundle_installObject

application commands



158
159
160
# File 'lib/labdb_manager.rb', line 158

def bundle_install
  "bundle install"
end

#bundle_updateObject



162
163
164
# File 'lib/labdb_manager.rb', line 162

def bundle_update
  confirm "bundle update"
end

#check_for_staging_branchObject

git commands



107
108
109
110
111
112
113
# File 'lib/labdb_manager.rb', line 107

def check_for_staging_branch
  # Check (via process return code) if the staging branch already exists.
  #
  # @return 0 if the branch exists, nonzero otherwise

  "git show-ref --verify --quiet refs/heads/#{BR_DEPLOY_STAGING}"
end

#clean_up_staging_branchObject



115
116
117
118
# File 'lib/labdb_manager.rb', line 115

def clean_up_staging_branch
  # Delete the staging branch.  Don't check for its existence.
  confirm "git checkout #{BR_DEPLOY} && git branch -d #{BR_DEPLOY_STAGING}"
end

#confirm(cmd) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/labdb_manager.rb', line 46

def confirm(cmd)
  # Ask the user for confirmation of the specified command
  #
  # If confirmation is not given, exit the program immediately without running
  # the command.
  print (cmd + " (y/N) " + CONFIRM_PREFIX ).yellow
  response = gets
  unless ['yes', 'y'].include? response.downcase.strip then
    exit 0
  end
  cmd
end

#create_backupObject

database commands



172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/labdb_manager.rb', line 172

def create_backup
  suffix = "_labdb_backup.dump"
  backup_timestring = Time.now.strftime("%Y%m%d_%H%M%S")
  fn = backup_timestring + suffix
  fn_full = File.expand_path(fn, DEFAULT_BACKUP_DIR)
  [PG_DUMP_PATH,
   "-h localhost labdb > #{fn_full}",
   "&&",
   "tar cjf #{fn_full}.tar.bz2 -C {DEFAULT_BACKUP_DIR} {fn}",
   "&&",
   "rm -f #{fn_full}"
   ].join(" ")
end

#create_production_dbObject



186
187
188
# File 'lib/labdb_manager.rb', line 186

def create_production_db
  "RAILS_ENV=production bundle exec rake db:setup"
end

#create_staging_branchObject



120
121
122
123
# File 'lib/labdb_manager.rb', line 120

def create_staging_branch
  # Create the staging branch.  Don't check for its existence.
  "git checkout #{BR_DEPLOY} && git branch #{BR_DEPLOY_STAGING}"
end

#devserverObject



277
278
279
# File 'lib/labdb_manager.rb', line 277

def devserver
  queue_command {run_devserver}
end

#fetch_remote_changesObject



125
126
127
128
129
130
131
# File 'lib/labdb_manager.rb', line 125

def fetch_remote_changes
  # Download changes from the central labdb repo set up as a remote.
  #
  # The remote name and branch to download are set up in the constants above.

  "git checkout #{BR_REMOTE} && git pull #{REM_NAME} #{BR_REMOTE}"
end

#force_update_depsObject



253
254
255
# File 'lib/labdb_manager.rb', line 253

def force_update_deps
  queue_command {bundle_update}
end

#generate_application_secretObject



215
216
217
218
219
220
221
222
223
224
# File 'lib/labdb_manager.rb', line 215

def generate_application_secret
  secret = SecureRandom.hex(64) # 512 bits
  puts (COMMAND_PREFIX +
        "Writing application secret to #{SECRET_CFG_FILE}").green
  File.open(SECRET_CFG_FILE, 'w') do |f|
    f.write secret
  end
  File.chmod(0600, SECRET_CFG_FILE)
  ok
end

#helpObject



281
282
# File 'lib/labdb_manager.rb', line 281

def help
end

#hostname(hostname: nil) ⇒ Object



261
262
263
# File 'lib/labdb_manager.rb', line 261

def hostname(hostname: nil)
  set_hostname(hostname: hostname)
end

#installObject



265
266
267
# File 'lib/labdb_manager.rb', line 265

def install
  queue_command {create_production_db}
end

#merge_into_productionObject



145
146
147
148
149
# File 'lib/labdb_manager.rb', line 145

def merge_into_production
  # Merge changes from staging into production.
  ("git checkout #{BR_DEPLOY} && " +
   "git merge -m #{AUTO_MERGE_MESSAGE} #{BR_DEPLOY_STAGING}")
end

#okObject

task helpers



228
229
230
# File 'lib/labdb_manager.rb', line 228

def ok
  puts "OK".green
end

#precompile_assetsObject



166
167
168
# File 'lib/labdb_manager.rb', line 166

def precompile_assets
  "bundle exec rake assets:precompile"
end


41
42
43
44
# File 'lib/labdb_manager.rb', line 41

def print_command(cmd)
  ### Print a command being run in a standard format
  puts (COMMAND_PREFIX + cmd).green
end

#queue_command(**kwargs, &bl) ⇒ Object



61
62
63
# File 'lib/labdb_manager.rb', line 61

def queue_command(**kwargs, &bl)
  SHELL_COMMAND_LIST << ShellCommand.new(bl, **kwargs)
end

#restartObject



273
274
275
# File 'lib/labdb_manager.rb', line 273

def restart
  queue_command {restart_server}
end

#restart_serverObject

server status commands



192
193
194
# File 'lib/labdb_manager.rb', line 192

def restart_server
  "supervisorctl restart labdb"
end

#revert_failureObject



269
270
271
# File 'lib/labdb_manager.rb', line 269

def revert_failure
  queue_command {revert_merge_failure}
end

#revert_merge_failureObject



151
152
153
154
# File 'lib/labdb_manager.rb', line 151

def revert_merge_failure
  # Revert a merge and go back to production in case conflicts arise.
  "git reset --merge && git checkout #{BR_DEPLOY}"
end

#run_devserverObject



196
197
198
# File 'lib/labdb_manager.rb', line 196

def run_devserver
  "bundle exec puma --config config/puma.rb"
end

#run_queued_commands(dry_run: false) ⇒ Object



65
66
67
68
69
70
# File 'lib/labdb_manager.rb', line 65

def run_queued_commands(dry_run: false)
  SHELL_COMMAND_LIST.each do |c|
    c.call(dry_run: dry_run)
  end
  SHELL_COMMAND_LIST.clear
end

#run_task(t, args: [], dry_run: false) ⇒ Object



284
285
286
287
288
# File 'lib/labdb_manager.rb', line 284

def run_task(t, args: [], dry_run: false)
  send t, *args
  run_queued_commands dry_run: dry_run
  ok
end

#secretObject



257
258
259
# File 'lib/labdb_manager.rb', line 257

def secret
  generate_application_secret
end

#set_hostname(hostname: nil) ⇒ Object

other commands not using the shell



202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/labdb_manager.rb', line 202

def set_hostname(hostname: nil)
  if hostname.nil?
    puts ("Please enter the full hostname of the machine.\n" +
      '(i.e. the part that would appear including the https:// ' +
      'in a url but before any other slashes):').yellow
    print CONFIRM_PREFIX.yellow
    hostname = gets
    File.open(HOSTNAME_CFG_FILE, 'w') do |f|
      f.write hostname
    end
  end
end

#stage_changesObject



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/labdb_manager.rb', line 133

def stage_changes
  # Merge changes from the downloaded branch into the staging branch.
  #
  # This is where problems should arise if there are merge conflicts.  If this
  # happens and you need to get back to a workable state, you can force the
  # load of the (still unchanged) deploy branch using `manage.py revert-
  # failure`.

  ("git checkout #{BR_DEPLOY_STAGING} && " +
   "git merge -m #{AUTO_MERGE_MESSAGE} #{BR_REMOTE}")
end

#updateObject

tasks



234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/labdb_manager.rb', line 234

def update
  queue_command {create_backup}
  if ShellCommand.new(
      Proc.new {check_for_staging_branch}, exit_on_fail: false).call == 0 then
    queue_command {clean_up_staging_branch}
  end
  queue_command {create_staging_branch}
  queue_command {fetch_remote_changes}
  queue_command {stage_changes}
  queue_command {bundle_install}
  queue_command {precompile_assets}
  queue_command {merge_into_production}
  queue_command {restart_server}
end