Nitrous plugin will install Base OS, multipath options, create VMs and their network settings for Fuel provisioning and deployment.
US809843 Change-Id: I18c8c10021da170ad9aaa29fe1410c4b4072ece5
This commit is contained in:
parent
c2a23b04f1
commit
df37614679
|
@ -0,0 +1,202 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 2016 AT&T Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
- name: additional_service:nitrous
|
||||||
|
compatible:
|
||||||
|
- name: 'hypervisor:kvm'
|
||||||
|
- name: 'hypervisor:qemu'
|
||||||
|
requires: []
|
||||||
|
incompatible:
|
||||||
|
- name: 'hypervisor:vmware'
|
||||||
|
label: "Nitrous"
|
||||||
|
description: "Configures bare metal servers and Fuel deployable VMs."
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
notice('MODULAR: nitrous/nitrous.pp')
|
||||||
|
|
||||||
|
include nitrous
|
||||||
|
|
||||||
|
class { 'nitrous::packages': }
|
||||||
|
class { 'nitrous::config': }
|
||||||
|
|
||||||
|
exec { '/etc/ops_create.sh' :
|
||||||
|
path => '/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||||
|
require => Class['nitrous'],
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:find_node, :type => :rvalue, :doc => <<-EOS
|
||||||
|
EOS
|
||||||
|
) do |args|
|
||||||
|
nodes = args[0]
|
||||||
|
required_name = args[1]
|
||||||
|
fail "Nodes should be an Array! Got: #{nodes.inspect}" unless nodes.is_a? Array
|
||||||
|
nodes.find do |node|
|
||||||
|
node['mac_address'] == required_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:opsvm_filter, :type => :rvalue, :doc => <<-EOS
|
||||||
|
Filter the ops_server_config array and convert to the structure readable by the opsvm script.
|
||||||
|
EOS
|
||||||
|
) do |args|
|
||||||
|
ops_server_config = args[0]
|
||||||
|
pxe_br = args[2]
|
||||||
|
kvm_filter = args[1]
|
||||||
|
mgt_br = args[3]
|
||||||
|
fail "The ops_server_config should be an Array! Got: #{ops_server_config}" unless ops_server_config.is_a? Array
|
||||||
|
kvm_hosts = []
|
||||||
|
ops_server_config.each do |op_host|
|
||||||
|
next unless op_host['kvm'] == kvm_filter
|
||||||
|
|
||||||
|
host_hash = {}
|
||||||
|
host_hash['name'] = op_host['name'] if op_host['name']
|
||||||
|
host_hash['cpu'] = op_host.fetch('cpu', 2)
|
||||||
|
host_hash['ram'] = op_host.fetch('ram', 2).to_i * 1024
|
||||||
|
|
||||||
|
networks = []
|
||||||
|
pxe_network = {}
|
||||||
|
pxe_network['network'] = "#{pxe_br}"
|
||||||
|
pxe_network['mac'] = op_host['mac_address']
|
||||||
|
networks << pxe_network
|
||||||
|
mgmt_network = {}
|
||||||
|
mgmt_network['network'] = "#{mgt_br}"
|
||||||
|
networks << mgmt_network
|
||||||
|
|
||||||
|
host_hash['networks'] = networks
|
||||||
|
|
||||||
|
volumes = []
|
||||||
|
app_volume = {}
|
||||||
|
app_volume['size'] = op_host.fetch('app_disk', 10).to_i * 1024 * 1024 * 1024
|
||||||
|
app_volume['name'] = op_host['app_volume_name']
|
||||||
|
app_volume['name'] = "app_disk_#{host_hash['name']}" unless app_volume['name']
|
||||||
|
volumes << app_volume
|
||||||
|
os_volume = {}
|
||||||
|
os_volume['size'] = op_host.fetch('os_disk', 10).to_i * 1024 * 1024 * 1024
|
||||||
|
os_volume['name'] = op_host['os_volume_name']
|
||||||
|
os_volume['name'] = "os_disk_#{host_hash['name']}" unless os_volume['name']
|
||||||
|
volumes << os_volume
|
||||||
|
log_volume = {}
|
||||||
|
log_volume['size'] = op_host.fetch('log_disk', 10).to_i * 1024 * 1024 * 1024
|
||||||
|
log_volume['name'] = op_host['log_volume_name']
|
||||||
|
log_volume['name'] = "log_disk_#{host_hash['name']}" unless log_volume['name']
|
||||||
|
volumes << log_volume
|
||||||
|
|
||||||
|
host_hash['volumes'] = volumes
|
||||||
|
|
||||||
|
kvm_hosts << host_hash
|
||||||
|
end
|
||||||
|
kvm_hosts
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,198 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
require 'rexml/document'
|
||||||
|
require 'tempfile'
|
||||||
|
|
||||||
|
Puppet::Type.type(:opsvm_pool).provide(:virsh) do
|
||||||
|
|
||||||
|
commands :virsh => 'virsh'
|
||||||
|
|
||||||
|
def self.instances
|
||||||
|
list = virsh('-q', 'pool-list', '--all')
|
||||||
|
list.split(/\n/)[0..-1].map do |line|
|
||||||
|
values = line.strip.split(/ +/)
|
||||||
|
new(
|
||||||
|
:name => values[0],
|
||||||
|
:active => values[1].match(/^act/)? :true : :false,
|
||||||
|
:autostart => values[2].match(/no/) ? :false : :true,
|
||||||
|
:provider => self.name
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def status
|
||||||
|
list = virsh('-q', 'pool-list', '--all')
|
||||||
|
list.split(/\n/)[0..-1].detect do |line|
|
||||||
|
fields = line.strip.split(/ +/)
|
||||||
|
if (fields[0].match(/^#{resource[:name]}$/))
|
||||||
|
return :present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return :absent
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.prefetch(resources)
|
||||||
|
pools = instances
|
||||||
|
resources.keys.each do |name|
|
||||||
|
if provider = pools.find{ |pool| pool.name == name}
|
||||||
|
resources[name].provider = provider
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
defined = self.definePool
|
||||||
|
if !defined
|
||||||
|
# for some reason the pool has not been defined
|
||||||
|
# malformed xml
|
||||||
|
# or failed tmpfile creationa
|
||||||
|
# or ?
|
||||||
|
raise Puppet::Error.new("Unable to define the pool")
|
||||||
|
end
|
||||||
|
self.buildPool
|
||||||
|
|
||||||
|
@property_hash[:ensure] = :present
|
||||||
|
should_active = @resource.should(:active)
|
||||||
|
unless self.active == should_active
|
||||||
|
self.active = should_active
|
||||||
|
end
|
||||||
|
should_autostart = @resource.should(:autostart)
|
||||||
|
unless self.autostart == should_autostart
|
||||||
|
self.autostart = should_autostart
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
self.destroyPool
|
||||||
|
@property_hash.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
def definePool
|
||||||
|
result = false
|
||||||
|
begin
|
||||||
|
tmpFile = Tempfile.new("pool.#{resource[:name]}")
|
||||||
|
xml = buildPoolXML resource
|
||||||
|
tmpFile.write(xml)
|
||||||
|
tmpFile.rewind
|
||||||
|
virsh('pool-define', tmpFile.path)
|
||||||
|
result = true
|
||||||
|
ensure
|
||||||
|
tmpFile.close
|
||||||
|
tmpFile.unlink
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
def buildPool
|
||||||
|
begin
|
||||||
|
virsh('pool-build', '--pool', resource[:name])
|
||||||
|
rescue
|
||||||
|
# Unable to build the pool maybe because
|
||||||
|
# it is already defined (it this case we should consider
|
||||||
|
# to continue execution)
|
||||||
|
# or there is permission issue on the fs
|
||||||
|
# or ?
|
||||||
|
# in these cases we should consider raising something
|
||||||
|
notice("Unable to build the pool")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroyPool
|
||||||
|
begin
|
||||||
|
virsh('pool-destroy', resource[:name])
|
||||||
|
rescue Puppet::ExecutionFailure => e
|
||||||
|
notice(e.message)
|
||||||
|
end
|
||||||
|
virsh('pool-undefine', resource[:name])
|
||||||
|
end
|
||||||
|
|
||||||
|
def active
|
||||||
|
@property_hash[:active] || :false
|
||||||
|
end
|
||||||
|
|
||||||
|
def active=(active)
|
||||||
|
if (active == :true)
|
||||||
|
virsh 'pool-start', '--pool', resource[:name]
|
||||||
|
@property_hash[:active] = 'true'
|
||||||
|
else
|
||||||
|
virsh 'pool-destroy', '--pool', resource[:name]
|
||||||
|
@property_hash[:active] = 'false'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def autostart
|
||||||
|
@property_hash[:autostart] || :false
|
||||||
|
end
|
||||||
|
|
||||||
|
def autostart=(autostart)
|
||||||
|
if (autostart == :true)
|
||||||
|
virsh 'pool-autostart', '--pool', resource[:name]
|
||||||
|
@property_hash[:autostart] = :true
|
||||||
|
else
|
||||||
|
virsh 'pool-autostart', '--pool', resource[:name], '--disable'
|
||||||
|
@property_hash[:autostart] = :false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def exists?
|
||||||
|
@property_hash[:ensure] != :absent
|
||||||
|
end
|
||||||
|
|
||||||
|
def buildPoolXML(resource)
|
||||||
|
root = REXML::Document.new
|
||||||
|
pool = root.add_element 'pool', {'type' => resource[:type]}
|
||||||
|
name = pool.add_element 'name'
|
||||||
|
name.add_text resource[:name]
|
||||||
|
|
||||||
|
srcHost = resource[:sourcehost]
|
||||||
|
srcPath = resource[:sourcepath]
|
||||||
|
srcDev = resource[:sourcedev]
|
||||||
|
srcName = resource[:sourcename]
|
||||||
|
srcFormat = resource[:sourceformat]
|
||||||
|
|
||||||
|
if (srcHost || srcPath || srcDev || srcName || srcFormat)
|
||||||
|
source = pool.add_element 'source'
|
||||||
|
|
||||||
|
source.add_element('host', {'name' => srcHost}) if srcHost
|
||||||
|
source.add_element('dir', {'path' => srcPath}) if srcPath
|
||||||
|
source.add_element('format', {'type' => srcFormat}) if (srcFormat)
|
||||||
|
|
||||||
|
if (srcDev)
|
||||||
|
Array(srcDev).each do |dev|
|
||||||
|
source.add_element('device', {'path' => dev})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (srcName)
|
||||||
|
srcNameEl = source.add_element 'name'
|
||||||
|
srcNameEl.add_text srcName
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
target = resource[:target]
|
||||||
|
if target
|
||||||
|
targetEl = pool.add_element 'target'
|
||||||
|
targetPathEl = targetEl.add_element 'path'
|
||||||
|
targetPathEl.add_text target
|
||||||
|
end
|
||||||
|
|
||||||
|
return root.to_s
|
||||||
|
|
||||||
|
end # buildPoolXML
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,118 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
Puppet::Type.newtype(:opsvm_pool) do
|
||||||
|
@doc = %q{Manages opsvm pools
|
||||||
|
|
||||||
|
Example :
|
||||||
|
opsvm_pool { 'default' :
|
||||||
|
ensure => absent
|
||||||
|
}
|
||||||
|
|
||||||
|
opsvm_pool { 'mydirpool' :
|
||||||
|
ensure => present,
|
||||||
|
active => true,
|
||||||
|
autostart => true,
|
||||||
|
type => 'dir',
|
||||||
|
target => '/tmp/mypool',
|
||||||
|
}
|
||||||
|
|
||||||
|
opsvm_pool { 'vm_storage':
|
||||||
|
ensure => 'present',
|
||||||
|
active => 'true',
|
||||||
|
type => 'logical',
|
||||||
|
sourcedev => ['/dev/sdb', '/dev/sdc'],
|
||||||
|
target => '/dev/vg0'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ensurable do
|
||||||
|
|
||||||
|
desc 'Creation or the removal of a pool`present` means that the pool will be defined and created
|
||||||
|
`absent` means that the pool will be purged from the system'
|
||||||
|
|
||||||
|
defaultto(:present)
|
||||||
|
newvalue(:present) do
|
||||||
|
provider.create
|
||||||
|
end
|
||||||
|
|
||||||
|
newvalue(:absent) do
|
||||||
|
if (provider.exists?)
|
||||||
|
provider.destroy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def retrieve
|
||||||
|
provider.status
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:name, :namevar => true) do
|
||||||
|
desc 'The pool name.'
|
||||||
|
newvalues(/^\S+$/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:type) do
|
||||||
|
desc 'The pool type.'
|
||||||
|
newvalues(:dir, :netfs, :fs, :logical, :disk, :iscsi, :mpath, :rbd, :sheepdog)
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:sourcehost) do
|
||||||
|
desc 'The source host.'
|
||||||
|
newvalues(/^\S+$/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:sourcepath) do
|
||||||
|
desc 'The source path.'
|
||||||
|
newvalues(/(\/)?(\w)/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:sourcedev) do
|
||||||
|
desc 'The source device.'
|
||||||
|
newvalues(/(\/)?(\w)/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:sourcename) do
|
||||||
|
desc 'The source name.'
|
||||||
|
newvalues(/^\S+$/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:sourceformat) do
|
||||||
|
desc 'The source format.'
|
||||||
|
newvalues(:auto, :nfs, :glusterfs, :cifs)
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:target) do
|
||||||
|
desc 'The target.'
|
||||||
|
newvalues(/(\/)?(\w)/)
|
||||||
|
end
|
||||||
|
|
||||||
|
newproperty(:active) do
|
||||||
|
desc 'Whether the pool should be started.'
|
||||||
|
defaultto(:true)
|
||||||
|
newvalues(:true)
|
||||||
|
newvalues(:false)
|
||||||
|
end
|
||||||
|
|
||||||
|
newproperty(:autostart) do
|
||||||
|
desc 'Whether the pool should be autostarted.'
|
||||||
|
defaultto(:false)
|
||||||
|
newvalues(:true)
|
||||||
|
newvalues(:false)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,65 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
class nitrous::config {
|
||||||
|
|
||||||
|
$ops_hosts = $::nitrous::kvm_hosts
|
||||||
|
$ops_endpoints_keys = $::nitrous::endpoints_keys
|
||||||
|
$pool_type = $::nitrous::opsvm_pool_type
|
||||||
|
|
||||||
|
file { 'opsvms_settings' :
|
||||||
|
ensure => 'present',
|
||||||
|
path => '/etc/hiera/plugins/fuel_opsvms.yaml',
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '0644',
|
||||||
|
content => inline_template('<%= require "yaml"; YAML.dump(@ops_hosts) + "\n" %>'),
|
||||||
|
}
|
||||||
|
|
||||||
|
file_line { 'kvm_user':
|
||||||
|
path => '/etc/libvirt/qemu.conf',
|
||||||
|
line => 'user = "root"',
|
||||||
|
match => '#user = "root"',
|
||||||
|
} ~>
|
||||||
|
|
||||||
|
service {'libvirtd':
|
||||||
|
ensure => 'running',
|
||||||
|
}
|
||||||
|
|
||||||
|
opsvm_pool { 'default' :
|
||||||
|
ensure => present,
|
||||||
|
type => "$pool_type",
|
||||||
|
active => true,
|
||||||
|
target => '/opt/opsvm',
|
||||||
|
}
|
||||||
|
|
||||||
|
if !($::nitrous::node_name == '') {
|
||||||
|
exec { "/bin/hostname $::nitrous::node_name" :
|
||||||
|
path => '/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning('Node is not available, please check Nitrous config.')
|
||||||
|
}
|
||||||
|
|
||||||
|
puppet::ops_endpoints_keys::keys { $ops_endpoints_keys: }
|
||||||
|
define puppet::ops_endpoints_keys::keys ($ops_endpoints_keys = $title) {
|
||||||
|
if ($::nitrous::net_bridge == 'linuxbr') {
|
||||||
|
opsvm_net { "$ops_endpoints_keys" :
|
||||||
|
forward_mode => 'bridge',
|
||||||
|
bridge => "$ops_endpoints_keys",
|
||||||
|
autostart => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
class nitrous {
|
||||||
|
|
||||||
|
$hiera_values = hiera_hash('nitrous', {})
|
||||||
|
$nitrous_config = $hiera_values['node_additional_config']
|
||||||
|
$nodes_hash = parseyaml($nitrous_config)
|
||||||
|
$nodes_array = pick($nodes_hash['nodes'], [])
|
||||||
|
|
||||||
|
$authors = 'Dinesh Yadav(dy270k@att.com)'
|
||||||
|
$plugin_version = $hiera_values['metadata']['plugin_version']
|
||||||
|
|
||||||
|
$agent_conf = '/etc/puppet/puppet.conf'
|
||||||
|
$env_conf = '/etc/rc.local'
|
||||||
|
$libvirt_conf = '/etc/libvirt'
|
||||||
|
$line = $hiera_values['puppet_master_entry']
|
||||||
|
$proxy_line = $hiera_values['aic_env_proxy']
|
||||||
|
$site_yaml = '/etc/hiera/plugins/site.yaml'
|
||||||
|
|
||||||
|
$network_scheme = hiera_hash('network_scheme', {})
|
||||||
|
$net_bridge = $hiera_values['selective_default_bridge']
|
||||||
|
$endpoints = pick($network_scheme['endpoints'])
|
||||||
|
$endpoints_keys = keys($endpoints)
|
||||||
|
$node_nic = upcase($::macaddress_br_fw_admin)
|
||||||
|
$bond_nic = upcase($::macaddress_bond0)
|
||||||
|
|
||||||
|
$nitrous_node = find_node($nodes_array, $node_nic)
|
||||||
|
$node_name = downcase($nitrous_node['name'])
|
||||||
|
$kvm_hostname = "$node_name"
|
||||||
|
$ops_vms_array = parseyaml($hiera_values["ops_server_config"])
|
||||||
|
|
||||||
|
$initiator_config='/etc/iscsi/initiatorname.iscsi'
|
||||||
|
$storage = $nitrous_node['storage']
|
||||||
|
$luns = $storage['luns']
|
||||||
|
$storage_type = $storage['initiator_name']
|
||||||
|
$storage_array = pick($nodes_hash['storage'], [])
|
||||||
|
$target_node = $storage_array['targets']
|
||||||
|
$opsvm_pool_type = $hiera_values['selective_opsvm_pool']
|
||||||
|
|
||||||
|
$kvm_hosts = opsvm_filter($ops_vms_array, $kvm_hostname, br-fw-admin, br-mgmt)
|
||||||
|
$vlan_tag = split($stg_nm, '\.')
|
||||||
|
$vlan_id = $::nitrous::vlan_tag[1]
|
||||||
|
$nic_bond = pick($network_scheme['transformations'])
|
||||||
|
$mgmt = $nic_bond[6]
|
||||||
|
$mgmt_brg = pick($mgmt['bridge'])
|
||||||
|
$mgmt_nm = pick($mgmt['name'])
|
||||||
|
$stg = $nic_bond[7]
|
||||||
|
$stg_brg = pick($stg['bridge'])
|
||||||
|
$stg_nm = pick($stg['name'])
|
||||||
|
$prv = $nic_bond[8]
|
||||||
|
$prv_brg = pick($prv['bridge'])
|
||||||
|
$prv_nm = pick($prv['name'])
|
||||||
|
|
||||||
|
if !($proxy_line == 'undef') {
|
||||||
|
file_line { 'env_proxy':
|
||||||
|
ensure => 'present',
|
||||||
|
line => "export http_proxy=$:nitrous::proxy_line",
|
||||||
|
path => "$::nitrous::env_conf",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exec { "src_bash":
|
||||||
|
command => "bash -c 'source $env_conf'",
|
||||||
|
path => '/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||||
|
}
|
||||||
|
|
||||||
|
file_line { 'agent_conf' :
|
||||||
|
ensure => 'present',
|
||||||
|
line => "server = $line",
|
||||||
|
path => "$agent_conf",
|
||||||
|
after => 'pluginsync = True',
|
||||||
|
}
|
||||||
|
|
||||||
|
file { "$site_yaml":
|
||||||
|
ensure => 'present',
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '0766',
|
||||||
|
content => template('nitrous/nitrous.yaml.erb'),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !($vlan_id == '') {
|
||||||
|
file { '/usr/local/bin/rm_vlan.sh':
|
||||||
|
ensure => 'present',
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '0766',
|
||||||
|
content => template('nitrous/vlan.erb'),
|
||||||
|
}
|
||||||
|
exec { 'remove_vlan':
|
||||||
|
command => '/usr/local/bin/rm_vlan.sh',
|
||||||
|
path => '/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||||
|
}
|
||||||
|
exec { 'add_brg':
|
||||||
|
command => "brctl addif br-mgmt bond0",
|
||||||
|
path => '/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file { '/usr/bin/opsvm':
|
||||||
|
ensure => 'present',
|
||||||
|
owner => 'root',
|
||||||
|
group => 'root',
|
||||||
|
mode => '0766',
|
||||||
|
content => template('nitrous/opsvm.erb'),
|
||||||
|
}
|
||||||
|
|
||||||
|
anchor {'nitrous_begin' : } ->
|
||||||
|
Class['nitrous::packages'] ->
|
||||||
|
Class['nitrous::config'] ->
|
||||||
|
anchor {'nitrous_end' : }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
define nitrous::opsvm_net (
|
||||||
|
$bridge,
|
||||||
|
$forward_mode = 'bridge',
|
||||||
|
$virtualport_type = undef,
|
||||||
|
$portgroups = [],
|
||||||
|
$autostart = true,
|
||||||
|
) {
|
||||||
|
exec {"opsvm-network-${name}":
|
||||||
|
command => join(['f=$(mktemp) && echo "',
|
||||||
|
template('nitrous/netbr.erb'),
|
||||||
|
'" > $f && virsh net-define $f && rm $f']),
|
||||||
|
provider => 'shell',
|
||||||
|
creates => "${nitrous::libvirt_conf}/qemu/networks/${name}.xml",
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($autostart) {
|
||||||
|
exec {"opsvm-network-autostart-${name}":
|
||||||
|
command => "virsh net-autostart ${name}",
|
||||||
|
provider => 'shell',
|
||||||
|
creates => "${nitrous::libvirt_conf}/qemu/networks/autostart/${name}.xml",
|
||||||
|
require => Exec["opsvm-network-${name}"],
|
||||||
|
}
|
||||||
|
|
||||||
|
exec {"opsvm-network-start-${name}":
|
||||||
|
command => "virsh net-start ${name}",
|
||||||
|
provider => 'shell',
|
||||||
|
unless => "virsh net-list | tail -n +3 | cut -d ' ' -f 2 | \
|
||||||
|
grep -q ^${name}$",
|
||||||
|
require => Exec["opsvm-network-${name}"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
class nitrous::packages {
|
||||||
|
|
||||||
|
# Resources defaults
|
||||||
|
|
||||||
|
$required_pkgs = ['qemu-kvm', 'libvirt-bin', 'db-util', 'db5.3-util', 'debhelper', 'dh-apparmor', 'gettext', 'ieee-data', 'intltool-debian', 'libcroco3', 'libunistring0', 'open-iscsi', 'po-debconf', 'python-crypto', 'python-ecdsa', 'python-libvirt', 'python-markupsafe', 'python-netaddr', 'python-netifaces', 'python-paramiko', 'qemu-utils', 'sasl2-bin', 'libasprintf-dev', 'libgettextpo-dev', 'libmail-sendmail-perl', 'sharutils','virtinst', 'ebtables', 'dnsmasq', 'libpcre3', 'cloud-guest-utils', 'cloud-image-utils', 'cloud-utils', 'euca2ools', 'fabric', 'ipmitool', 'genisoimage', 'libattr1', 'libreadline6', 'libsqlite3-0','mime-support', 'module-assistant', 'openvswitch-datapath-source', 'python-ipaddr', 'python-lxml', 'python-mako','python-nose', 'python-oauth', 'python-oauthlib', 'python-pexpect', 'python-requestbuilder', 'python-requests-oauthlib', 'readline-common' ]
|
||||||
|
|
||||||
|
package { $required_pkgs :
|
||||||
|
ensure => installed
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<%=
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
%>
|
||||||
|
<network>
|
||||||
|
<name><%= @name %></name>
|
||||||
|
<% if @forward_mode -%>
|
||||||
|
<forward mode='<%= @forward_mode %>'/>
|
||||||
|
<% end -%>
|
||||||
|
<% if @bridge -%>
|
||||||
|
<bridge name='<%= @bridge %>'/>
|
||||||
|
<% end -%>
|
||||||
|
<% if @virtualport_type -%>
|
||||||
|
<virtualport type='<%= @virtualport_type %>'/>
|
||||||
|
<% end -%>
|
||||||
|
</network>
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
---
|
||||||
|
<%= @nitrous_config %>
|
|
@ -0,0 +1,692 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
require 'optparse'
|
||||||
|
require 'yaml'
|
||||||
|
require 'open3'
|
||||||
|
require 'securerandom'
|
||||||
|
|
||||||
|
# Libvirt API interface functions
|
||||||
|
module LibVirt
|
||||||
|
|
||||||
|
# Delete a domain by it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
def domain_delete(domain_name)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'undefine',
|
||||||
|
domain_name,
|
||||||
|
]
|
||||||
|
debug "Domain delete: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
error "Failed to delete domain: #{domain_name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
|
||||||
|
# Start a domain by it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
def domain_start(domain_name)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'start',
|
||||||
|
domain_name,
|
||||||
|
]
|
||||||
|
debug "Domain start: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
warning "Failed to start domain: #{domain_name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set autostart for a domain by it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
def domain_autostart(domain_name)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'autostart',
|
||||||
|
domain_name,
|
||||||
|
]
|
||||||
|
debug "Domain autostart: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
warning "Failed to autostart domain: #{domain_name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unset autostart for a domain by it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
def domain_no_autostart(domain_name)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'--disable',
|
||||||
|
'autostart',
|
||||||
|
domain_name,
|
||||||
|
]
|
||||||
|
debug "Domain no autostart: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
warning "Failed to stop autostart domain: #{domain_name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
|
||||||
|
# Stop a domain by it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
def domain_stop(domain_name)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'destroy',
|
||||||
|
domain_name,
|
||||||
|
]
|
||||||
|
debug "Domain stop: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
warning "Failed to stop domain: #{domain_name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get a list of all defined domains, states and ids (if running)
|
||||||
|
# @return [Hash<String => Hash>]
|
||||||
|
def domain_list
|
||||||
|
command = %w(virsh list --all)
|
||||||
|
domains = {}
|
||||||
|
output, success = run command
|
||||||
|
error 'Failed to get domain list! Is you libvirt service running?' unless success
|
||||||
|
output.split("\n").each do |line|
|
||||||
|
line_array = line.split
|
||||||
|
id = line_array[0]
|
||||||
|
name = line_array[1]
|
||||||
|
state = line_array[2..-1]
|
||||||
|
next unless id and name and state
|
||||||
|
id = id.chomp.strip
|
||||||
|
name = name.chomp.strip
|
||||||
|
state = state.join(' ').chomp.strip
|
||||||
|
next if id == 'Id'
|
||||||
|
domain_hash = {}
|
||||||
|
domain_hash['state'] = state
|
||||||
|
domain_hash['id'] = id unless id == '-'
|
||||||
|
domains[name] = domain_hash
|
||||||
|
end
|
||||||
|
domains
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if a domain is started for it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
# @return [true,false]
|
||||||
|
def domain_started?(domain_name)
|
||||||
|
domain_state(domain_name) == 'running'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get a state of a domain by it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
# @return [String]
|
||||||
|
def domain_state(domain_name)
|
||||||
|
domain_attributes = domain_list.fetch domain_name, {}
|
||||||
|
domain_attributes.fetch 'state', 'missing'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if a domain is defined by it's name
|
||||||
|
# @param [String] domain_name
|
||||||
|
# @return [true,false]
|
||||||
|
def domain_defined?(domain_name)
|
||||||
|
domain_list.key? domain_name
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create a new libvirt volume if a pool
|
||||||
|
# @param [String] volume_name
|
||||||
|
# @param [String] virt_type
|
||||||
|
# @param [String,Numeric] volume_size
|
||||||
|
# @return [true,false] success?
|
||||||
|
def volume_create(volume_name, virt_type, volume_size)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'vol-create-as',
|
||||||
|
virt_type,
|
||||||
|
volume_name,
|
||||||
|
volume_size,
|
||||||
|
]
|
||||||
|
|
||||||
|
debug "Volume create: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
error "Failed to create volume: #{volume_name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get a path of a volume in a pool by it's name
|
||||||
|
# Returns nil if there is no such volume
|
||||||
|
# @param [String] volume_name
|
||||||
|
# @param [String] pool_name
|
||||||
|
# @return [String,nil]
|
||||||
|
def volume_path(volume_name, pool_name)
|
||||||
|
volume_list(pool_name).fetch(volume_name, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete a volume in a pool by its name
|
||||||
|
# @param [String] volume_name
|
||||||
|
# @param [String] pool_name
|
||||||
|
# @return [true,false] success?
|
||||||
|
def volume_delete(volume_name, pool_name)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'vol-delete',
|
||||||
|
'--pool', pool_name,
|
||||||
|
volume_name
|
||||||
|
]
|
||||||
|
debug "Delete volume: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
error "Failed to delete volume: #{volume_name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
|
||||||
|
# List all volumes in a pool
|
||||||
|
# @param [String] pool_name
|
||||||
|
# @return [Hash<String => String>] Volume name and path
|
||||||
|
def volume_list(pool_name)
|
||||||
|
commands = [
|
||||||
|
'virsh',
|
||||||
|
'vol-list',
|
||||||
|
'--pool', pool_name,
|
||||||
|
]
|
||||||
|
output, success = run commands
|
||||||
|
error "Failed to get volume list of pool: #{pool_name}!" unless success
|
||||||
|
volumes = {}
|
||||||
|
output.split("\n").each do |line|
|
||||||
|
line_array = line.split
|
||||||
|
name = line_array[0]
|
||||||
|
path = line_array[1]
|
||||||
|
next unless name and path
|
||||||
|
name = name.chomp.strip
|
||||||
|
path = path.chomp.strip
|
||||||
|
next if name == 'Name'
|
||||||
|
volumes[name] = path
|
||||||
|
end
|
||||||
|
volumes
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if a volume in a pool is defined
|
||||||
|
# @param [String] volume_name
|
||||||
|
# @param [String] pool_name
|
||||||
|
# @return [true,false]
|
||||||
|
def volume_defined?(volume_name, pool_name)
|
||||||
|
volume_list(pool_name).key? volume_name
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate a new serial for a disk
|
||||||
|
# @return [String]
|
||||||
|
def generate_disk_serial
|
||||||
|
::SecureRandom.uuid
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create a new domain using it's attributes structure
|
||||||
|
# @param [String] domain_name
|
||||||
|
# @param [Hash] domain_attributes
|
||||||
|
# @return [true,false] success?
|
||||||
|
def domain_create(domain_name, domain_attributes)
|
||||||
|
name = domain_attributes.fetch 'name', domain_name
|
||||||
|
fail 'There is no domain name!' unless name
|
||||||
|
ram = domain_attributes.fetch 'ram', '1024'
|
||||||
|
cpu = domain_attributes.fetch 'cpu', '2'
|
||||||
|
volumes = domain_attributes.fetch 'volumes', {}
|
||||||
|
networks = domain_attributes.fetch 'networks', {}
|
||||||
|
commands = [
|
||||||
|
'virt-install',
|
||||||
|
'--name', name,
|
||||||
|
'--ram', ram,
|
||||||
|
'--vcpus', "#{cpu},cores=#{cpu}",
|
||||||
|
'--os-type', 'linux',
|
||||||
|
'--virt-type', options[:virt],
|
||||||
|
'--pxe',
|
||||||
|
'--boot', 'network,hd',
|
||||||
|
'--noautoconsole',
|
||||||
|
'--graphics', 'vnc,listen=0.0.0.0',
|
||||||
|
'--autostart',
|
||||||
|
]
|
||||||
|
|
||||||
|
volumes.each do |volume|
|
||||||
|
volume['serial'] = generate_disk_serial unless volume['serial']
|
||||||
|
volume['cache'] = 'none' unless volume['cache']
|
||||||
|
volume['bus'] = 'virtio' unless volume['bus']
|
||||||
|
|
||||||
|
unless volume['path']
|
||||||
|
warning "Volume: #{volume.inspect} has no path defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
disk_string = volume.reject do |attribute_name, _attribute_value|
|
||||||
|
%w(size name).include? attribute_name
|
||||||
|
end.map do |attribute_name, attribute_value|
|
||||||
|
"#{attribute_name}=#{attribute_value}"
|
||||||
|
end.join ','
|
||||||
|
|
||||||
|
commands += ['--disk', disk_string]
|
||||||
|
end
|
||||||
|
|
||||||
|
networks.each do |network|
|
||||||
|
network['model'] = 'virtio' unless network['model']
|
||||||
|
|
||||||
|
unless network['network']
|
||||||
|
warning "Network: #{network.inspect} has no 'network' defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
network_string = network.map do |attribute_name, attribute_value|
|
||||||
|
"#{attribute_name}=#{attribute_value}"
|
||||||
|
end.join ','
|
||||||
|
commands += ['--network', network_string]
|
||||||
|
end
|
||||||
|
|
||||||
|
debug "Domain create: #{commands.join ' '}"
|
||||||
|
_output, success = run commands
|
||||||
|
error "Failed to create the domain: #{name}" unless success
|
||||||
|
success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Configuration and settings related functions
|
||||||
|
module Configuration
|
||||||
|
|
||||||
|
# The structure describing the domains to manage
|
||||||
|
# @return [Hash]
|
||||||
|
def domain_settings
|
||||||
|
error "There is no YAML file: #{options[:yaml]}" unless File.exists? options[:yaml]
|
||||||
|
begin
|
||||||
|
data = YAML.load_file options[:yaml]
|
||||||
|
rescue => exception
|
||||||
|
error "Could not read YAML file: #{options[:yaml]}: #{exception}"
|
||||||
|
end
|
||||||
|
error "Data format of YAML file: #{options[:yaml]} is incorrect!" unless data.is_a? Array
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
|
# Console options structure
|
||||||
|
# @return [Hash]
|
||||||
|
def options
|
||||||
|
return @options if @options
|
||||||
|
@options = {}
|
||||||
|
|
||||||
|
OptionParser.new do |opts|
|
||||||
|
opts.banner = 'opsvm [options] (domain)'
|
||||||
|
|
||||||
|
opts.on('-D', '--delete', 'Delete the created domains and volumes') do
|
||||||
|
@options[:delete] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-R', '--recreate', 'Delete and create the domains and volumes') do
|
||||||
|
@options[:recreate] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-s', '--stop', 'Stop all created domains') do
|
||||||
|
@options[:stop] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-r', '--start', 'Start all created domains') do
|
||||||
|
@options[:start] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-l', '--list', 'List the domains and volumes') do
|
||||||
|
@options[:list] = true
|
||||||
|
@options[:all] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-c', '--config', 'Show the requested configuration of the domains and volumes') do
|
||||||
|
@options[:config] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-a', '--all', 'Process all domains') do
|
||||||
|
@options[:all] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-d', '--debug', 'Show debug messages') do
|
||||||
|
@options[:debug] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-C', '--console', 'Run the debug console') do
|
||||||
|
@options[:debug] = true
|
||||||
|
@options[:console] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-y', '--yaml FILE', 'Settings YAML file') do |value|
|
||||||
|
@options[:yaml] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-q', '--qemu', 'Use QEMU instead of KVM') do
|
||||||
|
@options[:virt] = 'qemu'
|
||||||
|
end
|
||||||
|
|
||||||
|
opts.on('-p', '--pool POOL', 'The name of the libvirt storage pool') do |value|
|
||||||
|
@options[:pool] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
end.parse!
|
||||||
|
|
||||||
|
@options
|
||||||
|
end
|
||||||
|
|
||||||
|
def munge_options
|
||||||
|
return unless options.is_a? Hash
|
||||||
|
options[:yaml] = '/etc/hiera/plugins/fuel_opsvms.yaml' unless options[:yaml]
|
||||||
|
options[:pool] = 'default' unless options[:pool]
|
||||||
|
options[:virt] = 'kvm' unless options[:virt]
|
||||||
|
options[:hosts] = ARGV.compact.uniq
|
||||||
|
|
||||||
|
unless options[:all] or (options[:hosts] and options[:hosts].any?)
|
||||||
|
error "You have to provided any hosts names to work with.
|
||||||
|
Please, give obne or more host name or use '-a' to work on all defined hosts!
|
||||||
|
Defined hosts: #{domain_names.join ', '}"
|
||||||
|
end
|
||||||
|
debug "Options: #{options.inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# Main KVM control logic class
|
||||||
|
class KvmControl
|
||||||
|
attr_writer :options
|
||||||
|
include Configuration
|
||||||
|
include LibVirt
|
||||||
|
|
||||||
|
# The filtered list of domains
|
||||||
|
# It should contain only the domains from the command line
|
||||||
|
# or all domains if the "-a" is set.
|
||||||
|
def domains
|
||||||
|
domain_settings.select do |domain|
|
||||||
|
options[:all] or options[:hosts].include? domain['name']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get an array of defined domain names
|
||||||
|
# @return [Array<Staring>]
|
||||||
|
def domain_names
|
||||||
|
domain_settings.map do |domain|
|
||||||
|
domain['name']
|
||||||
|
end.compact.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run the debug console
|
||||||
|
def console
|
||||||
|
require 'pry'
|
||||||
|
binding.pry
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show the configuration
|
||||||
|
def show_config
|
||||||
|
info YAML.dump domains
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
# The 'list' action
|
||||||
|
# Lists all domains and their statuses
|
||||||
|
def action_list
|
||||||
|
domain_statuses = domain_list
|
||||||
|
max_length = domain_names.max_by { |d| d.length }.length
|
||||||
|
|
||||||
|
domain_names.each do |domain_name|
|
||||||
|
domain_attributes = domain_statuses.fetch(domain_name, {})
|
||||||
|
domain_state = domain_attributes.fetch 'state', 'missing'
|
||||||
|
info "#{domain_name.ljust max_length} - #{domain_state}"
|
||||||
|
end
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
# The 'delete' action
|
||||||
|
# Stops domains and deletes volumes and domains
|
||||||
|
def action_delete
|
||||||
|
domains_stop
|
||||||
|
domains_delete
|
||||||
|
volumes_delete
|
||||||
|
end
|
||||||
|
|
||||||
|
# The 'create action'
|
||||||
|
# Creates volumes and domains,
|
||||||
|
# starts domains and marks them for autostart
|
||||||
|
def action_create
|
||||||
|
volumes_create
|
||||||
|
domains_create
|
||||||
|
domains_autostart
|
||||||
|
domains_stop
|
||||||
|
domains_start
|
||||||
|
end
|
||||||
|
|
||||||
|
# The 'recreate' action
|
||||||
|
# Calls 'delete' and 'create' actions
|
||||||
|
def action_recreate
|
||||||
|
action_delete
|
||||||
|
action_create
|
||||||
|
end
|
||||||
|
|
||||||
|
# The 'stop' action
|
||||||
|
# Stop all domains in the working set
|
||||||
|
def action_stop
|
||||||
|
domains_stop
|
||||||
|
end
|
||||||
|
|
||||||
|
# The 'start' action
|
||||||
|
# Start all domains in the working set
|
||||||
|
def action_start
|
||||||
|
domains_start
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create all domains in the working set
|
||||||
|
def domains_create
|
||||||
|
debug 'Call: domains_create'
|
||||||
|
domains.each do |domain|
|
||||||
|
domain_name = domain.fetch 'name'
|
||||||
|
next unless domain_name
|
||||||
|
if domain_defined? domain_name
|
||||||
|
warning "Domain: #{domain_name} is already defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
resolve_volume_paths domain['volumes']
|
||||||
|
domain_create domain_name, domain
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Resolve the path of a libvirt volumes by their names
|
||||||
|
# If volume has a path already defined it will be skipped
|
||||||
|
# @param [Array] volumes
|
||||||
|
def resolve_volume_paths(volumes)
|
||||||
|
return unless volumes.is_a? Array
|
||||||
|
volumes.each do |volume|
|
||||||
|
next if volume['path']
|
||||||
|
volume['path'] = volume_path volume['name'], options[:pool]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create volumes for the domains in the working set
|
||||||
|
def volumes_create
|
||||||
|
domains.each do |domain|
|
||||||
|
volumes = domain.fetch 'volumes', {}
|
||||||
|
volumes.each do |volume|
|
||||||
|
volume_size = volume.fetch 'size'
|
||||||
|
volume_name = volume.fetch 'name'
|
||||||
|
next unless volume_name and volume_size
|
||||||
|
if volume_defined? volume_name, options[:pool]
|
||||||
|
warning "Volume: #{volume_name} of the pool: #{options[:pool]} is already created! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
if volume['path']
|
||||||
|
info "Volume: #{volume_name} has a path already defined. Assuming it's already created!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
volume_create volume_name, options[:pool], volume_size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete all volumes of domains in the working set
|
||||||
|
def volumes_delete
|
||||||
|
debug 'Call: volumes_delete'
|
||||||
|
domains.each do |domain|
|
||||||
|
volumes = domain.fetch 'volumes', {}
|
||||||
|
volumes.each do |volume|
|
||||||
|
volume_name = volume.fetch 'name'
|
||||||
|
next unless volume_name
|
||||||
|
unless volume_defined? volume_name, options[:pool]
|
||||||
|
info "Volume: #{volume_name} of the pool: #{options[:pool]} is not defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
volume_delete volume_name, options[:pool]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete all domains in the working set
|
||||||
|
def domains_delete
|
||||||
|
debug 'Call: domains_delete'
|
||||||
|
domains.each do |domain|
|
||||||
|
domain_name = domain.fetch 'name'
|
||||||
|
next unless domain_name
|
||||||
|
unless domain_defined? domain_name
|
||||||
|
warning "Domain: #{domain_name} is not defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
domain_delete domain_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Start all domains in the working set
|
||||||
|
def domains_start
|
||||||
|
debug 'Call: domains_start'
|
||||||
|
domains.each do |domain|
|
||||||
|
domain_name = domain.fetch 'name'
|
||||||
|
next unless domain_name
|
||||||
|
unless domain_defined? domain_name
|
||||||
|
warning "Domain: #{domain_name} is not defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
if domain_started? domain_name
|
||||||
|
warning "Domain: #{domain_name} is already started! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
domain_start domain_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unset autostart mark from all domain in the working set
|
||||||
|
def domains_no_autostart
|
||||||
|
debug 'Call: domains_no_autostart'
|
||||||
|
domains.each do |domain|
|
||||||
|
domain_name = domain.fetch 'name'
|
||||||
|
next unless domain_name
|
||||||
|
unless domain_defined? domain_name
|
||||||
|
warning "Domain: #{domain_name} is not defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
domain_no_autostart domain_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Mark all domains in the working set for autostart
|
||||||
|
def domains_autostart
|
||||||
|
debug 'Call: domains_autostart'
|
||||||
|
domains.each do |domain|
|
||||||
|
domain_name = domain.fetch 'name'
|
||||||
|
next unless domain_name
|
||||||
|
unless domain_defined? domain_name
|
||||||
|
warning "Domain: #{domain_name} is not defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
domain_autostart domain_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Stop all domains in the working set
|
||||||
|
def domains_stop
|
||||||
|
debug 'Call: domains_stop'
|
||||||
|
domains.each do |domain|
|
||||||
|
domain_name = domain.fetch 'name'
|
||||||
|
next unless domain_name
|
||||||
|
unless domain_defined? domain_name
|
||||||
|
warning "Domain: #{domain_name} is not defined! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
unless domain_started? domain_name
|
||||||
|
warning "Domain: #{domain_name} is not started! Skipping!"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
domain_stop domain_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run the command
|
||||||
|
# @param [Array] commands
|
||||||
|
# @return [Array] Array of stdout and success boolean value
|
||||||
|
def run(*commands)
|
||||||
|
commands.flatten!
|
||||||
|
commands.map!(&:to_s)
|
||||||
|
out, status = Open3.capture2 *commands
|
||||||
|
[out, status.exitstatus == 0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def debug(message)
|
||||||
|
$stdout.puts message if options[:debug]
|
||||||
|
end
|
||||||
|
|
||||||
|
def warning(message)
|
||||||
|
$stdout.puts "WARNING: #{message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def info(message)
|
||||||
|
$stdout.puts message
|
||||||
|
end
|
||||||
|
|
||||||
|
def error(message)
|
||||||
|
$stderr.puts "ERROR: #{message}"
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
# The main function
|
||||||
|
def main
|
||||||
|
munge_options
|
||||||
|
|
||||||
|
if options[:console]
|
||||||
|
console
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:config]
|
||||||
|
show_config
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:list]
|
||||||
|
action_list
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:delete]
|
||||||
|
action_delete
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:recreate]
|
||||||
|
action_recreate
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:stop]
|
||||||
|
action_stop
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:start]
|
||||||
|
action_start
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
action_create
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if $0 == __FILE__
|
||||||
|
opsvm = KvmControl.new
|
||||||
|
opsvm.main
|
||||||
|
end
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
brctl delif <%= @mgmt_brg %> <%= @mgmt_nm %>
|
||||||
|
if [ $? == 0 ]; then
|
||||||
|
echo "Deleted <%= @mgmt_nm %>" > /var/log/nitrous-vlan.log
|
||||||
|
vconfig rem <%= @mgmt_nm %>
|
||||||
|
if [ $? == 0 ]; then
|
||||||
|
echo "Removed <%= @mgmt_nm %>" >> /var/log/nitrous-vlan.log
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
brctl delif <%= @stg_brg %> <%= @stg_nm %>
|
||||||
|
if [ $? == 0 ]; then
|
||||||
|
echo "Deleted <%= @stg_nm %>" >> /var/log/nitrous-vlan.log
|
||||||
|
vconfig rem <%= @stg_nm %>
|
||||||
|
if [ $? == 0 ]; then
|
||||||
|
echo "Removed <%= @stg_nm %>" >> /var/log/nitrous-vlan.log
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
brctl delif <%= @prv_brg %> <%= @prv_nm %>
|
||||||
|
if [ $? == 0 ]; then
|
||||||
|
echo "Deleted <%= @prv_nm %>" >> /var/log/nitrous-vlan.log
|
||||||
|
vconfig rem <%= @prv_nm %>
|
||||||
|
if [ $? == 0 ]; then
|
||||||
|
echo "Removed <%= @prv_nm %>" >> /var/log/nitrous-vlan.log
|
||||||
|
fi
|
||||||
|
fi
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
- id: nitrous
|
||||||
|
type: group
|
||||||
|
role: [nitrous]
|
||||||
|
tasks: [hiera, globals, tools, logging, netconfig, hosts, deploy_start]
|
||||||
|
parameters:
|
||||||
|
strategy:
|
||||||
|
type: parallel
|
||||||
|
|
||||||
|
- id: nitrous-deployment-puppet
|
||||||
|
type: puppet
|
||||||
|
role: [nitrous]
|
||||||
|
version: 2.0.0
|
||||||
|
required_for: [deploy_end]
|
||||||
|
requires: [deploy_start]
|
||||||
|
parameters:
|
||||||
|
puppet_manifest: puppet/manifests/nitrous.pp
|
||||||
|
puppet_modules: puppet/modules:/etc/puppet/modules
|
||||||
|
timeout: 720
|
||||||
|
|
||||||
|
- id: nitrous-post-deployment-sh
|
||||||
|
type: shell
|
||||||
|
version: 2.0.0
|
||||||
|
role: [nitrous]
|
||||||
|
cross-depends:
|
||||||
|
- name: post_deployment_start
|
||||||
|
cross-depended-by:
|
||||||
|
- name: post_deployment_end
|
||||||
|
requires: [post_deploy_start]
|
||||||
|
required_for: [post_deploy_end]
|
||||||
|
parameters:
|
||||||
|
cmd: |
|
||||||
|
echo -e "#!/bin/sh \n\n/bin/sleep 60 && /usr/bin/opsvm -a >>/var/log/nitrous.log" > /etc/ops_create.sh && chmod +x /etc/ops_create.sh;
|
||||||
|
retries: 0
|
||||||
|
interval: 10
|
||||||
|
timeout: 120
|
|
@ -0,0 +1,498 @@
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
attributes:
|
||||||
|
metadata:
|
||||||
|
# Settings group can be one of "general", "security", "compute", "network",
|
||||||
|
# "storage", "logging", "openstack_services" and "other".
|
||||||
|
group: 'other'
|
||||||
|
puppet_master_address:
|
||||||
|
value: 'localhost'
|
||||||
|
label: 'Puppet master address'
|
||||||
|
description: 'This will make entry of puppet master in Nitrous nodes.'
|
||||||
|
weight: 21
|
||||||
|
type: "text"
|
||||||
|
env_proxy:
|
||||||
|
value: 'undef'
|
||||||
|
label: 'Enviornment Proxy'
|
||||||
|
description: 'Use if the server requires a proxy. The default value is "undef".'
|
||||||
|
weight: 22
|
||||||
|
type: "text"
|
||||||
|
node_additional_config:
|
||||||
|
label: "Nitrous config"
|
||||||
|
type: "textarea"
|
||||||
|
validate: "yaml"
|
||||||
|
weight: 30
|
||||||
|
value: |
|
||||||
|
webvirt: xxx.xxx.xxx.xx
|
||||||
|
dhcp_helper: xxx.xxx.xxx.11
|
||||||
|
site_name: YOUR_SITENAME
|
||||||
|
ubuntu_repo: http://archive.ubuntu.com/ubuntu/
|
||||||
|
domain_name: YOUR_DOMAIN
|
||||||
|
network:
|
||||||
|
bonds:
|
||||||
|
- bond-mode: active-backup
|
||||||
|
members:
|
||||||
|
- em1
|
||||||
|
- em2
|
||||||
|
name: bond0
|
||||||
|
vlans:
|
||||||
|
- name: 100
|
||||||
|
native: true
|
||||||
|
- bond-mode: 802.3ad
|
||||||
|
members:
|
||||||
|
- p1p1
|
||||||
|
- p1p2
|
||||||
|
- p2p1
|
||||||
|
- p2p2
|
||||||
|
mtu: '9000'
|
||||||
|
name: bond1
|
||||||
|
vlans:
|
||||||
|
- name: 101 #Management
|
||||||
|
- name: 102 #Storage
|
||||||
|
- name: 103 #Private
|
||||||
|
dhcp-ranges:
|
||||||
|
- end: 10.1.0.252
|
||||||
|
gateway: 10.1.0.1
|
||||||
|
mask: 255.255.255.255
|
||||||
|
name: rack01
|
||||||
|
start: 10.1.0.12
|
||||||
|
dns-nameservers:
|
||||||
|
- 8.8.8.8
|
||||||
|
storage:
|
||||||
|
iscsi_reservation_enabled: false
|
||||||
|
lun_mapping:
|
||||||
|
#ADD YOUR STORAGE LUN INFORMATION
|
||||||
|
storage_backend: local
|
||||||
|
storage_blacklist_enabled: true
|
||||||
|
storage_subnets:
|
||||||
|
- xxx.xx.xxx.0/24
|
||||||
|
storage_type: idc
|
||||||
|
storage_vlan: 102
|
||||||
|
targets:
|
||||||
|
- xxx.xx.xxx.xx
|
||||||
|
nodes:
|
||||||
|
- host_profile: cp-hp2
|
||||||
|
ipmi_address: xxx.xxx.xxx.1
|
||||||
|
ipmi_password: YOUR_PASSWORD
|
||||||
|
ipmi_username: YOUR_USERNAME
|
||||||
|
mac_address: xx:xx:xx:xx:xx:xx
|
||||||
|
name: svr01r01a001
|
||||||
|
power_type: ipmi
|
||||||
|
pxe_address: 10.1.0.5
|
||||||
|
pxe_subnet: rack01
|
||||||
|
server_hardware: DellR900
|
||||||
|
storage:
|
||||||
|
initiator_name: iqn.xxxx-xx.abc.abcdefg:svr01r01a001-6383eecf
|
||||||
|
luns:
|
||||||
|
#ADD YOUR STORAGE LUN INFORMATION
|
||||||
|
type: seed
|
||||||
|
vlans:
|
||||||
|
- address:
|
||||||
|
address: 10.1.0.5
|
||||||
|
gateway: 10.1.0.1
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 100
|
||||||
|
- address:
|
||||||
|
address: 10.1.1.5
|
||||||
|
gateway: 10.1.1.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 101
|
||||||
|
- address:
|
||||||
|
address: 10.1.2.5
|
||||||
|
gateway: 10.1.2.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 102
|
||||||
|
- address:
|
||||||
|
address: 10.1.3.5
|
||||||
|
gateway: 10.1.3.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 103
|
||||||
|
- host_profile: cp-hp2
|
||||||
|
ipmi_address: xxx.xxx.xxx.2
|
||||||
|
ipmi_password: YOUR_PASSWORD
|
||||||
|
ipmi_username: YOUR_USERNAME
|
||||||
|
mac_address: xx:xx:xx:xx:xx:xx
|
||||||
|
name: svr01r01a002
|
||||||
|
power_type: ipmi
|
||||||
|
pxe_address: 10.1.0.6
|
||||||
|
pxe_subnet: rack01
|
||||||
|
server_hardware: DellR900
|
||||||
|
storage:
|
||||||
|
initiator_name: iqn.xxxx-xx.abc.abcdefg:svr01r01a002-0bfa33c0
|
||||||
|
luns:
|
||||||
|
#ADD YOUR STORAGE LUN INFORMATION
|
||||||
|
type: lcp
|
||||||
|
vlans:
|
||||||
|
- address:
|
||||||
|
address: 10.1.0.6
|
||||||
|
gateway: 10.1.0.1
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 100
|
||||||
|
- address:
|
||||||
|
address: 10.1.1.6
|
||||||
|
gateway: 10.1.1.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 101
|
||||||
|
- address:
|
||||||
|
address: 10.1.2.6
|
||||||
|
gateway: 10.1.2.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 102
|
||||||
|
- address:
|
||||||
|
address: 10.1.3.6
|
||||||
|
gateway: 10.1.3.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 103
|
||||||
|
- host_profile: cp-hp2
|
||||||
|
ipmi_address: xxx.xxx.xxx.3
|
||||||
|
ipmi_password: YOUR_PASSWORD
|
||||||
|
ipmi_username: YOUR_USERNAME
|
||||||
|
mac_address: xx:xx:xx:xx:xx:xx
|
||||||
|
name: svr01r01a003
|
||||||
|
power_type: ipmi
|
||||||
|
pxe_address: 10.1.0.7
|
||||||
|
pxe_subnet: rack01
|
||||||
|
server_hardware: DellR900
|
||||||
|
storage:
|
||||||
|
initiator_name: iqn.xxxx-xx.abc.abcdefg:svr01r01a003-cab3c6a4
|
||||||
|
luns:
|
||||||
|
#ADD YOUR STORAGE LUN INFORMATION
|
||||||
|
type: lcp
|
||||||
|
vlans:
|
||||||
|
- address:
|
||||||
|
address: 10.1.0.7
|
||||||
|
gateway: 10.1.0.1
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 100
|
||||||
|
- address:
|
||||||
|
address: 10.1.1.7
|
||||||
|
gateway: 10.1.1.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 101
|
||||||
|
- address:
|
||||||
|
address: 10.1.2.7
|
||||||
|
gateway: 10.1.2.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 102
|
||||||
|
- address:
|
||||||
|
address: 10.1.3.7
|
||||||
|
gateway: 10.1.3.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 103
|
||||||
|
- availability_zone: null
|
||||||
|
host_profile: nv-hp1
|
||||||
|
ipmi_address: xxx.xxx.xxx.4
|
||||||
|
ipmi_password: YOUR_PASSWORD
|
||||||
|
ipmi_username: YOUR_USERNAME
|
||||||
|
mac_address: xx:xx:xx:xx:xx:xx
|
||||||
|
name: svr01r01a004
|
||||||
|
power_type: ipmi
|
||||||
|
pxe_address: 10.1.0.8
|
||||||
|
pxe_subnet: rack04
|
||||||
|
server_hardware: DellR900
|
||||||
|
storage:
|
||||||
|
initiator_name: iqn.xxxx-xx.abc.abcdefg:svr01r01a004-98c8ace6
|
||||||
|
type: compute
|
||||||
|
vlans:
|
||||||
|
- address:
|
||||||
|
address: 10.1.0.8
|
||||||
|
gateway: 10.1.0.1
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 100
|
||||||
|
- address:
|
||||||
|
address: 10.1.1.8
|
||||||
|
gateway: 10.1.1.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 101
|
||||||
|
- address:
|
||||||
|
address: 10.1.2.8
|
||||||
|
gateway: 10.1.2.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 102
|
||||||
|
- address:
|
||||||
|
address: 10.1.3.8
|
||||||
|
gateway: 10.1.3.3
|
||||||
|
netmask: 255.255.255.255
|
||||||
|
name: 103
|
||||||
|
image_base_path: /var/lib/libvirt/images/
|
||||||
|
host_aggregates:
|
||||||
|
- host_profiles:
|
||||||
|
- nd-hp1
|
||||||
|
- nd-hp2
|
||||||
|
meta:
|
||||||
|
- nd: true
|
||||||
|
- cpu_allocation_ratio: 1.0
|
||||||
|
name: svr01-nd-ha01
|
||||||
|
- host_profiles:
|
||||||
|
- nv-hp1
|
||||||
|
meta:
|
||||||
|
- nv: true
|
||||||
|
- cpu_allocation_ratio: 1.0
|
||||||
|
name: svr01-nv-ha01
|
||||||
|
- host_profiles:
|
||||||
|
- gv-hp1
|
||||||
|
meta:
|
||||||
|
- gv: true
|
||||||
|
- c2: true
|
||||||
|
- cpu_allocation_ratio: 2.0
|
||||||
|
name: svr01-gv-ha01
|
||||||
|
selective_default_bridge:
|
||||||
|
label: "Select network bridge for KVM Host"
|
||||||
|
description: 'Default network bridge is "Linux", select as per your requirement.'
|
||||||
|
type: "radio"
|
||||||
|
weight: 40
|
||||||
|
value: "linuxbr"
|
||||||
|
values:
|
||||||
|
- data: "linuxbr"
|
||||||
|
label: "Linux Bridge"
|
||||||
|
- data: "ovsbr"
|
||||||
|
label: "OVS Bridge"
|
||||||
|
selective_opsvm_pool:
|
||||||
|
label: "Select storage pool for OpenStack Vms"
|
||||||
|
description: 'Default pool type for OpenStack vms is directory(dir), please select storage pool type as per your equirement.'
|
||||||
|
type: "radio"
|
||||||
|
weight: 50
|
||||||
|
value: "dir"
|
||||||
|
values:
|
||||||
|
- data: "dir"
|
||||||
|
label: "Directory"
|
||||||
|
- data: "mpath"
|
||||||
|
label: "Multipath"
|
||||||
|
ops_server_config:
|
||||||
|
label: "OpenStack Vms config"
|
||||||
|
type: "textarea"
|
||||||
|
validate: "yaml"
|
||||||
|
weight: 60
|
||||||
|
value: |
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: false
|
||||||
|
is_vm: true
|
||||||
|
kvm: svr01r01a002
|
||||||
|
mac_address: 52:54:00:e5:e4:06
|
||||||
|
name: mosc01
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_mosc01
|
||||||
|
ram: 32
|
||||||
|
server_type: controller
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:c2:dd:c5
|
||||||
|
name: mosc02
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_mosc02
|
||||||
|
ram: 32
|
||||||
|
server_type: controller
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a002
|
||||||
|
mac_address: 52:54:00:b3:dc:b2
|
||||||
|
name: mosc03
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_mosc03
|
||||||
|
ram: 32
|
||||||
|
server_type: controller
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: false
|
||||||
|
is_vm: true
|
||||||
|
kvm: svr01r01a002
|
||||||
|
mac_address: 52:54:00:3b:e5:fb
|
||||||
|
name: dbmq01
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_dbmq01
|
||||||
|
ram: 32
|
||||||
|
server_type: dbmq
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:92:35:52
|
||||||
|
name: dbmq02
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_dbmq02
|
||||||
|
ram: 32
|
||||||
|
server_type: dbmq
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:aa:53:25
|
||||||
|
name: dbmq03
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_dbmq03
|
||||||
|
ram: 32
|
||||||
|
server_type: dbmq
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a002
|
||||||
|
mac_address: 52:54:00:7d:8c:ad
|
||||||
|
name: mong01
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_mong01
|
||||||
|
ram: 32
|
||||||
|
server_type: mongo_db
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:21:5d:b3
|
||||||
|
name: mong02
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_mong02
|
||||||
|
ram: 32
|
||||||
|
server_type: mongo_db
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:00:86:3e
|
||||||
|
name: mong03
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_mong03
|
||||||
|
ram: 32
|
||||||
|
server_type: mongo_db
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: false
|
||||||
|
is_vm: true
|
||||||
|
kvm: svr01r01a002
|
||||||
|
mac_address: 52:54:00:f0:2b:5d
|
||||||
|
name: hapr01
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_hapr01
|
||||||
|
ram: 32
|
||||||
|
server_type: haproxy
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:9a:d8:61
|
||||||
|
name: hapr02
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_hapr02
|
||||||
|
ram: 32
|
||||||
|
server_type: haproxy
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a002
|
||||||
|
mac_address: 52:54:00:5c:b3:eb
|
||||||
|
name: hapr03
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_hapr03
|
||||||
|
ram: 32
|
||||||
|
server_type: haproxy
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: false
|
||||||
|
is_vm: true
|
||||||
|
kvm: svr01r01a002
|
||||||
|
mac_address: 52:54:00:07:f1:bd
|
||||||
|
name: kshz01
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_kshz01
|
||||||
|
ram: 32
|
||||||
|
server_type: identity
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:75:24:24
|
||||||
|
name: kshz02
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_kshz02
|
||||||
|
ram: 32
|
||||||
|
server_type: identity
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 8
|
||||||
|
app_disk: 120
|
||||||
|
log_disk: 15
|
||||||
|
os_disk: 80
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: svr01r01a003
|
||||||
|
mac_address: 52:54:00:5d:08:78
|
||||||
|
name: kshz03
|
||||||
|
network_profile: vm_ops-profile
|
||||||
|
os_volume_name: mpath_kshz03
|
||||||
|
ram: 32
|
||||||
|
server_type: identity
|
||||||
|
- app_volume_name: null
|
||||||
|
cpu: 0
|
||||||
|
ignore: true
|
||||||
|
is_vm: false
|
||||||
|
kvm: xx:xx:xx:xx:xx:xx
|
||||||
|
name: svr01r01a004
|
||||||
|
network_profile: dellr900_nv-hp1
|
||||||
|
os_volume_name: null
|
||||||
|
ram: 0
|
||||||
|
server_type: compute
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
name: nitrous
|
||||||
|
title: Nitrous plugin for Bare Metal provisioning.
|
||||||
|
version: '1.0.0'
|
||||||
|
description: Nitrous plugin will install Base OS, multipath options, create VMs and their network settings for Fuel provisioning and deployment.
|
||||||
|
fuel_version: ['9.0']
|
||||||
|
licenses: ['Apache License Version 2.0']
|
||||||
|
authors: ['Dinesh Yadav (dy270k@att.com), AT&T Inc.']
|
||||||
|
homepage: 'https://github.com/openstack/fuel-plugin-nitrous'
|
||||||
|
groups: []
|
||||||
|
is_hotpluggable: false
|
||||||
|
|
||||||
|
releases:
|
||||||
|
- os: ubuntu
|
||||||
|
version: kilo-9.0
|
||||||
|
mode: ['ha', 'multinode']
|
||||||
|
deployment_scripts_path: deployment_scripts/
|
||||||
|
repository_path: repositories/ubuntu
|
||||||
|
- os: ubuntu
|
||||||
|
version: liberty-9.0
|
||||||
|
mode: ['ha', 'multinode']
|
||||||
|
deployment_scripts_path: deployment_scripts/
|
||||||
|
repository_path: repositories/ubuntu
|
||||||
|
- os: ubuntu
|
||||||
|
version: mitaka-9.0
|
||||||
|
mode: ['ha', 'multinode']
|
||||||
|
deployment_scripts_path: deployment_scripts/
|
||||||
|
repository_path: repositories/ubuntu
|
||||||
|
|
||||||
|
package_version: '4.0.0'
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
- id: "example_net_role"
|
||||||
|
# Role mapping to network
|
||||||
|
default_mapping: "public"
|
||||||
|
properties:
|
||||||
|
# Should be true if network role requires subnet being set
|
||||||
|
subnet: true
|
||||||
|
# Should be true if network role requires gateway being set
|
||||||
|
gateway: false
|
||||||
|
# List of VIPs to be allocated
|
||||||
|
vip:
|
||||||
|
# Unique VIP name
|
||||||
|
- name: "vip_name"
|
||||||
|
# Optional linux namespace for VIP
|
||||||
|
namespace: "haproxy"
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
nitrous:
|
||||||
|
name: Nitrous
|
||||||
|
description: Base OS installation on bare metal with KVM/QEMU/libvirt hypervisor and creates VMs for Fuel provisioning and deployment.
|
||||||
|
has_primary: false
|
||||||
|
public_ip_required: false
|
||||||
|
weight: 100
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
DEBUG=true
|
||||||
|
REL_NAME='Ubuntu 14.04'
|
||||||
|
|
||||||
|
FUEL='/usr/bin/fuel'
|
||||||
|
REL=`$FUEL rel | grep -i "${REL_NAME}.* available " | awk '{print $1}'`
|
||||||
|
FUEL_REL=`$FUEL rel | grep -i "${REL_NAME}.* available " | awk '{print $NF}'`
|
||||||
|
|
||||||
|
function debug {
|
||||||
|
if $DEBUG; then
|
||||||
|
echo $@
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_min_controller_count {
|
||||||
|
count=$1
|
||||||
|
workdir=$(mktemp -d /tmp/modifyenv.XXXX)
|
||||||
|
local os_roles=(ceph-osd cinder compute controller cinder-block-device ironic mongo)
|
||||||
|
for role in ${os_roles[@]}; do
|
||||||
|
$FUEL role --rel $REL --role $role --file $workdir/${role}.yaml
|
||||||
|
sed -i "s/ min: ./ min: ${count}/" $workdir/${role}.yaml
|
||||||
|
$FUEL role --rel $REL --update --file $workdir/${role}.yaml
|
||||||
|
done
|
||||||
|
rm -rf $workdir
|
||||||
|
}
|
||||||
|
|
||||||
|
set_min_controller_count 0
|
||||||
|
$FUEL rel --sync-deployment-tasks --dir /etc/puppet/$FUEL_REL
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License
|
||||||
|
|
||||||
|
# Add here any the actions which are required before plugin build
|
||||||
|
# like packages building, packages downloading from mirrors and so on.
|
||||||
|
# The script should return 0 if there were no errors.
|
||||||
|
|
||||||
|
set -eux
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Copyright (c) 2016 AT&T Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# WARNING: `tasks.yaml` will be deprecated in further releases.
|
||||||
|
# Please, use `deployment_tasks.yaml` to describe tasks instead.
|
||||||
|
|
||||||
|
# This tasks will be applied on controller nodes,
|
||||||
|
# here you can also specify several roles, for example
|
||||||
|
# ['cinder', 'compute'] will be applied only on
|
||||||
|
# cinder and compute nodes
|
||||||
|
- role: ['controller']
|
||||||
|
stage: post_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: bash deploy.sh
|
||||||
|
timeout: 42
|
||||||
|
# Task is applied for all roles
|
||||||
|
- role: '*'
|
||||||
|
stage: pre_deployment
|
||||||
|
type: shell
|
||||||
|
parameters:
|
||||||
|
cmd: echo all > /tmp/plugin.all
|
||||||
|
timeout: 42
|
||||||
|
# "reboot" task reboots the nodes and waits until they get back online
|
||||||
|
# - role: '*'
|
||||||
|
# stage: pre_deployment
|
||||||
|
# type: reboot
|
||||||
|
# parameters:
|
||||||
|
# timeout: 600
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Copyright 2016 AT&T, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
volumes_roles_mapping:
|
||||||
|
nitrous:
|
||||||
|
- {allocate_size: "min", id: "os"}
|
||||||
|
- {allocate_size: "min", id: "logs"}
|
||||||
|
- {allocate_size: "all", id: "nitrous"}
|
||||||
|
volumes:
|
||||||
|
- id: "nitrous"
|
||||||
|
type: "vg"
|
||||||
|
min_size:
|
||||||
|
generator: "calc_gb_to_mb"
|
||||||
|
generator_args: [10]
|
||||||
|
label: "Nitrous Vol"
|
||||||
|
volumes:
|
||||||
|
- mount: "/opt"
|
||||||
|
type: "lv"
|
||||||
|
name: "nitrous"
|
||||||
|
size:
|
||||||
|
generator: "calc_total_vg"
|
||||||
|
generator_args: ["nitrous"]
|
||||||
|
file_system: "ext4"
|
Loading…
Reference in New Issue