vmfloaty 0.10.0 → 1.2.0
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.
- checksums.yaml +4 -4
- data/README.md +19 -75
- data/extras/completions/floaty.bash +17 -9
- data/extras/completions/floaty.zsh +43 -0
- data/lib/vmfloaty.rb +167 -42
- data/lib/vmfloaty/abs.rb +178 -73
- data/lib/vmfloaty/conf.rb +1 -1
- data/lib/vmfloaty/logger.rb +40 -0
- data/lib/vmfloaty/nonstandard_pooler.rb +1 -1
- data/lib/vmfloaty/pooler.rb +3 -3
- data/lib/vmfloaty/service.rb +27 -16
- data/lib/vmfloaty/utils.rb +126 -33
- data/lib/vmfloaty/version.rb +2 -1
- data/spec/vmfloaty/abs_spec.rb +55 -8
- data/spec/vmfloaty/utils_spec.rb +451 -73
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d229737ed9cb959ec725227d7c344ad56c1af7fcd7a53a59502fdb5bf7c0c696
|
4
|
+
data.tar.gz: 4625d46bc08dc61e806beff43237adac120d509ae704c437b47d56a4ef5413bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8763f1c3849bfa0ab7ad2f45cae9737ab16c4f96c7aa9ff9545126979bc7ab611cc40db1c5ace88d812a1dc7004eafa8b27210df92cbe316aff07480db9fe80a
|
7
|
+
data.tar.gz: eb5691d5fc84dc667abb0609c6ed9ce1222838e07cc3a5818c5d7294c888e869d28b8fd89300787e4691cfbf691b12356d01c2528d6c2235d832e7245b220dc3
|
data/README.md
CHANGED
@@ -14,9 +14,8 @@ A CLI helper tool for [Puppet's vmpooler](https://github.com/puppetlabs/vmpooler
|
|
14
14
|
- [Example workflow](#example-workflow)
|
15
15
|
- [vmfloaty dotfile](#vmfloaty-dotfile)
|
16
16
|
- [Basic configuration](#basic-configuration)
|
17
|
-
- [
|
18
|
-
- [
|
19
|
-
- [Using a Nonstandard Pooler service](#using-a-nonstandard-pooler-service)
|
17
|
+
- [Using multiple services](#using-multiple-services)
|
18
|
+
- [Using backends besides VMPooler](#using-backends-besides-vmpooler)
|
20
19
|
- [Valid config keys](#valid-config-keys)
|
21
20
|
- [Tab Completion](#tab-completion)
|
22
21
|
- [vmpooler API](#vmpooler-api)
|
@@ -54,6 +53,7 @@ $ floaty --help
|
|
54
53
|
modify Modify a VM's tags, time to live, disk space, or reservation reason
|
55
54
|
query Get information about a given vm
|
56
55
|
revert Reverts a vm to a specified snapshot
|
56
|
+
service Display information about floaty services and their configuration
|
57
57
|
snapshot Takes a snapshot of a given vm
|
58
58
|
ssh Grabs a single vm and sshs into it
|
59
59
|
status Prints the status of pools in the pooler service
|
@@ -90,95 +90,32 @@ floaty get centos-7-x86_64=2 debian-7-x86_64 windows-10=3 --token mytokenstring
|
|
90
90
|
|
91
91
|
### vmfloaty dotfile
|
92
92
|
|
93
|
-
If you do not wish to continually specify various config options with the cli, you can
|
93
|
+
If you do not wish to continually specify various config options with the cli, you can `~/.vmfloaty.yml` for some defaults. You can get a list of valid service types and example configuration files via `floaty service types` and `floaty service examples`, respectively.
|
94
94
|
|
95
95
|
#### Basic configuration
|
96
96
|
|
97
|
-
|
98
|
-
# file at ~/.vmfloaty.yml
|
99
|
-
url: 'https://vmpooler.example.net/api/v1'
|
100
|
-
user: 'brian'
|
101
|
-
token: 'tokenstring'
|
102
|
-
```
|
103
|
-
|
104
|
-
Now vmfloaty will use those config files if no flag was specified.
|
105
|
-
|
106
|
-
#### Default to Puppet's ABS instead of vmpooler
|
97
|
+
This is the simplest type of configuration where you only need a single service:
|
107
98
|
|
108
99
|
```yaml
|
109
100
|
# file at ~/.vmfloaty.yml
|
110
|
-
url: 'https://
|
101
|
+
url: 'https://vmpooler.example.net/api/v1'
|
111
102
|
user: 'brian'
|
112
103
|
token: 'tokenstring'
|
113
|
-
type: 'abs'
|
114
104
|
```
|
115
105
|
|
116
|
-
|
106
|
+
Run `floaty service examples` to see additional configuration options
|
117
107
|
|
118
|
-
|
108
|
+
#### Using multiple services
|
119
109
|
|
120
|
-
|
121
|
-
|
122
|
-
```yaml
|
123
|
-
# file at /Users/me/.vmfloaty.yml
|
124
|
-
user: 'brian'
|
125
|
-
services:
|
126
|
-
main:
|
127
|
-
url: 'https://vmpooler.example.net/api/v1'
|
128
|
-
token: 'tokenstring'
|
129
|
-
alternate:
|
130
|
-
url: 'https://vmpooler.example.com/api/v1'
|
131
|
-
token: 'alternate-tokenstring'
|
132
|
-
```
|
110
|
+
Most commands allow you to specify a `--service <servicename>` option to allow the use of multiple pooler instances. This can be useful when you'd rather not specify a `--url` or `--token` by hand for alternate services.
|
133
111
|
|
134
112
|
- If you run `floaty` without a `--service <name>` option, vmfloaty will use the first configured service by default.
|
135
|
-
With the config file above, the default would be to use the 'main' vmpooler instance.
|
136
113
|
- If keys are missing for a configured service, vmfloaty will attempt to fall back to the top-level values.
|
137
|
-
|
138
|
-
|
139
|
-
Examples using the above configuration:
|
140
|
-
|
141
|
-
List available vm types from our main vmpooler instance:
|
142
|
-
|
143
|
-
```bash
|
144
|
-
floaty list --service main
|
145
|
-
# or, since the first configured service is used by default:
|
146
|
-
floaty list
|
147
|
-
```
|
148
|
-
|
149
|
-
List available vm types from our alternate vmpooler instance:
|
150
|
-
|
151
|
-
```bash
|
152
|
-
floaty list --service alternate
|
153
|
-
```
|
114
|
+
This makes it so you can specify things like `user` once at the top of your `~/.vmfloaty.yml`.
|
154
115
|
|
155
|
-
#### Using
|
116
|
+
#### Using backends besides VMPooler
|
156
117
|
|
157
|
-
vmfloaty
|
158
|
-
|
159
|
-
```yaml
|
160
|
-
# file at /Users/me/.vmfloaty.yml
|
161
|
-
user: 'brian'
|
162
|
-
services:
|
163
|
-
vm:
|
164
|
-
url: 'https://vmpooler.example.net/api/v1'
|
165
|
-
token: 'tokenstring'
|
166
|
-
ns:
|
167
|
-
url: 'https://nspooler.example.net/api/v1'
|
168
|
-
token: 'nspooler-tokenstring'
|
169
|
-
type: 'nonstandard' # <-- 'type' is necessary for any non-vmpooler service
|
170
|
-
abs:
|
171
|
-
url: 'https://abs.example.net/'
|
172
|
-
token: 'abs-tokenstring'
|
173
|
-
type: 'abs' # <-- 'type' is necessary for any non-vmpooler service
|
174
|
-
|
175
|
-
```
|
176
|
-
|
177
|
-
With this configuration, you could list available OS types from nspooler like this:
|
178
|
-
|
179
|
-
```bash
|
180
|
-
floaty list --service ns
|
181
|
-
```
|
118
|
+
vmfloaty supports additional backends besides VMPooler. To see a complete list, run `floaty service types`. The output of `floaty service examples` will show you how to configure each of the supported backends.
|
182
119
|
|
183
120
|
#### Valid config keys
|
184
121
|
|
@@ -190,6 +127,7 @@ Here are the keys that vmfloaty currently supports:
|
|
190
127
|
- url (String)
|
191
128
|
- services (String)
|
192
129
|
- type (String)
|
130
|
+
- vmpooler_fallback (String)
|
193
131
|
|
194
132
|
### Tab Completion
|
195
133
|
|
@@ -207,6 +145,12 @@ If you are running on macOS and use Homebrew's `bash-completion` formula, you ca
|
|
207
145
|
ln -s $(floaty completion --shell bash) /usr/local/etc/bash_completion.d/floaty
|
208
146
|
```
|
209
147
|
|
148
|
+
There is also tab completion for zsh:
|
149
|
+
|
150
|
+
```zsh
|
151
|
+
source $(floaty completion --shell zsh)
|
152
|
+
```
|
153
|
+
|
210
154
|
## vmpooler API
|
211
155
|
|
212
156
|
This cli tool uses the [vmpooler API](https://github.com/puppetlabs/vmpooler/blob/master/API.md).
|
@@ -2,29 +2,37 @@
|
|
2
2
|
|
3
3
|
_vmfloaty()
|
4
4
|
{
|
5
|
-
local cur prev
|
5
|
+
local cur prev commands template_arg_commands hostname_arg_commands service_subcommands
|
6
|
+
|
6
7
|
COMPREPLY=()
|
7
8
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
8
9
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
commands="delete get help list modify query revert service snapshot ssh status summary token"
|
12
|
+
template_arg_commands="get ssh"
|
13
|
+
hostname_arg_commands="delete modify query revert snapshot"
|
14
|
+
service_subcommands="types examples"
|
13
15
|
|
14
16
|
if [[ $cur == -* ]] ; then
|
15
17
|
# TODO: option completion
|
16
18
|
COMPREPLY=()
|
17
|
-
elif [[ $
|
19
|
+
elif [[ $template_arg_commands =~ (^| )$prev($| ) ]] ; then
|
18
20
|
if [[ -z "$_vmfloaty_avail_templates" ]] ; then
|
21
|
+
# TODO: need a --hostnameonly equivalent here because the section headers of
|
22
|
+
# `floaty list` are adding some spurious entries (including files in current
|
23
|
+
# directory because part of the headers is `**` which is getting expanded)
|
19
24
|
_vmfloaty_avail_templates=$(floaty list 2>/dev/null)
|
20
25
|
fi
|
21
26
|
|
22
27
|
COMPREPLY=( $(compgen -W "${_vmfloaty_avail_templates}" -- "${cur}") )
|
23
|
-
elif [[ $
|
24
|
-
_vmfloaty_active_hostnames=$(floaty list --active 2>/dev/null
|
28
|
+
elif [[ $hostname_arg_commands =~ (^| )$prev($| ) ]] ; then
|
29
|
+
_vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null)
|
25
30
|
COMPREPLY=( $(compgen -W "${_vmfloaty_active_hostnames}" -- "${cur}") )
|
26
|
-
|
27
|
-
COMPREPLY=( $(compgen -W "${
|
31
|
+
elif [[ "service" == $prev ]] ; then
|
32
|
+
COMPREPLY=( $(compgen -W "${service_subcommands}" -- "${cur}") )
|
33
|
+
elif [[ $1 == $prev ]] ; then
|
34
|
+
# only show top level commands we are at root
|
35
|
+
COMPREPLY=( $(compgen -W "${commands}" -- "${cur}") )
|
28
36
|
fi
|
29
37
|
}
|
30
38
|
complete -F _vmfloaty floaty
|
@@ -0,0 +1,43 @@
|
|
1
|
+
_floaty()
|
2
|
+
{
|
3
|
+
local line commands template_arg_commands hostname_arg_commands service_subcommands
|
4
|
+
|
5
|
+
commands="delete get help list modify query revert service snapshot ssh status summary token"
|
6
|
+
|
7
|
+
template_arg_commands=("get" "ssh")
|
8
|
+
hostname_arg_commands=("delete" "modify" "query" "revert" "snapshot")
|
9
|
+
service_subcommands=("types" "examples")
|
10
|
+
|
11
|
+
_arguments -C \
|
12
|
+
"1: :(${commands})" \
|
13
|
+
"*::arg:->args"
|
14
|
+
|
15
|
+
if ((template_arg_commands[(Ie)$line[1]])); then
|
16
|
+
_floaty_template_sub
|
17
|
+
elif ((hostname_arg_commands[(Ie)$line[1]])); then
|
18
|
+
_floaty_hostname_sub
|
19
|
+
elif [[ "service" == $line[1] ]]; then
|
20
|
+
_arguments "1: :(${service_subcommands})"
|
21
|
+
fi
|
22
|
+
}
|
23
|
+
|
24
|
+
_floaty_template_sub()
|
25
|
+
{
|
26
|
+
if [[ -z "$_vmfloaty_avail_templates" ]] ; then
|
27
|
+
# TODO: need a --hostnameonly equivalent here because the section headers of
|
28
|
+
# `floaty list` are adding some spurious entries (including files in current
|
29
|
+
# directory because part of the headers is `**` which is getting expanded)
|
30
|
+
_vmfloaty_avail_templates=$(floaty list 2>/dev/null)
|
31
|
+
fi
|
32
|
+
|
33
|
+
_arguments "1: :(${_vmfloaty_avail_templates})"
|
34
|
+
}
|
35
|
+
|
36
|
+
_floaty_hostname_sub()
|
37
|
+
{
|
38
|
+
_vmfloaty_active_hostnames=$(floaty list --active --hostnameonly 2>/dev/null)
|
39
|
+
|
40
|
+
_arguments "1: :(${_vmfloaty_active_hostnames})"
|
41
|
+
}
|
42
|
+
|
43
|
+
compdef _floaty floaty
|
data/lib/vmfloaty.rb
CHANGED
@@ -13,13 +13,14 @@ require 'vmfloaty/conf'
|
|
13
13
|
require 'vmfloaty/utils'
|
14
14
|
require 'vmfloaty/service'
|
15
15
|
require 'vmfloaty/ssh'
|
16
|
+
require 'vmfloaty/logger'
|
16
17
|
|
17
18
|
class Vmfloaty
|
18
19
|
include Commander::Methods
|
19
20
|
|
20
21
|
def run # rubocop:disable Metrics/AbcSize
|
21
22
|
program :version, Vmfloaty::VERSION
|
22
|
-
program :description, "A CLI helper tool for Puppet's vmpooler to help you stay afloat"
|
23
|
+
program :description, "A CLI helper tool for Puppet's vmpooler to help you stay afloat.\n\nConfiguration may be placed in a ~/.vmfloaty.yml file."
|
23
24
|
|
24
25
|
config = Conf.read_config
|
25
26
|
|
@@ -38,33 +39,38 @@ class Vmfloaty
|
|
38
39
|
c.option '--force', 'Forces vmfloaty to get requested vms'
|
39
40
|
c.option '--json', 'Prints retrieved vms in JSON format'
|
40
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)'
|
41
44
|
c.action do |args, options|
|
42
45
|
verbose = options.verbose || config['verbose']
|
46
|
+
if options.loglevel
|
47
|
+
FloatyLogger.setlevel = options.loglevel
|
48
|
+
end
|
43
49
|
service = Service.new(options, config)
|
44
50
|
use_token = !options.notoken
|
45
51
|
force = options.force
|
46
52
|
|
47
53
|
if args.empty?
|
48
|
-
|
54
|
+
FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
|
49
55
|
exit 1
|
50
56
|
end
|
51
57
|
|
52
58
|
os_types = Utils.generate_os_hash(args)
|
53
59
|
|
54
|
-
|
55
|
-
|
56
|
-
if !large_pool_requests.empty? && !force
|
57
|
-
STDERR.puts "Requesting vms over #{max_pool_request} requires a --force flag."
|
58
|
-
STDERR.puts 'Try again with `floaty get --force`'
|
60
|
+
if os_types.empty?
|
61
|
+
FloatyLogger.error 'No operating systems provided to obtain. See `floaty get --help` for more information on how to get VMs.'
|
59
62
|
exit 1
|
60
63
|
end
|
61
64
|
|
62
|
-
|
63
|
-
|
65
|
+
max_pool_request = 5
|
66
|
+
large_pool_requests = os_types.select { |_, v| v > max_pool_request }
|
67
|
+
if !large_pool_requests.empty? && !force
|
68
|
+
FloatyLogger.error "Requesting vms over #{max_pool_request} requires a --force flag."
|
69
|
+
FloatyLogger.error 'Try again with `floaty get --force`'
|
64
70
|
exit 1
|
65
71
|
end
|
66
72
|
|
67
|
-
response = service.retrieve(verbose, os_types, use_token, options.ondemand)
|
73
|
+
response = service.retrieve(verbose, os_types, use_token, options.ondemand, options.continue)
|
68
74
|
request_id = response['request_id'] if options.ondemand
|
69
75
|
response = service.wait_for_request(verbose, request_id) if options.ondemand
|
70
76
|
|
@@ -86,23 +92,47 @@ class Vmfloaty
|
|
86
92
|
c.option '--verbose', 'Enables verbose output'
|
87
93
|
c.option '--service STRING', String, 'Configured pooler service name'
|
88
94
|
c.option '--active', 'Prints information about active vms for a given token'
|
95
|
+
c.option '--json', 'Prints information as JSON'
|
96
|
+
c.option '--hostnameonly', 'When listing active vms, prints only hostnames, one per line'
|
89
97
|
c.option '--token STRING', String, 'Token for pooler service'
|
90
98
|
c.option '--url STRING', String, 'URL of pooler service'
|
99
|
+
c.option '--user STRING', String, 'User to authenticate with'
|
100
|
+
c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
|
91
101
|
c.action do |args, options|
|
92
102
|
verbose = options.verbose || config['verbose']
|
103
|
+
if options.loglevel
|
104
|
+
FloatyLogger.setlevel = options.loglevel
|
105
|
+
end
|
93
106
|
|
94
107
|
service = Service.new(options, config)
|
95
108
|
filter = args[0]
|
96
109
|
|
97
110
|
if options.active
|
98
111
|
# list active vms
|
99
|
-
|
112
|
+
if service.type == "ABS"
|
113
|
+
# this is actually job_ids
|
114
|
+
running_vms = service.list_active_job_ids(verbose, service.url, service.user)
|
115
|
+
else
|
116
|
+
running_vms = service.list_active(verbose)
|
117
|
+
end
|
100
118
|
host = URI.parse(service.url).host
|
101
119
|
if running_vms.empty?
|
102
|
-
|
120
|
+
if options.json
|
121
|
+
puts {}.to_json
|
122
|
+
else
|
123
|
+
FloatyLogger.info "You have no running VMs on #{host}"
|
124
|
+
end
|
103
125
|
else
|
104
|
-
|
105
|
-
|
126
|
+
if options.json
|
127
|
+
puts Utils.get_host_data(verbose, service, running_vms).to_json
|
128
|
+
elsif options.hostnameonly
|
129
|
+
Utils.get_host_data(verbose, service, running_vms).each do |hostname, host_data|
|
130
|
+
Utils.print_fqdn_for_host(service, hostname, host_data)
|
131
|
+
end
|
132
|
+
else
|
133
|
+
puts "Your VMs on #{host}:"
|
134
|
+
Utils.pretty_print_hosts(verbose, service, running_vms)
|
135
|
+
end
|
106
136
|
end
|
107
137
|
else
|
108
138
|
# list available vms from pooler
|
@@ -115,7 +145,7 @@ class Vmfloaty
|
|
115
145
|
command :query do |c|
|
116
146
|
c.syntax = 'floaty query hostname [options]'
|
117
147
|
c.summary = 'Get information about a given vm'
|
118
|
-
c.description = 'Given a hostname from the pooler service, vmfloaty with query the service to get various details about the vm.'
|
148
|
+
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'
|
119
149
|
c.example 'Get information about a sample host', 'floaty query hostname --url http://vmpooler.example.com'
|
120
150
|
c.option '--verbose', 'Enables verbose output'
|
121
151
|
c.option '--service STRING', String, 'Configured pooler service name'
|
@@ -151,10 +181,15 @@ class Vmfloaty
|
|
151
181
|
modify_all = options.all
|
152
182
|
|
153
183
|
if hostname.nil? && !modify_all
|
154
|
-
|
184
|
+
FloatyLogger.error 'ERROR: Provide a hostname or specify --all.'
|
155
185
|
exit 1
|
156
186
|
end
|
157
|
-
running_vms =
|
187
|
+
running_vms =
|
188
|
+
if modify_all
|
189
|
+
service.list_active(verbose)
|
190
|
+
else
|
191
|
+
hostname.split(',')
|
192
|
+
end
|
158
193
|
|
159
194
|
tags = options.tags ? JSON.parse(options.tags) : nil
|
160
195
|
modify_hash = {
|
@@ -172,13 +207,13 @@ class Vmfloaty
|
|
172
207
|
begin
|
173
208
|
modified_hash[vm] = service.modify(verbose, vm, modify_hash)
|
174
209
|
rescue ModifyError => e
|
175
|
-
|
210
|
+
FloatyLogger.error e
|
176
211
|
ok = false
|
177
212
|
end
|
178
213
|
end
|
179
214
|
if ok
|
180
215
|
if modify_all
|
181
|
-
puts
|
216
|
+
puts "Successfully modified all #{running_vms.count} VMs."
|
182
217
|
else
|
183
218
|
puts "Successfully modified VM #{hostname}."
|
184
219
|
end
|
@@ -199,10 +234,17 @@ class Vmfloaty
|
|
199
234
|
c.option '--service STRING', String, 'Configured pooler service name'
|
200
235
|
c.option '--all', 'Deletes all vms acquired by a token'
|
201
236
|
c.option '-f', 'Does not prompt user when deleting all vms'
|
237
|
+
c.option '--json', 'Outputs hosts scheduled for deletion as JSON'
|
202
238
|
c.option '--token STRING', String, 'Token for pooler service'
|
203
239
|
c.option '--url STRING', String, 'URL of pooler service'
|
240
|
+
c.option '--user STRING', String, 'User to authenticate with'
|
241
|
+
c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
|
204
242
|
c.action do |args, options|
|
205
243
|
verbose = options.verbose || config['verbose']
|
244
|
+
if options.loglevel
|
245
|
+
FloatyLogger.setlevel = options.loglevel
|
246
|
+
end
|
247
|
+
|
206
248
|
service = Service.new(options, config)
|
207
249
|
hostnames = args[0]
|
208
250
|
delete_all = options.all
|
@@ -212,15 +254,25 @@ class Vmfloaty
|
|
212
254
|
successes = []
|
213
255
|
|
214
256
|
if delete_all
|
215
|
-
|
257
|
+
if service.type == "ABS"
|
258
|
+
# this is actually job_ids
|
259
|
+
running_vms = service.list_active_job_ids(verbose, service.url, service.user)
|
260
|
+
else
|
261
|
+
running_vms = service.list_active(verbose)
|
262
|
+
end
|
216
263
|
if running_vms.empty?
|
217
|
-
|
264
|
+
if options.json
|
265
|
+
puts {}.to_json
|
266
|
+
else
|
267
|
+
FloatyLogger.info "You have no running VMs."
|
268
|
+
end
|
218
269
|
else
|
219
|
-
Utils.pretty_print_hosts(verbose, service, running_vms)
|
220
|
-
# Confirm deletion
|
221
|
-
puts
|
222
270
|
confirmed = true
|
223
|
-
|
271
|
+
unless force
|
272
|
+
Utils.pretty_print_hosts(verbose, service, running_vms, true)
|
273
|
+
# Confirm deletion
|
274
|
+
confirmed = agree('Delete all these VMs? [y/N]')
|
275
|
+
end
|
224
276
|
if confirmed
|
225
277
|
response = service.delete(verbose, running_vms)
|
226
278
|
response.each do |hostname, result|
|
@@ -243,23 +295,28 @@ class Vmfloaty
|
|
243
295
|
end
|
244
296
|
end
|
245
297
|
else
|
246
|
-
|
298
|
+
FloatyLogger.info 'You did not provide any hosts to delete'
|
247
299
|
exit 1
|
248
300
|
end
|
249
301
|
|
250
302
|
unless failures.empty?
|
251
|
-
|
303
|
+
FloatyLogger.info 'Unable to delete the following VMs:'
|
252
304
|
failures.each do |hostname|
|
253
|
-
|
305
|
+
FloatyLogger.info "- #{hostname}"
|
254
306
|
end
|
255
|
-
|
307
|
+
FloatyLogger.info 'Check `floaty list --active`; Do you need to specify a different service?'
|
256
308
|
end
|
257
309
|
|
258
310
|
unless successes.empty?
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
puts
|
311
|
+
if options.json
|
312
|
+
puts successes.to_json
|
313
|
+
else
|
314
|
+
puts 'Scheduled the following VMs for deletion:'
|
315
|
+
output = ''
|
316
|
+
successes.each do |hostname|
|
317
|
+
output += "- #{hostname}\n"
|
318
|
+
end
|
319
|
+
puts output
|
263
320
|
end
|
264
321
|
end
|
265
322
|
|
@@ -284,7 +341,7 @@ class Vmfloaty
|
|
284
341
|
begin
|
285
342
|
snapshot_req = service.snapshot(verbose, hostname)
|
286
343
|
rescue TokenError, ModifyError => e
|
287
|
-
|
344
|
+
FloatyLogger.error e
|
288
345
|
exit 1
|
289
346
|
end
|
290
347
|
|
@@ -309,12 +366,12 @@ class Vmfloaty
|
|
309
366
|
hostname = args[0]
|
310
367
|
snapshot_sha = args[1] || options.snapshot
|
311
368
|
|
312
|
-
|
369
|
+
FloatyLogger.info "Two snapshot arguments were given....using snapshot #{snapshot_sha}" if args[1] && options.snapshot
|
313
370
|
|
314
371
|
begin
|
315
372
|
revert_req = service.revert(verbose, hostname, snapshot_sha)
|
316
373
|
rescue TokenError, ModifyError => e
|
317
|
-
|
374
|
+
FloatyLogger.error e
|
318
375
|
exit 1
|
319
376
|
end
|
320
377
|
|
@@ -331,8 +388,12 @@ class Vmfloaty
|
|
331
388
|
c.option '--service STRING', String, 'Configured pooler service name'
|
332
389
|
c.option '--url STRING', String, 'URL of pooler service'
|
333
390
|
c.option '--json', 'Prints status in JSON format'
|
391
|
+
c.option '--loglevel STRING', String, 'the log level to use (debug, info, error)'
|
334
392
|
c.action do |_, options|
|
335
393
|
verbose = options.verbose || config['verbose']
|
394
|
+
if options.loglevel
|
395
|
+
FloatyLogger.setlevel = options.loglevel
|
396
|
+
end
|
336
397
|
service = Service.new(options, config)
|
337
398
|
if options.json
|
338
399
|
pp service.status(verbose)
|
@@ -389,14 +450,14 @@ class Vmfloaty
|
|
389
450
|
status = service.token_status(verbose, token_value)
|
390
451
|
puts status
|
391
452
|
when nil
|
392
|
-
|
453
|
+
FloatyLogger.error 'No action provided'
|
393
454
|
exit 1
|
394
455
|
else
|
395
|
-
|
456
|
+
FloatyLogger.error "Unknown action: #{action}"
|
396
457
|
exit 1
|
397
458
|
end
|
398
459
|
rescue TokenError => e
|
399
|
-
|
460
|
+
FloatyLogger.error e
|
400
461
|
exit 1
|
401
462
|
end
|
402
463
|
exit 0
|
@@ -420,13 +481,13 @@ class Vmfloaty
|
|
420
481
|
use_token = !options.notoken
|
421
482
|
|
422
483
|
if args.empty?
|
423
|
-
|
484
|
+
FloatyLogger.error 'No operating systems provided to obtain. See `floaty ssh --help` for more information on how to get VMs.'
|
424
485
|
exit 1
|
425
486
|
end
|
426
487
|
|
427
488
|
host_os = args.first
|
428
489
|
|
429
|
-
|
490
|
+
FloatyLogger.info "Can't ssh to multiple hosts; Using #{host_os} only..." if args.length > 1
|
430
491
|
|
431
492
|
service.ssh(verbose, host_os, use_token)
|
432
493
|
exit 0
|
@@ -453,7 +514,71 @@ class Vmfloaty
|
|
453
514
|
puts completion_file
|
454
515
|
exit 0
|
455
516
|
else
|
456
|
-
|
517
|
+
FloatyLogger.error "Could not find completion file for '#{shell}': No such file #{completion_file}"
|
518
|
+
exit 1
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
command :service do |c|
|
524
|
+
c.syntax = 'floaty service <types examples>'
|
525
|
+
c.summary = 'Display information about floaty services and their configuration'
|
526
|
+
c.description = 'Display information about floaty services to aid in setting up a configuration file.'
|
527
|
+
c.example 'Print a list of the valid service types', 'floaty service types'
|
528
|
+
c.example 'Print a sample config file with multiple services', 'floaty service examples'
|
529
|
+
c.example 'list vms from the service named "nspooler-prod"', 'floaty list --service nspooler-prod'
|
530
|
+
c.action do |args, options|
|
531
|
+
action = args.first
|
532
|
+
|
533
|
+
example_config = Utils.strip_heredoc(<<-CONFIG)
|
534
|
+
# Sample ~/.vmfloaty.yml with just vmpooler
|
535
|
+
user: 'jdoe'
|
536
|
+
url: 'https://vmpooler.example.net'
|
537
|
+
token: '456def789'
|
538
|
+
|
539
|
+
# Sample ~/.vmfloaty.yml with multiple services
|
540
|
+
# Note: when the --service is not specified on the command line,
|
541
|
+
# the first service listed here is selected automatically
|
542
|
+
user: 'jdoe'
|
543
|
+
services:
|
544
|
+
abs-prod:
|
545
|
+
type: 'abs'
|
546
|
+
url: 'https://abs.example.net/api/v2'
|
547
|
+
token: '123abc456'
|
548
|
+
vmpooler_fallback: 'vmpooler-prod'
|
549
|
+
nspooler-prod:
|
550
|
+
type: 'nspooler'
|
551
|
+
url: 'https://nspooler.example.net'
|
552
|
+
token: '789ghi012'
|
553
|
+
vmpooler-dev:
|
554
|
+
type: 'vmpooler'
|
555
|
+
url: 'https://vmpooler-dev.example.net'
|
556
|
+
token: '987dsa654'
|
557
|
+
vmpooler-prod:
|
558
|
+
type: 'vmpooler'
|
559
|
+
url: 'https://vmpooler.example.net'
|
560
|
+
token: '456def789'
|
561
|
+
|
562
|
+
CONFIG
|
563
|
+
|
564
|
+
types_output = Utils.strip_heredoc(<<-TYPES)
|
565
|
+
The values on the left below can be used in ~/.vmfloaty.yml as the value of type:
|
566
|
+
|
567
|
+
abs: Puppet's Always Be Scheduling
|
568
|
+
nspooler: Puppet's Non-standard Pooler, aka NSPooler
|
569
|
+
vmpooler: Puppet's VMPooler
|
570
|
+
TYPES
|
571
|
+
|
572
|
+
case action
|
573
|
+
when 'examples'
|
574
|
+
FloatyLogger.info example_config
|
575
|
+
when 'types'
|
576
|
+
FloatyLogger.info types_output
|
577
|
+
when nil
|
578
|
+
FloatyLogger.error 'No action provided'
|
579
|
+
exit 1
|
580
|
+
else
|
581
|
+
FloatyLogger.error "Unknown action: #{action}"
|
457
582
|
exit 1
|
458
583
|
end
|
459
584
|
end
|