floatyhelper 1.4 → 2.0.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.
@@ -1,19 +1,55 @@
1
+ # This is for interfacing with floaty (or vmpooler/ABS directly if needed) to
2
+ # request, query, or modify VMs on the service, and managing snapshots in the
3
+ # yaml file.
1
4
  require 'floatyhelper/groups'
2
5
  require 'floatyhelper/hosts'
3
- require 'floatyhelper/conf'
6
+ require 'floatyhelper/config'
7
+ require 'colorize'
8
+ require 'net/http'
9
+ require 'json'
4
10
 
5
11
  class VM
12
+ def self.pooled_platforms_default
13
+ [
14
+ 'centos-7-x86_64',
15
+ 'centos-8-x86_64',
16
+ 'oracle-7-x86_64',
17
+ 'redhat-7-x86_64',
18
+ 'redhat-8-x86_64',
19
+ 'redhat-fips-7-x86_64',
20
+ 'scientific-7-x86_64',
21
+ 'sles-12-x86_64',
22
+ 'ubuntu-1804-x86_64',
23
+ ]
24
+ end
25
+
26
+ def self.find_pooled_platforms
27
+ begin # rubocop:disable Style/RedundantBegin
28
+ result = Net::HTTP.get('vmpooler.delivery.puppetlabs.net','/status')
29
+ result = JSON.parse(result)
30
+ # Techinally, 'max > 0' tells you if it's a pooled platform, but if
31
+ # the pool is empty, we'll want to fall back to ABS anyway.
32
+ result['pools'].select { |_pool, info| info['ready'].positive? }.map { |pool, _info| pool.gsub('-pixa4','') }
33
+ rescue StandardError
34
+ # Not a great practice to swallow all errors, but this list is probably
35
+ # pretty stable, so let's just pass along the default.
36
+ puts 'Error looking up pooled platforms from vmpooler.delivery.puppetlabs.net. Using default pooled platform list instead.'.yellow
37
+ pooled_platforms_default
38
+ end
39
+ end
6
40
 
41
+ ### VM Management ###
7
42
  def self.destroy(id)
8
43
  hosts = Hosts.get_hosts_from_id(id)
9
- Groups.delete_tag(id) if Groups.is_tag?(id)
44
+ Groups.delete_tag(id) if Groups.tag?(id)
10
45
  Groups.delete_all if id == 'all'
11
46
  hosts = hosts.select { |host| alive(host) }
12
- puts `floaty delete #{hosts.join(',')}` unless hosts.empty?
47
+ puts Floaty.floaty_cmd("delete #{hosts.join(',')} --service vmpooler") unless hosts.empty?
13
48
  end
14
49
 
15
50
  def self.query(host)
16
- eval(`floaty query #{host}`)
51
+ output = Floaty.floaty_cmd("query #{host} --service vmpooler")
52
+ Floaty.parse_floaty_json_output(output)
17
53
  end
18
54
 
19
55
  def self.get_current_lifetime(host)
@@ -21,58 +57,70 @@ class VM
21
57
  status['ok'] ? status[host]['lifetime'] : nil
22
58
  end
23
59
 
24
- def self.alive(host, query=nil)
60
+ def self.alive(host, query = nil)
25
61
  query ||= query(host)
26
62
  query['ok'] && query[host]['state'] == 'running'
27
63
  end
28
64
 
29
- def self.increaselife(id, amount)
30
- amount = 100 if amount.nil?
65
+ def self.increaselife(id, amount = nil)
66
+ amount ||= Config.get_config_setting('increaselife').to_i
67
+ return if amount < 1
31
68
  hosts = Hosts.get_hosts_from_id(id)
32
69
  hosts.each do |host|
33
- if lifetime = get_current_lifetime(host)
70
+ if (lifetime = get_current_lifetime(host))
34
71
  lifetime += amount
35
- print "#{host} to #{lifetime} hours: "
36
- puts `floaty modify #{host} --lifetime #{lifetime}`.split("\n")[0]
72
+ output = Floaty.floaty_cmd("modify #{host} --lifetime #{lifetime} --service vmpooler")
73
+ if output =~ /Successfully modified/
74
+ puts "#{host} lifetime set to #{lifetime} hours".green
75
+ else
76
+ puts "Error setting VM lifetime: #{output}".red
77
+ end
37
78
  else
38
79
  puts "Could not query host #{host}".red
39
80
  end
40
81
  end
41
82
  end
42
83
 
43
- def self.snapshot(id, snaptag, clr=false)
44
- snaptag = 'Blank Snaptag' unless snaptag
84
+ ### Snapshots ###
85
+ def self.snapshot(id, snaptag)
86
+ clr = Config.get_config_setting('vertical_snapshot_status')
87
+ clr = clr.to_s.downcase == 'true'
88
+ snaptag ||= 'Blank Snaptag'
45
89
  hosts = Hosts.get_hosts_from_id(id)
46
90
  shas = {}
91
+ # There's probably a better way to do this...
92
+ puts `tput clear` if clr
93
+
47
94
  hosts.each do |host|
48
- print "#{host}: "
49
- result = `floaty snapshot #{host}`
50
- message = result.split("\n")[0]
51
- answer = eval(result.sub(message,''))
95
+ result = Floaty.floaty_cmd("snapshot #{host} --service vmpooler")
96
+ answer = Floaty.parse_floaty_json_output(result)
52
97
  sha = answer[host]['snapshot']
53
- puts sha
98
+ puts "#{host}: #{sha}"
54
99
  shas[host] = sha
55
100
  end
56
101
 
57
- data = Conf.load_data
102
+ data = Config.load_data
58
103
  data['snapshots'] ||= {}
59
104
  data['snapshots'][id] ||= {}
60
105
  data['snapshots'][id][snaptag] = shas
61
- Conf.write_data(data)
106
+ Config.write_data(data)
62
107
 
63
- puts `tput clear` if clr
108
+ puts
64
109
  puts 'Waiting for snapshots to appear in floaty query...'
65
110
  alldone = false
66
- while !alldone do
67
- puts `tput cup 1` if clr
111
+ until alldone
112
+ puts `tput cup 4` if clr
68
113
  alldone = true
69
114
  print "\r" unless clr
70
115
  hosts.each do |host|
71
- answer = eval(`floaty query #{host}`)[host]
116
+ answer = query(host)[host]
72
117
  done = answer.keys.include?('snapshots') && answer['snapshots'].include?(shas[host])
73
- status = done ? 'Done' : 'Wait'
74
- print "* #{host}: #{status} *" unless clr
75
- puts "* #{host}: #{status} *" if clr
118
+ status = done ? 'Done'.green : 'Wait'.yellow
119
+ if clr
120
+ puts "* %s #{status} *" % "#{host}:".ljust(16)
121
+ else
122
+ print "* %s #{status} *" % "#{host}:".ljust(16)
123
+ end
76
124
  alldone &= done
77
125
  end
78
126
  sleep(1)
@@ -81,31 +129,41 @@ class VM
81
129
  end
82
130
 
83
131
  def self.getsnapshot(id, snaptag)
84
- data = Conf.load_data
132
+ data = Config.load_data
85
133
  data['snapshots'][id][snaptag]
86
134
  end
87
135
 
88
136
  def self.snaptag_exists?(id, snaptag)
89
- data = Conf.load_data
90
- exists = data['snapshots'].keys.include?(id) ? data['snapshots'][id].keys.include?(snaptag) : false
137
+ data = Config.load_data
138
+ data['snapshots'].keys.include?(id) ? data['snapshots'][id].keys.include?(snaptag) : false
139
+ end
140
+
141
+ def self.snaplist(tag)
142
+ data = Config.load_data
143
+ return [] if !data['snapshots'].keys.include?(tag)
144
+ data['snapshots'][tag].keys
91
145
  end
92
146
 
93
147
  def self.revert(id, snaptag)
94
- snaptag = 'Blank Snaptag' unless snaptag
148
+ snaptag ||= 'Blank Snaptag'
95
149
  shas = VM.getsnapshot(id, snaptag)
96
150
  shas.each do |host, sha|
97
151
  print "#{host}: #{sha} --- "
98
- puts `floaty revert #{host} #{sha}`
152
+ puts Floaty.floaty_cmd("revert #{host} #{sha} --service vmpooler")
99
153
  end
100
154
  puts 'Waiting 10 seconds for revert to take effect'
101
155
  sleep(10)
102
156
  end
103
157
 
104
- def self.get_vm(platform='centos-7-x86_64')
105
- response = `floaty get #{platform} 2>&1`
106
- raise "Error obtaining a VM: #{response}" if response.include?('error')
107
- return response.split(' ')[1].split('.')[0]
158
+ ### Get a VM from floaty ###
159
+ def self.get_vm(platform: 'centos-7-x86_64', force_abs: false)
160
+ if !find_pooled_platforms.include?(platform.gsub('-pixa4','')) || force_abs
161
+ response = Floaty.floaty_cmd("get #{platform} --service abs --priority 1", use_pty: true)
162
+ response.chomp.split('- ')[1].split[0].split('.')[0]
163
+ else
164
+ response = Floaty.floaty_cmd("get #{platform} --service vmpooler")
165
+ raise "Error obtaining a VM: #{response}" if response.include?('error')
166
+ response.split[1].split('.')[0]
167
+ end
108
168
  end
109
-
110
169
  end
111
-