• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

puppetlabs / vmfloaty / 20521574501

26 Dec 2025 11:21AM UTC coverage: 47.849%. First build
20521574501

Pull #255

github

web-flow
Merge 4686213f4 into 6b6d6f73c
Pull Request #255: Add support for deleting ondemand requests by request-id

7 of 10 new or added lines in 2 files covered. (70.0%)

534 of 1116 relevant lines covered (47.85%)

17.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

4.23
/lib/vmfloaty.rb
1
# frozen_string_literal: true
2

3
require 'rubygems'
8✔
4
require 'commander'
8✔
5
require 'json'
8✔
6
require 'pp'
8✔
7
require 'uri'
8✔
8
require 'vmfloaty/auth'
8✔
9
require 'vmfloaty/pooler'
8✔
10
require 'vmfloaty/version'
8✔
11
require 'vmfloaty/conf'
8✔
12
require 'vmfloaty/utils'
8✔
13
require 'vmfloaty/service'
8✔
14
require 'vmfloaty/ssh'
8✔
15
require 'vmfloaty/logger'
8✔
16

17
class Vmfloaty
8✔
18
  include Commander::Methods
8✔
19

20
  def run # rubocop:disable Metrics/AbcSize
8✔
21
    program :version, Vmfloaty::VERSION
×
22
    program :description,
×
23
            "A CLI helper tool for Puppet's vmpooler to help you stay afloat.\n\nConfiguration may be placed in a ~/.vmfloaty.yml file."
24

25
    config = Conf.read_config
×
26

27
    command :get do |c|
×
28
      c.syntax = 'floaty get os_type0 os_type1=x ox_type2=y [options]'
×
29
      c.summary = 'Gets a vm or vms based on the os argument'
×
30
      c.description = 'A command to retrieve vms from a pooler service. Can either be a single vm, or multiple with the `=` syntax.'
×
31
      c.example 'Gets a few vms', 'floaty get centos=3 debian --user brian --url http://vmpooler.example.com'
×
32
      c.option '--verbose', 'Enables verbose output'
×
33
      c.option '--service STRING', String, 'Configured pooler service name'
×
34
      c.option '--user STRING', String, 'User to authenticate with'
×
35
      c.option '--url STRING', String, 'URL of pooler service'
×
36
      c.option '--token STRING', String, 'Token for pooler service'
×
37
      c.option '--priority STRING', 'Priority for supported backends(ABS) (High(1), Medium(2), Low(3))'
×
38
      c.option '--notoken', 'Makes a request without a token'
×
39
      c.option '--force', 'Forces vmfloaty to get requested vms'
×
40
      c.option '--json', 'Prints retrieved vms in JSON format'
×
41
      c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID'
×
42
      c.option '--continue STRING', String, 'resume polling ABS for job_id, for use when the cli was interrupted'
×
43
      c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
×
44
      c.action do |args, options|
×
45
        verbose = options.verbose || config['verbose']
×
46
        FloatyLogger.setlevel = options.loglevel if options.loglevel
×
47
        service = Service.new(options, config)
×
48
        use_token = !options.notoken
×
49
        force = options.force
×
50

51
        if args.empty?
×
52
          FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
×
53
          exit 1
×
54
        end
55

56
        os_types = Utils.generate_os_hash(args)
×
57

58
        if os_types.empty?
×
59
          FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
×
60
          exit 1
×
61
        end
62

63
        max_pool_request = 5
×
64
        large_pool_requests = os_types.select { |_, v| v > max_pool_request }
×
65
        if !large_pool_requests.empty? && !force
×
66
          FloatyLogger.error "Requesting vms over #{max_pool_request} requires a --force flag."
×
67
          FloatyLogger.error 'Try again with `floaty get --force`'
×
68
          exit 1
×
69
        end
70

71
        response = service.retrieve(verbose, os_types, use_token, options.ondemand, options.continue)
×
72
        request_id = response['request_id'] if options.ondemand
×
73
        response = service.wait_for_request(verbose, request_id) if options.ondemand
×
74

75
        hosts = Utils.standardize_hostnames(response)
×
76

77
        if options.json || options.ondemand
×
78
          puts JSON.pretty_generate(hosts)
×
79
        else
80
          puts Utils.format_host_output(hosts)
×
81
        end
82
      end
83
    end
84

85
    command :list do |c|
×
86
      c.syntax = 'floaty list [options]'
×
87
      c.summary = 'Shows a list of available vms from the pooler or vms obtained with a token'
×
88
      c.description = 'List will either show all vm templates available in pooler service, or with the --active flag it will list vms obtained with a pooler service token.'
×
89
      c.example 'Filter the list on centos', 'floaty list centos --url http://vmpooler.example.com'
×
90
      c.option '--verbose', 'Enables verbose output'
×
91
      c.option '--service STRING', String, 'Configured pooler service name'
×
92
      c.option '--active', 'Prints information about active vms for a given token'
×
93
      c.option '--json', 'Prints information as JSON'
×
94
      c.option '--hostnameonly', 'When listing active vms, prints only hostnames, one per line'
×
95
      c.option '--token STRING', String, 'Token for pooler service'
×
96
      c.option '--url STRING', String, 'URL of pooler service'
×
97
      c.option '--user STRING', String, 'User to authenticate with'
×
98
      c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
×
99
      c.action do |args, options|
×
100
        verbose = options.verbose || config['verbose']
×
101
        FloatyLogger.setlevel = options.loglevel if options.loglevel
×
102

103
        service = Service.new(options, config)
×
104
        filter = args[0]
×
105

106
        if options.active
×
107
          # list active vms
108
          running_vms = if service.type == 'ABS'
×
109
                          # this is actually job_ids
110
                          service.list_active_job_ids(verbose, service.url, service.user)
×
111
                        else
112
                          service.list_active(verbose)
×
113
                        end
114
          host = URI.parse(service.url).host
×
115
          if running_vms.empty?
×
116
            if options.json
×
117
              puts {}.to_json
×
118
            else
119
              FloatyLogger.info "You have no running VMs on #{host}"
×
120
            end
121
          elsif options.json
×
122
            puts Utils.get_host_data(verbose, service, running_vms).to_json
×
123
          elsif options.hostnameonly
×
124
            Utils.get_host_data(verbose, service, running_vms).each do |hostname, host_data|
×
125
              Utils.print_fqdn_for_host(service, hostname, host_data)
×
126
            end
127
          else
128
            puts "Your VMs on #{host}:"
×
129
            Utils.pretty_print_hosts(verbose, service, running_vms)
×
130
          end
131
        else
132
          # list available vms from pooler
133
          os_list = service.list(verbose, filter)
×
134
          puts os_list
×
135
        end
136
      end
137
    end
138

139
    command :query do |c|
×
140
      c.syntax = 'floaty query hostname [options]'
×
141
      c.summary = 'Get information about a given vm'
×
142
      c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm. If using ABS, you can query a job_id'
×
143
      c.example 'Get information about a sample host', 'floaty query hostname --url http://vmpooler.example.com'
×
144
      c.option '--verbose', 'Enables verbose output'
×
145
      c.option '--service STRING', String, 'Configured pooler service name'
×
146
      c.option '--url STRING', String, 'URL of pooler service'
×
147
      c.action do |args, options|
×
148
        verbose = options.verbose || config['verbose']
×
149
        service = Service.new(options, config)
×
150
        hostname = args[0]
×
151

152
        query_req = service.query(verbose, hostname)
×
153
        pp query_req
×
154
      end
155
    end
156

157
    command :modify do |c|
×
158
      c.syntax = 'floaty modify hostname [options]'
×
159
      c.summary = 'Modify a VM\'s tags, time to live, disk space, or reservation reason'
×
160
      c.description = 'This command makes modifications to the virtual machines state in the pooler service. You can either append tags to the vm, increase how long it stays active for, or increase the amount of disk space.'
×
161
      c.example 'Modifies myhost1 to have a TTL of 12 hours and adds a custom tag',
×
162
                'floaty modify myhost1 --lifetime 12 --url https://myurl --token mytokenstring --tags \'{"tag":"myvalue"}\''
163
      c.option '--verbose', 'Enables verbose output'
×
164
      c.option '--service STRING', String, 'Configured pooler service name'
×
165
      c.option '--url STRING', String, 'URL of pooler service'
×
166
      c.option '--token STRING', String, 'Token for pooler service'
×
167
      c.option '--lifetime INT', Integer, 'VM TTL (Integer, in hours) [vmpooler only]'
×
168
      c.option '--disk INT', Integer, 'Increases VM disk space (Integer, in gb) [vmpooler only]'
×
169
      c.option '--tags STRING', String, 'free-form VM tagging (json) [vmpooler only]'
×
170
      c.option '--reason STRING', String, 'VM reservation reason [nspooler only]'
×
171
      c.option '--all', 'Modifies all vms acquired by a token'
×
172
      c.action do |args, options|
×
173
        verbose = options.verbose || config['verbose']
×
174
        service = Service.new(options, config)
×
175
        hostname = args[0]
×
176
        modify_all = options.all
×
177

178
        if hostname.nil? && !modify_all
×
179
          FloatyLogger.error 'ERROR: Provide a hostname or specify --all.'
×
180
          exit 1
×
181
        end
182
        running_vms =
183
          if modify_all
×
184
            service.list_active(verbose)
×
185
          else
186
            hostname.split(',')
×
187
          end
188

189
        tags = options.tags ? JSON.parse(options.tags) : nil
×
190
        modify_hash = {
191
          lifetime: options.lifetime,
×
192
          disk: options.disk,
193
          tags: tags,
194
          reason: options.reason
195
        }
196
        modify_hash.delete_if { |_, value| value.nil? }
×
197

198
        unless modify_hash.empty?
×
199
          ok = true
×
200
          modified_hash = {}
×
201
          running_vms.each do |vm|
×
202
            modified_hash[vm] = service.modify(verbose, vm, modify_hash)
×
203
          rescue ModifyError => e
204
            FloatyLogger.error e
×
205
            ok = false
×
206
          end
207
          if ok
×
208
            if modify_all
×
209
              puts "Successfully modified all #{running_vms.count} VMs."
×
210
            else
211
              puts "Successfully modified VM #{hostname}."
×
212
            end
213
            puts 'Use `floaty list --active` to see the results.'
×
214
          end
215
        end
216
      end
217
    end
218

219
    command :delete do |c|
×
220
      c.syntax = 'floaty delete hostname,hostname2 [options]'
×
221
      c.syntax += "\n    floaty delete job1,job2 [options] (only supported with ABS)"
×
NEW
222
      c.syntax += "\n    floaty delete request-id [options] (for ondemand requests)"
×
223
      c.summary = 'Schedules the deletion of a host or hosts'
×
NEW
224
      c.description = 'Given a comma separated list of hostnames, or --all for all vms, vmfloaty makes a request to the pooler service to schedule the deletion of those vms. If you are using the ABS service, you can also pass in JobIDs here. Note that passing in a Job ID will delete *all* of the hosts in the job. For vmpooler, you can also pass in a request-id (UUID format) to cancel an ondemand request and move any already-provisioned VMs to the deletion queue.' # rubocop:disable Layout/LineLength
×
225
      c.example 'Schedules the deletion of a host or hosts', 'floaty delete myhost1,myhost2 --url http://vmpooler.example.com'
×
226
      c.example 'Schedules the deletion of a JobID or JobIDs', 'floaty delete 1579300120799,1579300120800 --url http://abs.example.com'
×
NEW
227
      c.example 'Cancels an ondemand request and deletes provisioned VMs', 'floaty delete e3ff6271-d201-4f31-a315-d17f4e15863a --url http://vmpooler.example.com'
×
228
      c.option '--verbose', 'Enables verbose output'
×
229
      c.option '--service STRING', String, 'Configured pooler service name'
×
230
      c.option '--all', 'Deletes all vms acquired by a token'
×
231
      c.option '-f', 'Does not prompt user when deleting all vms'
×
232
      c.option '--json', 'Outputs hosts scheduled for deletion as JSON'
×
233
      c.option '--token STRING', String, 'Token for pooler service'
×
234
      c.option '--url STRING', String, 'URL of pooler service'
×
235
      c.option '--user STRING', String, 'User to authenticate with'
×
236
      c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
×
237
      c.action do |args, options|
×
238
        verbose = options.verbose || config['verbose']
×
239
        FloatyLogger.setlevel = options.loglevel if options.loglevel
×
240

241
        service = Service.new(options, config)
×
242
        hostnames = args[0]
×
243
        delete_all = options.all
×
244
        force = options.f
×
245

246
        failures = []
×
247
        successes = []
×
248

249
        if delete_all
×
250
          running_vms = if service.type == 'ABS'
×
251
                          # this is actually job_ids
252
                          service.list_active_job_ids(verbose, service.url, service.user)
×
253
                        else
254
                          service.list_active(verbose)
×
255
                        end
256
          if running_vms.empty?
×
257
            if options.json
×
258
              puts {}.to_json
×
259
            else
260
              FloatyLogger.info 'You have no running VMs.'
×
261
            end
262
          else
263
            confirmed = true
×
264
            unless force
×
265
              Utils.pretty_print_hosts(verbose, service, running_vms, true)
×
266
              # Confirm deletion
267
              confirmed = agree('Delete all these VMs? [y/N]')
×
268
            end
269
            if confirmed
×
270
              response = service.delete(verbose, running_vms)
×
271
              response.each do |hostname, result|
×
272
                if result['ok']
×
273
                  successes << hostname
×
274
                else
275
                  failures << hostname
×
276
                end
277
              end
278
            end
279
          end
280
        elsif hostnames || args
×
281
          hostnames = hostnames.split(',')
×
282
          results = service.delete(verbose, hostnames)
×
283
          results.each do |hostname, result|
×
284
            if result['ok']
×
285
              successes << hostname
×
286
            else
287
              failures << hostname
×
288
            end
289
          end
290
        else
291
          FloatyLogger.info 'You did not provide any hosts to delete'
×
292
          exit 1
×
293
        end
294

295
        unless failures.empty?
×
296
          FloatyLogger.info 'Unable to delete the following VMs:'
×
297
          failures.each do |hostname|
×
298
            FloatyLogger.info "- #{hostname}"
×
299
          end
300
          FloatyLogger.info 'Check `floaty list --active`; Do you need to specify a different service?'
×
301
        end
302

303
        unless successes.empty?
×
304
          if options.json
×
305
            puts successes.to_json
×
306
          else
307
            puts 'Scheduled the following VMs for deletion:'
×
308
            output = ''
×
309
            successes.each do |hostname|
×
310
              output += "- #{hostname}\n"
×
311
            end
312
            puts output
×
313
          end
314
        end
315

316
        exit 1 unless failures.empty?
×
317
      end
318
    end
319

320
    command :snapshot do |c|
×
321
      c.syntax = 'floaty snapshot hostname [options]'
×
322
      c.summary = 'Takes a snapshot of a given vm'
×
323
      c.description = 'Will request a snapshot be taken of the given hostname in the pooler service. This command is known to take a while depending on how much load is on the pooler service.'
×
324
      c.example 'Takes a snapshot for a given host',
×
325
                'floaty snapshot myvm.example.com --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
326
      c.option '--verbose', 'Enables verbose output'
×
327
      c.option '--service STRING', String, 'Configured pooler service name'
×
328
      c.option '--url STRING', String, 'URL of pooler service'
×
329
      c.option '--token STRING', String, 'Token for pooler service'
×
330
      c.action do |args, options|
×
331
        verbose = options.verbose || config['verbose']
×
332
        service = Service.new(options, config)
×
333
        hostname = args[0]
×
334

335
        begin
336
          snapshot_req = service.snapshot(verbose, hostname)
×
337
        rescue TokenError, ModifyError => e
338
          FloatyLogger.error e
×
339
          exit 1
×
340
        end
341

342
        puts "Snapshot pending. Use `floaty query #{hostname}` to determine when snapshot is valid."
×
343
        pp snapshot_req
×
344
      end
345
    end
346

347
    command :revert do |c|
×
348
      c.syntax = 'floaty revert hostname snapshot [options]'
×
349
      c.summary = 'Reverts a vm to a specified snapshot'
×
350
      c.description = 'Given a snapshot SHA, vmfloaty will request a revert to the pooler service to go back to a previous snapshot.'
×
351
      c.example 'Reverts to a snapshot for a given host',
×
352
                'floaty revert myvm.example.com n4eb4kdtp7rwv4x158366vd9jhac8btq --url http://vmpooler.example.com --token a9znth9dn01t416hrguu56ze37t790bl'
353
      c.option '--verbose', 'Enables verbose output'
×
354
      c.option '--service STRING', String, 'Configured pooler service name'
×
355
      c.option '--url STRING', String, 'URL of pooler service'
×
356
      c.option '--token STRING', String, 'Token for pooler service'
×
357
      c.option '--snapshot STRING', String, 'SHA of snapshot'
×
358
      c.action do |args, options|
×
359
        verbose = options.verbose || config['verbose']
×
360
        service = Service.new(options, config)
×
361
        hostname = args[0]
×
362
        snapshot_sha = args[1] || options.snapshot
×
363

364
        if args[1] && options.snapshot
×
365
          FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}"
×
366
        end
367

368
        begin
369
          revert_req = service.revert(verbose, hostname, snapshot_sha)
×
370
        rescue TokenError, ModifyError => e
371
          FloatyLogger.error e
×
372
          exit 1
×
373
        end
374

375
        pp revert_req
×
376
      end
377
    end
378

379
    command :status do |c|
×
380
      c.syntax = 'floaty status [options]'
×
381
      c.summary = 'Prints the status of pools in the pooler service'
×
382
      c.description = 'Makes a request to the pooler service to request the information about vm pools and how many are ready to be used, what pools are empty, etc.'
×
383
      c.example 'Gets the current pooler service status', 'floaty status --url http://vmpooler.example.com'
×
384
      c.option '--verbose', 'Enables verbose output'
×
385
      c.option '--service STRING', String, 'Configured pooler service name'
×
386
      c.option '--url STRING', String, 'URL of pooler service'
×
387
      c.option '--json', 'Prints status in JSON format'
×
388
      c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
×
389
      c.action do |_, options|
×
390
        verbose = options.verbose || config['verbose']
×
391
        FloatyLogger.setlevel = options.loglevel if options.loglevel
×
392
        service = Service.new(options, config)
×
393
        if options.json
×
394
          pp service.status(verbose)
×
395
        else
396
          Utils.pretty_print_status(verbose, service)
×
397
        end
398
      end
399
    end
400

401
    command :summary do |c|
×
402
      c.syntax = 'floaty summary [options]'
×
403
      c.summary = 'Prints a summary of a pooler service'
×
404
      c.description = 'Gives a very detailed summary of information related to the pooler service.'
×
405
      c.example 'Gets the current day summary of the pooler service', 'floaty summary --url http://vmpooler.example.com'
×
406
      c.option '--verbose', 'Enables verbose output'
×
407
      c.option '--service STRING', String, 'Configured pooler service name'
×
408
      c.option '--url STRING', String, 'URL of pooler service'
×
409
      c.action do |_, options|
×
410
        verbose = options.verbose || config['verbose']
×
411
        service = Service.new(options, config)
×
412

413
        summary = service.summary(verbose)
×
414
        pp summary
×
415
        exit 0
×
416
      end
417
    end
418

419
    command :token do |c|
×
420
      c.syntax = 'floaty token <get delete status> [options]'
×
421
      c.summary = 'Retrieves or deletes a token or checks token status'
×
422
      c.description = 'This command is used to manage your pooler service token. Through the various options, you are able to get a new token, delete an existing token, and request a tokens status.'
×
423
      c.example 'Gets a token from the pooler', 'floaty token get'
×
424
      c.option '--verbose', 'Enables verbose output'
×
425
      c.option '--service STRING', String, 'Configured pooler service name'
×
426
      c.option '--url STRING', String, 'URL of pooler service'
×
427
      c.option '--user STRING', String, 'User to authenticate with'
×
428
      c.option '--token STRING', String, 'Token for pooler service'
×
429
      c.action do |args, options|
×
430
        verbose = options.verbose || config['verbose']
×
431
        service = Service.new(options, config)
×
432
        action = args.first
×
433

434
        begin
435
          case action
×
436
          when 'get'
437
            token = service.get_new_token(verbose)
×
438
            puts token
×
439
          when 'delete'
440
            result = service.delete_token(verbose, options.token)
×
441
            puts result
×
442
          when 'status'
443
            token_value = options.token
×
444
            token_value = args[1] if token_value.nil?
×
445
            status = service.token_status(verbose, token_value)
×
446
            puts status
×
447
          when nil
448
            FloatyLogger.error 'No action provided'
×
449
            exit 1
×
450
          else
451
            FloatyLogger.error "Unknown action: #{action}"
×
452
            exit 1
×
453
          end
454
        rescue TokenError => e
455
          FloatyLogger.error e
×
456
          exit 1
×
457
        end
458
        exit 0
×
459
      end
460
    end
461

462
    command :ssh do |c|
×
463
      c.syntax = 'floaty ssh os_type [options]'
×
464
      c.summary = 'Grabs a single vm and sshs into it'
×
465
      c.description = 'This command simply will grab a vm template that was requested, and then ssh the user into the machine all at once.'
×
466
      c.example 'SSHs into a centos vm', 'floaty ssh centos7 --url https://vmpooler.example.com'
×
467
      c.option '--verbose', 'Enables verbose output'
×
468
      c.option '--service STRING', String, 'Configured pooler service name'
×
469
      c.option '--url STRING', String, 'URL of pooler service'
×
470
      c.option '--user STRING', String, 'User to authenticate with'
×
471
      c.option '--token STRING', String, 'Token for pooler service'
×
472
      c.option '--notoken', 'Makes a request without a token'
×
473
      c.option '--priority STRING', 'Priority for supported backends(ABS) (High(1), Medium(2), Low(3))'
×
474
      c.option '--ondemand', 'Requested vms are provisioned upon receival of the request, tracked by a request ID'
×
475
      c.action do |args, options|
×
476
        verbose = options.verbose || config['verbose']
×
477
        service = Service.new(options, config)
×
478
        use_token = !options.notoken
×
479

480
        if args.empty?
×
481
          FloatyLogger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
×
482
          exit 1
×
483
        end
484

485
        host_os = args.first
×
486

487
        FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
×
488

489
        service.ssh(verbose, host_os, use_token, options.ondemand)
×
490
        exit 0
×
491
      end
492
    end
493

494
    command :completion do |c|
×
495
      c.syntax = 'floaty completion [options]'
×
496
      c.summary = 'Outputs path to completion script'
×
497
      c.description = Utils.strip_heredoc(<<-DESCRIPTION)
×
498
        Outputs path to a completion script for the specified shell (or 'bash' if not specified). This makes it easy to add the completion script to your profile:
499

500
          source $(floaty completion --shell bash)
501

502
        This subcommand will exit non-zero with an error message if no completion script is available for the requested shell.
503
      DESCRIPTION
504
      c.example 'Gets path to bash tab completion script', 'floaty completion --shell bash'
×
505
      c.option '--shell STRING', String, 'Shell to request completion script for'
×
506
      c.action do |_, options|
×
507
        shell = (options.shell || 'bash').downcase.strip
×
508
        completion_file = File.expand_path(File.join('..', '..', 'extras', 'completions', "floaty.#{shell}"), __FILE__)
×
509

510
        if File.exist?(completion_file)
×
511
          puts completion_file
×
512
          exit 0
×
513
        else
514
          FloatyLogger.error "Could not find completion file for '#{shell}': No such file #{completion_file}"
×
515
          exit 1
×
516
        end
517
      end
518
    end
519

520
    command :service do |c|
×
521
      c.syntax = 'floaty service <types examples>'
×
522
      c.summary = 'Display information about floaty services and their configuration'
×
523
      c.description = 'Display information about floaty services to aid in setting up a configuration file.'
×
524
      c.example 'Print a list of the valid service types', 'floaty service types'
×
525
      c.example 'Print a sample config file with multiple services', 'floaty service examples'
×
526
      c.example 'list vms from the service named "nspooler-prod"', 'floaty list --service nspooler-prod'
×
527
      c.action do |args, _options|
×
528
        action = args.first
×
529

530
        example_config = Utils.strip_heredoc(<<-CONFIG)
×
531
          # Sample ~/.vmfloaty.yml with just vmpooler
532
          user: 'jdoe'
533
          url: 'https://vmpooler.example.net'
534
          token: '456def789'
535

536
          # Sample ~/.vmfloaty.yml with multiple services
537
          # Note: when the --service is not specified on the command line,
538
          # the first service listed here is selected automatically
539
          user: 'jdoe'
540
          services:
541
            abs-prod:
542
              type: 'abs'
543
              url: 'https://abs.example.net/api/v2'
544
              token: '123abc456'
545
              vmpooler_fallback: 'vmpooler-prod'
546
            nspooler-prod:
547
              type: 'nspooler'
548
              url: 'https://nspooler.example.net'
549
              token:  '789ghi012'
550
            vmpooler-dev:
551
              type: 'vmpooler'
552
              url: 'https://vmpooler-dev.example.net'
553
              token: '987dsa654'
554
            vmpooler-prod:
555
              type: 'vmpooler'
556
              url: 'https://vmpooler.example.net'
557
              token: '456def789'
558

559
        CONFIG
560

561
        types_output = Utils.strip_heredoc(<<-TYPES)
×
562
          The values on the left below can be used in ~/.vmfloaty.yml as the value of type:
563

564
          abs:       Puppet's Always Be Scheduling
565
          nspooler:  Puppet's Non-standard Pooler, aka NSPooler
566
          vmpooler:  Puppet's VMPooler
567
        TYPES
568

569
        case action
×
570
        when 'examples'
571
          FloatyLogger.info example_config
×
572
        when 'types'
573
          FloatyLogger.info types_output
×
574
        when nil
575
          FloatyLogger.error 'No action provided'
×
576
          exit 1
×
577
        else
578
          FloatyLogger.error "Unknown action: #{action}"
×
579
          exit 1
×
580
        end
581
      end
582
    end
583

584
    run!
×
585
  end
586
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc