opennebula 5.4.15 → 5.5.80.pre

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/NOTICE +1 -1
  3. data/lib/ActionManager.rb +1 -1
  4. data/lib/CommandManager.rb +82 -59
  5. data/lib/DriverExecHelper.rb +1 -1
  6. data/lib/OpenNebulaDriver.rb +1 -1
  7. data/lib/VirtualMachineDriver.rb +1 -1
  8. data/lib/cloud/CloudClient.rb +3 -3
  9. data/lib/opennebula.rb +2 -2
  10. data/lib/opennebula/acl.rb +1 -1
  11. data/lib/opennebula/acl_pool.rb +1 -1
  12. data/lib/opennebula/client.rb +1 -1
  13. data/lib/opennebula/cluster.rb +1 -1
  14. data/lib/opennebula/cluster_pool.rb +1 -1
  15. data/lib/opennebula/datastore.rb +1 -1
  16. data/lib/opennebula/datastore_pool.rb +1 -1
  17. data/lib/opennebula/document.rb +1 -1
  18. data/lib/opennebula/document_json.rb +1 -1
  19. data/lib/opennebula/document_pool.rb +1 -1
  20. data/lib/opennebula/document_pool_json.rb +1 -1
  21. data/lib/opennebula/error.rb +1 -1
  22. data/lib/opennebula/group.rb +1 -1
  23. data/lib/opennebula/group_pool.rb +1 -1
  24. data/lib/opennebula/host.rb +1 -1
  25. data/lib/opennebula/host_pool.rb +1 -1
  26. data/lib/opennebula/image.rb +12 -2
  27. data/lib/opennebula/image_pool.rb +1 -1
  28. data/lib/opennebula/ldap_auth.rb +15 -20
  29. data/lib/opennebula/ldap_auth_spec.rb +1 -1
  30. data/lib/opennebula/marketplace.rb +1 -1
  31. data/lib/opennebula/marketplace_pool.rb +1 -1
  32. data/lib/opennebula/marketplaceapp.rb +14 -2
  33. data/lib/opennebula/marketplaceapp_pool.rb +1 -1
  34. data/lib/opennebula/oneflow_client.rb +1 -1
  35. data/lib/opennebula/pool.rb +1 -1
  36. data/lib/opennebula/pool_element.rb +24 -3
  37. data/lib/opennebula/security_group.rb +1 -1
  38. data/lib/opennebula/security_group_pool.rb +1 -1
  39. data/lib/opennebula/server_cipher_auth.rb +1 -1
  40. data/lib/opennebula/server_x509_auth.rb +1 -1
  41. data/lib/opennebula/ssh_auth.rb +1 -1
  42. data/lib/opennebula/system.rb +1 -1
  43. data/lib/opennebula/template.rb +14 -2
  44. data/lib/opennebula/template_pool.rb +1 -1
  45. data/lib/opennebula/user.rb +1 -1
  46. data/lib/opennebula/user_pool.rb +1 -1
  47. data/lib/opennebula/utils.rb +20 -1
  48. data/lib/opennebula/vdc.rb +1 -1
  49. data/lib/opennebula/vdc_pool.rb +1 -1
  50. data/lib/opennebula/virtual_machine.rb +19 -4
  51. data/lib/opennebula/virtual_machine_pool.rb +1 -1
  52. data/lib/opennebula/virtual_network.rb +12 -2
  53. data/lib/opennebula/virtual_network_pool.rb +1 -1
  54. data/lib/opennebula/virtual_router.rb +13 -1
  55. data/lib/opennebula/virtual_router_pool.rb +1 -1
  56. data/lib/opennebula/vm_group.rb +14 -2
  57. data/lib/opennebula/vm_group_pool.rb +1 -1
  58. data/lib/opennebula/x509_auth.rb +1 -1
  59. data/lib/opennebula/xml_element.rb +10 -1
  60. data/lib/opennebula/xml_pool.rb +1 -1
  61. data/lib/opennebula/xml_utils.rb +1 -1
  62. data/lib/opennebula/zone.rb +67 -1
  63. data/lib/opennebula/zone_pool.rb +1 -1
  64. data/lib/vcenter_driver.rb +17 -1
  65. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 787d43768bd9a76d896cb0a960818c34c0a46d01
4
- data.tar.gz: d246a6e077184ee02bee81977a2b1db62b357ebb
3
+ metadata.gz: e3d15137240bd50cd5cd0b5b710f2391a9f59a02
4
+ data.tar.gz: 8e57ca62e09d70ba52f2ed134277b87666815e3c
5
5
  SHA512:
6
- metadata.gz: 5f60cf48564b462b9563206a2d0358cd100520acdde77f3cdf3f5a4a69c2da22622d42d08fc40999e1168827d4559bd3c432b14badb426256e6921471e21c38d
7
- data.tar.gz: a92b4d493963ba1072b87cc6de707b005ae8453b0210b8f65c03e8918ccb5207a8bd1037df0662c161b05df177e0a7ed503341673708b989598fc300f421d367
6
+ metadata.gz: 8493c8467c61fe2da156ac062f69ebc85274f8b6de47c0ce49322d7214e7ce0a8ae3c56582d86593040fd93997499b3adbe0c5da6134115926fb1a1de95030fd
7
+ data.tar.gz: a398e6261cb6c11383b2dcfc395f32c91a9d2d611567156e322305041c2245c856858beae40cb164167535ccf2729fc91274842e8388f4ad9f067c815683b2f1
data/NOTICE CHANGED
@@ -1,6 +1,6 @@
1
1
  OpenNebula Open Source Project
2
2
  --------------------------------------------------------------------------------
3
- Copyright 2002-2016, OpenNebula Project, OpenNebula Systems (formerly C12G Labs)
3
+ Copyright 2002-2018, OpenNebula Project, OpenNebula Systems (formerly C12G Labs)
4
4
  --------------------------------------------------------------------------------
5
5
 
6
6
  You can find more information about the project, release notes and
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- */
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License"); you may */
4
4
  # not use this file except in compliance with the License. You may obtain */
5
5
  # a copy of the License at */
@@ -1,5 +1,5 @@
1
1
  # --------------------------------------------------------------------------
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may
5
5
  # not use this file except in compliance with the License. You may obtain
@@ -16,7 +16,6 @@
16
16
 
17
17
  require 'pp'
18
18
  require 'open3'
19
- require 'stringio'
20
19
  require 'timeout'
21
20
 
22
21
  # Generic command executor that holds the code shared by all the command
@@ -70,59 +69,30 @@ class GenericCommand
70
69
  @logger.call(message, all) if @logger
71
70
  end
72
71
 
73
- def kill(pid)
74
- # executed processes now have its own process group to be able
75
- # to kill all children
76
- pgid = Process.getpgid(pid)
77
-
78
- # Kill all processes belonging to process group
79
- Process.kill("HUP", pgid * -1)
80
- end
81
-
82
72
  # Runs the command
83
73
  def run
84
- std = nil
85
- process = Proc.new do
86
- std = execute
87
-
88
- # Close standard IO descriptors
89
- if @stdin
90
- std[0] << @stdin
91
- std[0].flush
92
- end
93
- std[0].close if !std[0].closed?
94
-
95
- @stdout=std[1].read
96
- std[1].close if !std[1].closed?
97
-
98
- @stderr=std[2].read
99
- std[2].close if !std[2].closed?
74
+ begin
75
+ @stdout, @stderr, status = execute
100
76
 
101
- @code=get_exit_code(@stderr)
77
+ if status && status.exited?
78
+ @code = status.exitstatus
79
+ else
80
+ @code = 255
81
+ end
102
82
 
103
- if @code!=0
104
- log("Command execution fail: #{command}")
83
+ if @code != 0
84
+ log("Command execution failed (exit code: #{@code}): #{command}")
105
85
  log(@stderr)
106
86
  end
107
- end
108
-
109
- begin
110
- if @timeout
111
- Timeout.timeout(@timeout, nil, &process)
87
+ rescue Exception => e
88
+ if e.is_a?(Timeout::Error)
89
+ error_message = "Timeout executing #{command}"
112
90
  else
113
- process.call
91
+ error_message = "Internal error #{e}"
114
92
  end
115
- rescue Timeout::Error
116
- error_message = "Timeout executing #{command}"
117
- log(error_message)
118
93
 
94
+ log(error_message)
119
95
  @stderr = ERROR_OPEN + "\n" + error_message + "\n" + ERROR_CLOSE
120
-
121
- 3.times {|n| std[n].close if !std[n].closed? }
122
-
123
- pid = std[-1].pid
124
- self.kill(pid)
125
-
126
96
  @code = 255
127
97
  end
128
98
 
@@ -138,19 +108,72 @@ class GenericCommand
138
108
 
139
109
  private
140
110
 
141
- # Gets exit code from STDERR
142
- def get_exit_code(str)
143
- tmp=str.scan(/^ExitCode: (\d*)$/)
144
- return nil if !tmp[0]
145
- tmp[0][0].to_i
146
- end
147
-
148
111
  # Low level command execution. This method has to be redefined
149
112
  # for each kind of command execution. Returns an array with
150
- # +stdin+, +stdout+ and +stderr+ handlers of the command execution.
113
+ # +stdout+, +stderr+ and +status+ of the command execution.
151
114
  def execute
152
115
  puts "About to execute \"#{@command}\""
153
- [StringIO.new, StringIO.new, StringIO.new]
116
+ ['', '', nil]
117
+ end
118
+
119
+ # modified Open3.capture with terminator thread
120
+ # to deal with timeouts
121
+ def capture3_timeout(*cmd)
122
+ if Hash === cmd.last
123
+ opts = cmd.pop.dup
124
+ else
125
+ opts = {}
126
+ end
127
+
128
+ stdin_data = opts.delete(:stdin_data) || ''
129
+ binmode = opts.delete(:binmode)
130
+
131
+ Open3.popen3(*cmd, opts) {|i, o, e, t|
132
+ if binmode
133
+ i.binmode
134
+ o.binmode
135
+ e.binmode
136
+ end
137
+
138
+ terminator_e = nil
139
+ mutex = Mutex.new
140
+
141
+ out_reader = Thread.new { o.read }
142
+ err_reader = Thread.new { e.read }
143
+ terminator = Thread.new {
144
+ if @timeout and @timeout>0
145
+ begin
146
+ pid = Process.getpgid(t.pid) * -1
147
+ rescue
148
+ pid = t.pid
149
+ end
150
+
151
+ if pid
152
+ begin
153
+ sleep @timeout
154
+
155
+ mutex.synchronize do
156
+ terminator_e = Timeout::Error
157
+ end
158
+ ensure
159
+ end
160
+
161
+ Process.kill('TERM', pid)
162
+ end
163
+ end
164
+ }
165
+
166
+ i.write stdin_data
167
+ i.close
168
+
169
+ out = [out_reader.value, err_reader.value, t.value]
170
+
171
+ mutex.lock
172
+ terminator.kill
173
+ raise terminator_e if terminator_e
174
+
175
+ out
176
+ }
154
177
  end
155
178
 
156
179
  end
@@ -161,8 +184,8 @@ class LocalCommand < GenericCommand
161
184
  private
162
185
 
163
186
  def execute
164
- Open3.popen3("#{command} ; echo ExitCode: $? 1>&2",
165
- :pgroup => true)
187
+ capture3_timeout("#{command}",
188
+ :pgroup => true, :stdin_data => @stdin)
166
189
  end
167
190
  end
168
191
 
@@ -189,10 +212,10 @@ private
189
212
 
190
213
  def execute
191
214
  if @stdin
192
- Open3.popen3("ssh #{@host} #{@command} ; echo ExitCode: $? 1>&2",
193
- :pgroup => true)
215
+ capture3_timeout("ssh #{@host} #{@command}",
216
+ :pgroup => true, :stdin_data => @stdin)
194
217
  else
195
- Open3.popen3("ssh -n #{@host} #{@command} ; echo ExitCode: $? 1>&2",
218
+ capture3_timeout("ssh -n #{@host} #{@command}",
196
219
  :pgroup => true)
197
220
  end
198
221
  end
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -50,7 +50,7 @@ end
50
50
  module CloudClient
51
51
 
52
52
  # OpenNebula version
53
- VERSION = '5.4.15'
53
+ VERSION = '5.5.80'
54
54
 
55
55
  # #########################################################################
56
56
  # Default location for the authentication file
@@ -207,7 +207,7 @@ module CloudCLI
207
207
  def version_text
208
208
  version=<<EOT
209
209
  OpenNebula #{CloudClient::VERSION}
210
- Copyright 2002-2017, OpenNebula Project, OpenNebula Systems
210
+ Copyright 2002-2018, OpenNebula Project, OpenNebula Systems
211
211
 
212
212
  Licensed under the Apache License, Version 2.0 (the "License"); you may
213
213
  not use this file except in compliance with the License. You may obtain
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -69,5 +69,5 @@ require 'opennebula/vm_group_pool'
69
69
  module OpenNebula
70
70
 
71
71
  # OpenNebula version
72
- VERSION = '5.4.15'
72
+ VERSION = '5.5.80'
73
73
  end
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #
@@ -38,7 +38,9 @@ module OpenNebula
38
38
  :rename => "image.rename",
39
39
  :snapshotdelete => "image.snapshotdelete",
40
40
  :snapshotrevert => "image.snapshotrevert",
41
- :snapshotflatten=> "image.snapshotflatten"
41
+ :snapshotflatten=> "image.snapshotflatten",
42
+ :lock => "image.lock",
43
+ :unlock => "image.unlock"
42
44
  }
43
45
 
44
46
  IMAGE_STATES=%w{INIT READY USED DISABLED LOCKED ERROR CLONE DELETE
@@ -296,6 +298,14 @@ module OpenNebula
296
298
  self['GID'].to_i
297
299
  end
298
300
 
301
+ def lock(level)
302
+ return call(IMAGE_METHODS[:lock], @pe_id, level)
303
+ end
304
+
305
+ def unlock()
306
+ return call(IMAGE_METHODS[:unlock], @pe_id)
307
+ end
308
+
299
309
  def public?
300
310
  if self['PERMISSIONS/GROUP_U'] == "1" || self['PERMISSIONS/OTHER_U'] == "1"
301
311
  true
@@ -1,5 +1,5 @@
1
1
  # -------------------------------------------------------------------------- #
2
- # Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
2
+ # Copyright 2002-2018, OpenNebula Project, OpenNebula Systems #
3
3
  # #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
5
  # not use this file except in compliance with the License. You may obtain #