foreman_maintain 0.6.2 → 0.6.7

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/definitions/checks/check_hotfix_installed.rb +2 -1
  4. data/definitions/checks/disk/performance.rb +24 -9
  5. data/definitions/checks/env_proxy.rb +13 -0
  6. data/definitions/checks/foreman/check_corrupted_roles.rb +14 -2
  7. data/definitions/checks/foreman/validate_external_db_version.rb +28 -0
  8. data/definitions/checks/foreman_proxy/check_tftp_storage.rb +52 -0
  9. data/definitions/checks/original_assets.rb +1 -0
  10. data/definitions/checks/repositories/check_non_rh_repository.rb +23 -0
  11. data/definitions/checks/repositories/check_upstream_repository.rb +2 -1
  12. data/definitions/checks/repositories/validate.rb +2 -1
  13. data/definitions/features/apache.rb +19 -0
  14. data/definitions/features/capsule.rb +2 -1
  15. data/definitions/features/dynflow_sidekiq.rb +1 -1
  16. data/definitions/features/foreman_proxy.rb +30 -5
  17. data/definitions/features/foreman_server.rb +10 -4
  18. data/definitions/features/installer.rb +9 -2
  19. data/definitions/features/puppet_server.rb +6 -2
  20. data/definitions/features/service.rb +10 -3
  21. data/definitions/procedures/backup/metadata.rb +2 -0
  22. data/definitions/procedures/content/prepare.rb +1 -1
  23. data/definitions/procedures/content/switchover.rb +9 -4
  24. data/definitions/procedures/hammer_setup.rb +1 -1
  25. data/definitions/procedures/installer/run.rb +3 -1
  26. data/definitions/procedures/installer/upgrade.rb +6 -1
  27. data/definitions/procedures/packages/update.rb +1 -1
  28. data/definitions/procedures/restore/configs.rb +6 -0
  29. data/definitions/procedures/restore/regenerate_queues.rb +69 -0
  30. data/definitions/procedures/service/stop.rb +1 -1
  31. data/definitions/scenarios/backup.rb +1 -0
  32. data/definitions/scenarios/content.rb +27 -0
  33. data/definitions/scenarios/packages.rb +39 -16
  34. data/definitions/scenarios/restore.rb +17 -2
  35. data/definitions/scenarios/upgrade_to_capsule_6_8.rb +88 -0
  36. data/definitions/scenarios/upgrade_to_capsule_6_8_z.rb +88 -0
  37. data/definitions/scenarios/upgrade_to_satellite_6_2.rb +13 -5
  38. data/definitions/scenarios/upgrade_to_satellite_6_2_z.rb +13 -5
  39. data/definitions/scenarios/upgrade_to_satellite_6_3.rb +13 -5
  40. data/definitions/scenarios/upgrade_to_satellite_6_3_z.rb +13 -5
  41. data/definitions/scenarios/upgrade_to_satellite_6_4.rb +13 -5
  42. data/definitions/scenarios/upgrade_to_satellite_6_4_z.rb +13 -5
  43. data/definitions/scenarios/upgrade_to_satellite_6_5.rb +13 -5
  44. data/definitions/scenarios/upgrade_to_satellite_6_5_z.rb +13 -5
  45. data/definitions/scenarios/upgrade_to_satellite_6_6.rb +13 -5
  46. data/definitions/scenarios/upgrade_to_satellite_6_6_z.rb +13 -5
  47. data/definitions/scenarios/upgrade_to_satellite_6_7.rb +13 -5
  48. data/definitions/scenarios/upgrade_to_satellite_6_7_z.rb +13 -5
  49. data/definitions/scenarios/upgrade_to_satellite_6_8.rb +88 -0
  50. data/definitions/scenarios/upgrade_to_satellite_6_8_z.rb +88 -0
  51. data/lib/foreman_maintain.rb +31 -0
  52. data/lib/foreman_maintain/cli.rb +2 -0
  53. data/lib/foreman_maintain/cli/content_command.rb +17 -0
  54. data/lib/foreman_maintain/cli/restore_command.rb +2 -1
  55. data/lib/foreman_maintain/cli/upgrade_command.rb +10 -0
  56. data/lib/foreman_maintain/concerns/base_database.rb +11 -0
  57. data/lib/foreman_maintain/concerns/downstream.rb +10 -10
  58. data/lib/foreman_maintain/package_manager/dnf.rb +11 -5
  59. data/lib/foreman_maintain/package_manager/yum.rb +15 -5
  60. data/lib/foreman_maintain/reporter/cli_reporter.rb +3 -3
  61. data/lib/foreman_maintain/upgrade_runner.rb +20 -26
  62. data/lib/foreman_maintain/utils/backup.rb +4 -0
  63. data/lib/foreman_maintain/utils/facter.rb +1 -1
  64. data/lib/foreman_maintain/utils/service/abstract.rb +6 -0
  65. data/lib/foreman_maintain/version.rb +1 -1
  66. metadata +15 -4
  67. data/definitions/checks/check_epel_repository.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b80a6708b24b9107d23a2e88357ecd8dbaba11d3015eda0c07f2ffc34f47cc4
4
- data.tar.gz: f0e5890c595b48d44f22eba1b1ac5872137669100d97465090cc12fccd7aa480
3
+ metadata.gz: 90eacd73fa55b32a916a21202f5505f5b23aeacb8669815807c467a1a3a59099
4
+ data.tar.gz: 6c5fdb1c2ced614672d721ea3eedf4fa87240be901371fb16deecfeccdb84896
5
5
  SHA512:
6
- metadata.gz: 8859ccb05729eb6588465e71504918744163899025eba90c2819bd19d0e979e0e15fe199df62def03d23e1445685104f385ced535dc0ee892077affc1a54c2ba
7
- data.tar.gz: 16db194cc592c4dc2c0a9212ea569e361cbac8782da5bd9500a5d0c351dc55715667a941ea8ca8f4297e5886ebda1fcf2a06a7d9d4e18b992f2431434fe47b21
6
+ metadata.gz: 18d9c5e18cc69d58d874201ec26366f7fb3444cb62162d61944344aa4783ecfffda9b6e232e58303df6da9cf51ea4f0e28bb7262e3b77bc0f91bc09ebaaf5412
7
+ data.tar.gz: 629d81c5ee075d1ce030594d5ac2bec6111c286ff4a54b7adf85c2105e146a73711e67ce2bf7279930294c225e404d9cfb4b50737e99d3648e6d5d00a5ac383b
data/README.md CHANGED
@@ -48,6 +48,10 @@ Subcommands:
48
48
  stop Stop maintenance-mode
49
49
  status Get maintenance-mode status
50
50
  is-enabled Get maintenance-mode status code
51
+
52
+ content Content related commands
53
+ prepare Prepare content for Pulp 3
54
+ switchover Switch support for certain content from Pulp 2 to Pulp 3
51
55
  ```
52
56
 
53
57
  ### Upgrades
@@ -4,7 +4,8 @@ class Checks::CheckHotfixInstalled < ForemanMaintain::Check
4
4
  description 'Check to verify if any hotfix installed on system'
5
5
  tags :pre_upgrade
6
6
  preparation_steps do
7
- Procedures::Packages::Install.new(:packages => %w[yum-utils])
7
+ [Checks::Repositories::CheckNonRhRepository.new,
8
+ Procedures::Packages::Install.new(:packages => %w[yum-utils])]
8
9
  end
9
10
 
10
11
  confine do
@@ -3,9 +3,14 @@ module Checks
3
3
  class Performance < ForemanMaintain::Check
4
4
  metadata do
5
5
  label :disk_performance
6
- description 'Check for recommended disk speed of pulp, mongodb, pgsql dir.'
7
- tags :pre_upgrade
8
- preparation_steps { Procedures::Packages::Install.new(:packages => %w[fio]) }
6
+ preparation_steps do
7
+ if feature(:instance).downstream
8
+ [Checks::Repositories::CheckNonRhRepository.new,
9
+ Procedures::Packages::Install.new(:packages => %w[fio])]
10
+ else
11
+ [Procedures::Packages::Install.new(:packages => %w[fio])]
12
+ end
13
+ end
9
14
 
10
15
  confine do
11
16
  feature(:instance).pulp
@@ -14,9 +19,6 @@ module Checks
14
19
 
15
20
  EXPECTED_IO = 60
16
21
  DEFAULT_UNIT = 'MB/sec'.freeze
17
- DEFAULT_DIRS = [
18
- '/var/lib/pulp', '/var/lib/mongodb', '/var/lib/pgsql'
19
- ].select { |file_path| File.directory?(file_path) }.freeze
20
22
 
21
23
  attr_reader :stats
22
24
 
@@ -37,16 +39,29 @@ module Checks
37
39
  end
38
40
  end
39
41
 
42
+ def default_dirs
43
+ @default_dirs ||= %i[pulp2 pulpcore_database mongo foreman_database].inject({}) do |dirs, f|
44
+ if feature(f) && File.directory?(feature(f).data_dir)
45
+ dirs[feature(f).label_dashed] = feature(f).data_dir
46
+ end
47
+ dirs
48
+ end
49
+ end
50
+
51
+ def description
52
+ "Check recommended disk speed for #{default_dirs.keys.join(', ')} directories."
53
+ end
54
+
40
55
  def check_only_single_device?
41
- DEFAULT_DIRS.map do |dir|
56
+ default_dirs.values do |dir|
42
57
  ForemanMaintain::Utils::Disk::Device.new(dir).name
43
58
  end.uniq.length <= 1
44
59
  end
45
60
 
46
61
  def dirs_to_check
47
- return DEFAULT_DIRS.first(1) if check_only_single_device?
62
+ return default_dirs.values.first(1) if check_only_single_device?
48
63
 
49
- DEFAULT_DIRS
64
+ default_dirs.values
50
65
  end
51
66
 
52
67
  private
@@ -0,0 +1,13 @@
1
+ class Checks::EnvProxy < ForemanMaintain::Check
2
+ metadata do
3
+ label :env_proxy
4
+ tags :env_proxy
5
+ description 'Check to make sure no HTTP(S) proxy set in ENV'
6
+ end
7
+
8
+ def run
9
+ variables = %w[http_proxy https_proxy HTTP_PROXY HTTPS_PROXY]
10
+ has_proxy_set = true if variables.map { |variable| ENV[variable] }.compact.any?
11
+ assert(has_proxy_set, 'Global HTTP(S) proxy in environment (env) is set. Please unset first!')
12
+ end
13
+ end
@@ -14,14 +14,22 @@ module Checks
14
14
  def run
15
15
  items = find_filter_permissions
16
16
  assert(items.empty?,
17
- 'There are user roles with inconsistent filters',
17
+ error_message(items),
18
18
  :next_steps => Procedures::Foreman::FixCorruptedRoles.new)
19
19
  end
20
20
 
21
+ def error_message(items)
22
+ roles = items.map { |item| item['role_name'] }.uniq
23
+ 'There are filters having permissions with multiple resource types. ' \
24
+ 'Roles with such filters are:' \
25
+ "\n#{roles.join("\n")}"
26
+ end
27
+
21
28
  def find_filter_permissions
22
29
  feature(:foreman_database).query(self.class.inconsistent_filter_perms)
23
30
  end
24
31
 
32
+ # rubocop:disable Metrics/MethodLength
25
33
  def self.inconsistent_filter_perms
26
34
  subquery = <<-SQL
27
35
  SELECT filters.id AS filter_id,
@@ -32,14 +40,17 @@ module Checks
32
40
  filterings.id AS filtering_id,
33
41
  permissions.id AS permission_id,
34
42
  permissions.name AS permission_name,
35
- permissions.resource_type
43
+ permissions.resource_type,
44
+ roles.name AS role_name
36
45
  FROM filters INNER JOIN filterings ON filters.id = filterings.filter_id
37
46
  INNER JOIN permissions ON permissions.id = filterings.permission_id
47
+ INNER JOIN roles ON filters.role_id = roles.id
38
48
  SQL
39
49
 
40
50
  <<-SQL
41
51
  SELECT DISTINCT first.filter_id,
42
52
  first.role_id,
53
+ first.role_name,
43
54
  first.filtering_id,
44
55
  first.permission_id,
45
56
  first.permission_name,
@@ -54,6 +65,7 @@ module Checks
54
65
  OR (first.resource_type != second.resource_type))
55
66
  SQL
56
67
  end
68
+ # rubocop:enable Metrics/MethodLength
57
69
  end
58
70
  end
59
71
  end
@@ -0,0 +1,28 @@
1
+ module Checks
2
+ module Foreman
3
+ class ValidateExternalDbVersion < ForemanMaintain::Check
4
+ metadata do
5
+ description 'Make sure server is running on required database version'
6
+ tags :pre_upgrade
7
+ label :validate_external_db_version
8
+ confine do
9
+ feature(:foreman_database) && !feature(:foreman_database).local? &&
10
+ !check_min_version('foreman', '2.0')
11
+ end
12
+ end
13
+
14
+ def run
15
+ current_db_version = feature(:foreman_database).db_version
16
+ fail!(db_upgrade_message(current_db_version)) if current_db_version.major < 12
17
+ end
18
+
19
+ def db_upgrade_message(db_version)
20
+ product_name = feature(:instance).product_name
21
+
22
+ "\n\n*** ERROR: Server is running on PostgreSQL #{db_version} database.\n"\
23
+ "*** Newer version of #{product_name} supports only PostgreSQL version 12.\n"\
24
+ "*** Before proceeding further, you must upgrade database to PostgreSQL 12.\n"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,52 @@
1
+ module Checks::ForemanProxy
2
+ class CheckTftpStorage < ForemanMaintain::Check
3
+ metadata do
4
+ label :check_tftp_storage
5
+ description 'Clean old Kernel and initramfs files from tftp-boot'
6
+ tags :default
7
+ confine do
8
+ feature(:satellite) && feature(:foreman_proxy) &&
9
+ feature(:foreman_proxy).features.include?('tftp') && non_zero_token_duration?
10
+ end
11
+ end
12
+
13
+ def run
14
+ if Dir.exist?(tftp_boot_directory)
15
+ files = old_files_from_tftp_boot
16
+ assert(files.empty?,
17
+ 'There are old initrd and vmlinuz files present in tftp',
18
+ :next_steps => Procedures::Files::Remove.new(:files => files))
19
+ else
20
+ skip "TFTP #{tftp_boot_directory} directory doesn't exist."
21
+ end
22
+ end
23
+
24
+ def old_files_from_tftp_boot
25
+ Dir.entries(tftp_boot_directory).map do |file|
26
+ unless File.directory?(file)
27
+ file_path = tftp_boot_directory + file
28
+ file_path if File.mtime(file_path) + (token_duration * 60) < Time.now
29
+ end
30
+ end.compact
31
+ end
32
+
33
+ def self.non_zero_token_duration?
34
+ lookup_token_duration != 0
35
+ end
36
+
37
+ def tftp_boot_directory
38
+ @tftp_boot_directory ||= "#{feature(:foreman_proxy).tftp_root_directory}/boot/"
39
+ end
40
+
41
+ def token_duration
42
+ @token_duration ||= self.class.lookup_token_duration
43
+ end
44
+
45
+ def self.lookup_token_duration
46
+ data = feature(:foreman_database). \
47
+ query("select s.value, s.default from settings s \
48
+ where category = 'Setting::Provisioning' and name = 'token_duration'")
49
+ YAML.load(data[0]['value'] || data[0]['default'])
50
+ end
51
+ end
52
+ end
@@ -2,6 +2,7 @@ class Checks::OriginalAssets < ForemanMaintain::Check
2
2
  metadata do
3
3
  description 'Check if only installed assets are present on the system'
4
4
  tags :post_upgrade
5
+ for_feature :foreman_server
5
6
  end
6
7
 
7
8
  ASSETS_DIR = '/var/lib/foreman/public/assets'.freeze
@@ -0,0 +1,23 @@
1
+ module Checks::Repositories
2
+ class CheckNonRhRepository < ForemanMaintain::Check
3
+ metadata do
4
+ label :check_non_redhat_repository
5
+ description 'Check whether system has any non Red Hat repositories (e.g.: EPEL) enabled'
6
+ tags :pre_upgrade
7
+ confine do
8
+ feature(:instance).downstream
9
+ end
10
+ end
11
+
12
+ def run
13
+ with_spinner('Checking repositories enabled on the system') do
14
+ assert(!epel_enabled?, 'System is subscribed to non Red Hat repositories')
15
+ end
16
+ end
17
+
18
+ def epel_enabled?
19
+ system_repos = execute("yum repolist enabled -d 6 -e 0| grep -E 'Repo-baseurl|Repo-id'")
20
+ system_repos.to_s.match(/\bepel\b/i)
21
+ end
22
+ end
23
+ end
@@ -4,7 +4,8 @@ class Checks::CheckUpstreamRepository < ForemanMaintain::Check
4
4
  description 'Check if any upstream repositories are enabled on system'
5
5
  tags :pre_upgrade
6
6
  preparation_steps do
7
- Procedures::Packages::Install.new(:packages => %w[yum-utils])
7
+ [Checks::Repositories::CheckNonRhRepository.new,
8
+ Procedures::Packages::Install.new(:packages => %w[yum-utils])]
8
9
  end
9
10
  confine do
10
11
  feature(:instance).downstream
@@ -3,7 +3,8 @@ module Checks::Repositories
3
3
  metadata do
4
4
  description 'Validate availability of repositories'
5
5
  preparation_steps do
6
- Procedures::Packages::Install.new(:packages => [ForemanMaintain::Utils::Facter.package])
6
+ [Checks::Repositories::CheckNonRhRepository.new,
7
+ Procedures::Packages::Install.new(:packages => [ForemanMaintain::Utils::Facter.package])]
7
8
  end
8
9
 
9
10
  confine do
@@ -0,0 +1,19 @@
1
+ class Features::Apache < ForemanMaintain::Feature
2
+ metadata do
3
+ label :apache
4
+
5
+ confine do
6
+ find_package('httpd')
7
+ end
8
+ end
9
+
10
+ def services
11
+ [
12
+ system_service('httpd', 30)
13
+ ]
14
+ end
15
+
16
+ def config_files
17
+ ['/etc/httpd']
18
+ end
19
+ end
@@ -5,7 +5,8 @@ class Features::Capsule < ForemanMaintain::Feature
5
5
  label :capsule
6
6
 
7
7
  confine do
8
- package_manager.installed?(['satellite-capsule']) ||
8
+ !package_manager.installed?(['satellite']) &&
9
+ package_manager.installed?(['satellite-capsule']) ||
9
10
  package_manager.installed?(['capsule-installer'])
10
11
  end
11
12
  end
@@ -13,7 +13,7 @@ class Features::DynflowSidekiq < ForemanMaintain::Feature
13
13
 
14
14
  def config_files
15
15
  # Workaround until foreman-installer can deploy scaled workers
16
- service_symlinks = configured_services.map do |service|
16
+ service_symlinks = configured_instances.map do |service|
17
17
  "/etc/systemd/system/multi-user.target.wants/#{service}.service"
18
18
  end
19
19
  [
@@ -12,6 +12,9 @@ class Features::ForemanProxy < ForemanMaintain::Feature
12
12
  FOREMAN_PROXY_DHCP_YML_PATHS = ['/etc/foreman-proxy/settings.d/dhcp.yml',
13
13
  '/usr/local/etc/foreman-proxy/settings.d/dhcp.yml'].freeze
14
14
 
15
+ FOREMAN_PROXY_TFTP_YML_PATHS = ['/etc/foreman-proxy/settings.d/tftp.yml',
16
+ '/usr/local/etc/foreman-proxy/settings.d/tftp.yml'].freeze
17
+
15
18
  def valid_dhcp_configs?
16
19
  dhcp_req_pass? && !syntax_error_exists?
17
20
  end
@@ -66,7 +69,7 @@ class Features::ForemanProxy < ForemanMaintain::Feature
66
69
 
67
70
  configs.push('/var/lib/tftpboot') if backup_features.include?('tftp')
68
71
  configs += ['/var/named/', '/etc/named*'] if backup_features.include?('dns')
69
- if backup_features.include?('dhcp')
72
+ if backup_features.include?('dhcp') && dhcp_isc_provider?
70
73
  configs += ['/var/lib/dhcpd', File.dirname(dhcpd_config_file)]
71
74
  end
72
75
  configs.push('/usr/share/xml/scap') if backup_features.include?('openscap')
@@ -113,6 +116,10 @@ class Features::ForemanProxy < ForemanMaintain::Feature
113
116
  @dhcpd_config_file ||= lookup_dhcpd_config_file
114
117
  end
115
118
 
119
+ def tftp_root_directory
120
+ @tftp_root_directory ||= lookup_tftp_root_directory
121
+ end
122
+
116
123
  private
117
124
 
118
125
  def backup_features(for_features)
@@ -209,11 +216,22 @@ class Features::ForemanProxy < ForemanMaintain::Feature
209
216
  dhcpd_config_file
210
217
  end
211
218
 
212
- def lookup_using_dhcp_yml
213
- dhcp_yml_path = lookup_into(FOREMAN_PROXY_DHCP_YML_PATHS)
214
- raise "Couldn't find dhcp.yml file under foreman-proxy" unless dhcp_yml_path
219
+ def dhcp_yml_path
220
+ dhcp_path = lookup_into(FOREMAN_PROXY_DHCP_YML_PATHS)
221
+ raise "Couldn't find dhcp.yml file under foreman-proxy" unless dhcp_path
222
+
223
+ dhcp_path
224
+ end
225
+
226
+ def configs_from_dhcp_yml
227
+ @configs_from_dhcp_yml ||= yaml_load(dhcp_yml_path)
228
+ end
229
+
230
+ def dhcp_isc_provider?
231
+ configs_from_dhcp_yml[:use_provider] == 'dhcp_isc'
232
+ end
215
233
 
216
- configs_from_dhcp_yml = yaml_load(dhcp_yml_path)
234
+ def lookup_using_dhcp_yml
217
235
  if configs_from_dhcp_yml.key?(:dhcp_config)
218
236
  return configs_from_dhcp_yml[:dhcp_config]
219
237
  elsif configs_from_dhcp_yml.key?(:use_provider)
@@ -226,6 +244,13 @@ class Features::ForemanProxy < ForemanMaintain::Feature
226
244
  end
227
245
  end
228
246
 
247
+ def lookup_tftp_root_directory
248
+ tftp_yml_path = lookup_into(FOREMAN_PROXY_TFTP_YML_PATHS)
249
+ raise "Couldn't find tftp.yml file under foreman-proxy" unless tftp_yml_path
250
+
251
+ yaml_load(tftp_yml_path)[:tftproot]
252
+ end
253
+
229
254
  def yaml_load(path)
230
255
  YAML.load_file(path) || {}
231
256
  end
@@ -9,9 +9,11 @@ module ForemanMaintain
9
9
  end
10
10
 
11
11
  def services
12
- [
13
- system_service('httpd', 30)
14
- ]
12
+ if execute?('systemctl is-enabled foreman')
13
+ [system_service('foreman', 30, :socket => 'foreman')]
14
+ else
15
+ [system_service('httpd', 30)]
16
+ end
15
17
  end
16
18
 
17
19
  def plugins
@@ -26,7 +28,7 @@ module ForemanMaintain
26
28
  def config_files
27
29
  [
28
30
  '/etc/httpd',
29
- '/var/www/html/pub',
31
+ '/var/www/html/pub/katello-*',
30
32
  '/etc/squid',
31
33
  '/etc/foreman',
32
34
  '/etc/selinux/targeted/contexts/files/file_contexts.subs',
@@ -41,6 +43,10 @@ module ForemanMaintain
41
43
  '/var/lib/foreman/public'
42
44
  ]
43
45
  end
46
+
47
+ def services_running?
48
+ services.all?(&:running?)
49
+ end
44
50
  end
45
51
  end
46
52
  end
@@ -92,8 +92,15 @@ class Features::Installer < ForemanMaintain::Feature
92
92
  end
93
93
 
94
94
  def upgrade(exec_options = {})
95
- arguments = '--upgrade' if can_upgrade?
96
- run(arguments, exec_options)
95
+ run(installer_arguments, exec_options)
96
+ end
97
+
98
+ def installer_arguments
99
+ installer_args = ' --disable-system-checks'
100
+ unless check_min_version('foreman', '2.1') || check_min_version('foreman-proxy', '2.1')
101
+ installer_args += ' --upgrade' if can_upgrade?
102
+ end
103
+ installer_args
97
104
  end
98
105
 
99
106
  def initial_admin_username