diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..849b4c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.build +*.swp +*.rpm diff --git a/README.md b/README.md index af5fdd6..6735c61 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Requirements | Requirement | Version/Comment | |--------------------------------|-----------------| -| Mirantis OpenStack compatility | 6.1 or higher | +| Mirantis OpenStack compatility | 8.0 or higher | | A running SwiftStack Swift cluster | all versions, the `Keystone Auth` and `'Keystone Auth Token Support` middlewares must be enable | @@ -33,8 +33,8 @@ $ sudo apt-get install python-dev python-pip python-virtualenv $ virtualenv fuel # Clone fule-plugin-builder and SwiftStack Swift Fuel plugin -$ git clone https://github.com/stackforge/fuel-plugins -$ git clone https://github.com/stackforge/fuel-plugin-swiftstack +$ git clone https://github.com/openstack/fuel-plugins +$ git clone https://github.com/openstack/fuel-plugin-swiftstack $ source fuel/bin/activate (fuel) $ cd fuel-plugins/fuel_plugin_builder/ diff --git a/deployment_scripts/delete_entrypoint.rb b/deployment_scripts/delete_entrypoint.rb deleted file mode 100755 index d5b39f1..0000000 --- a/deployment_scripts/delete_entrypoint.rb +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env ruby -require 'hiera' - -ENV['LANG'] = 'C' - -hiera = Hiera.new(:config => '/etc/hiera.yaml') -swift = hiera.lookup 'swift', {} , {} -auth_addr = hiera.lookup 'management_vip', nil, {} - -ENV['OS_TENANT_NAME']="services" -ENV['OS_USERNAME']="swift" -ENV['OS_PASSWORD']="#{swift['user_password']}" -ENV['OS_AUTH_URL']="http://#{auth_addr}:5000/v2.0" -ENV['OS_ENDPOINT_TYPE'] = "internalURL" - -def service_list - stdout = `keystone service-list` - return_code = $?.exitstatus - names = [] - uuids = [] - types = [] - stdout.split("\n").each do |line| - fields = line.split('|').map { |f| f.chomp.strip } - next if fields[1] == 'id' - next unless fields[2] - names << fields[2] - uuids << fields[1] - types << fields[3] - end - {:names => names, :uuids => uuids, :types => types, :exit_code => return_code} -end - -def endpoint_list - stdout = `keystone endpoint-list` - return_code = $?.exitstatus - service_ids = [] - uuids = [] - stdout.split("\n").each do |line| - fields = line.split('|').map { |f| f.chomp.strip } - next if fields[1] == 'id' - next unless fields[2] - service_ids << fields[6] - uuids << fields[1] - end - {:service_ids => service_ids, :uuids => uuids, :exit_code => return_code} -end - - -def delete_endpoint(service_name) - list_of_services = service_list - list_of_endpoints = endpoint_list - types = Hash[list_of_services[:types].map.with_index.to_a] - service_id = list_of_services[:uuids][types[service_name]] - endpoint_service_ids = Hash[list_of_endpoints[:service_ids].map.with_index.to_a] - endpoint_uuid = list_of_endpoints[:uuids][endpoint_service_ids[service_id]] - puts "Remove endpoint ('#{endpoint_uuid}') in '#{service_name}' " - "(service_id: '#{service_id}'." - stdout = `keystone endpoint-delete '#{endpoint_uuid}'` -end - -######################## - - -delete_endpoint("object-store") -delete_endpoint("s3") - - diff --git a/deployment_scripts/puppet/manifests/sscluster.pp b/deployment_scripts/puppet/manifests/sscluster.pp index 8e44126..a74d4df 100755 --- a/deployment_scripts/puppet/manifests/sscluster.pp +++ b/deployment_scripts/puppet/manifests/sscluster.pp @@ -1,24 +1,39 @@ -$fuel_settings = parseyaml(file('/etc/astute.yaml')) +notice('PLUGIN: SwiftStack Swift cluster integration/sscluster.pp') -if $fuel_settings['swiftstack']['metadata']['enabled'] { +$swiftstack = hiera_hash('swiftstack', {}) +$swift = hiera_hash('swift', {}) +$glance = hiera_hash('glance', {}) + +if $swiftstack['metadata']['enabled'] { notice("Enable SwiftStack Swift cluster ingegtation in $deployment_mode") - $role = $fuel_settings['role'] - $deployment_mode = $fuel_settings['deployment_mode'] - $keystone_vip = $fuel_settings['management_vip'] + $role = hiera('roles') + $deployment_mode = hiera('deployment_mode') + $keystone_vip = pick($swift['management_vip'], hiera('management_vip')) - $swift_api_address = $fuel_settings['swiftstack']['swift_api_address'] - $swift_user = 'swift' - $swift_password = $fuel_settings['swift']['user_password'] - $glance_user = 'glance' - $glance_password = $fuel_settings['glance']['user_password'] - $default_tenant = $fuel_settings['workloads_collector']['tenant'] + + $swift_api_address = $swiftstack['swift_api_address'] + $swift_api_fqdn = $swiftstack['swift_api_fqdn'] + $swift_user = pick($swift['user'], 'swift') + $swift_password = $swift['user_password'] + $glance_user = pick($glance['user'],'glance') + $glance_password = $glance['user_password'] + $default_tenant = pick($swift['tenant'], 'services') + + case $swift_api_fqdn { + '': { + $api_address = $swift_api_address + } + default: { + $api_address = $swift_api_fqdn + } + } class {'sscluster': deployment_mode => $deployment_mode, keystone_vip => $keystone_vip, - api_address => $swift_api_address, + api_address => $api_address, swift_user => $swift_user, swift_password => $swift_password, glance_user => $glance_user, diff --git a/deployment_scripts/puppet/modules/sscluster/manifests/init.pp b/deployment_scripts/puppet/modules/sscluster/manifests/init.pp index fcdc8b4..bad869e 100755 --- a/deployment_scripts/puppet/modules/sscluster/manifests/init.pp +++ b/deployment_scripts/puppet/modules/sscluster/manifests/init.pp @@ -3,178 +3,85 @@ class sscluster ( $deployment_mode, $keystone_vip, $api_address, - $swift_user = 'swift', - $swift_password = 'PASSWORD', - $glance_user = 'glance', - $glance_password = 'PASSWORD', - $tenant = 'services', + $swift_user, + $swift_password, + $glance_user, + $glance_password, + $tenant, $role = 'controller', ) { - case $::osfamily { - 'Debian':{ - $glance_api = 'glance-api' - $swift_proxy = 'swift-proxy' - $swift_object = 'swift-object' - $swift_object_auditor = 'swift-object-auditor' - $swift_object_replicator = 'swift-object-replicator' - $swift_container = 'swift-container' - $swift_container_auditor = 'swift-container-auditor' - $swift_container_replicator = 'swift-container-replicator' - $swift_container_updater = 'swift-container-updater' - $swift_container_sync = 'swift-container-sync' - $swift_account = 'swift-account' - $swift_account_auditor = 'swift-account-auditor' - $swift_account_replicator = 'swift-account-replicator' - $swift_account_reaper = 'swift-account-reaper' - } - 'RedHat':{ - $glance_api = 'openstack-glance-api' - $swift_proxy = 'openstack-swift-proxy' - $swift_object = 'openstack-swift-object' - $swift_object_auditor = 'openstack-swift-object-auditor' - $swift_object_replicator = 'openstack-swift-object-replicator' - $swift_container = 'openstack-swift-container' - $swift_container_auditor = 'openstack-swift-container-auditor' - $swift_container_replicator = 'openstack-swift-container-replicator' - $swift_container_updater = 'openstack-swift-container-updater' - $swift_container_sync = 'openstack-swift-container-sync' - $swift_account = 'openstack-swift-account' - $swift_account_auditor = 'openstack-swift-account-auditor' - $swift_account_replicator = 'openstack-swift-account-replicator' - $swift_account_reaper = 'openstack-swift-account-reaper' + $swiftstack = hiera_hash('swiftstack', {}) + $swift_hash = hiera_hash('swift', {}) + + $region = pick($swift_hash['region'], hiera('region', 'RegionOne')) + $ssl_hash = hiera_hash('use_ssl', {}) + + $swift_tls_enabled = pick($swiftstack['swift_tls_enabled']) + case $swift_tls_enabled { + true: { + $ssl_enabled = 'https' + $swift_port = 443 } default: { - fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian") + $ssl_enabled = 'http' + $swift_port = 80 + } + } + + $public_protocol = get_ssl_property($ssl_hash, {}, 'swift', 'public', 'protocol', $ssl_enabled) + $admin_protocol = get_ssl_property($ssl_hash, {}, 'swift', 'admin', 'protocol', $ssl_enabled) + $internal_protocol = get_ssl_property($ssl_hash, {}, 'swift', 'internal', 'protocol', $ssl_enabled) + + $internal_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'protocol', 'http') + $internal_auth_address = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'hostname', [hiera('service_endpoint', ''), $keystone_vip]) + $auth_uri = "${internal_auth_protocol}://${internal_auth_address}:5000/v2.0" + + $swift_as_glance_backend = $swiftstack['swift_as_glance_backend'] + if $swift_as_glance_backend { + notice("Switch Glance backend to Swift Cluster: ${api_address}") + class {'glance::backend::swift': + swift_store_user => "$tenant:$glance_user", + swift_store_key => $glance_password, + swift_store_region => $region, + swift_store_auth_address => $auth_uri, + swift_store_create_container_on_put => true, + } + + glance_api_config { + 'glance_store/stores': value => 'glance.store.swift.Store'; } } - notice("Stop Glance API Service") - exec { 'Stop glance-api': - command => "service $glance_api stop", - path => ['/usr/bin', '/sbin', '/bin'], - } - - notice("Switch Glance backend to Swift Cluster: ${api_address}") - class {'glance::backend::swift': - swift_store_user => "$tenant:$glance_user", - swift_store_key => $glance_password, - swift_store_auth_address => "http://$keystone_vip:5000/v2.0", - swift_store_create_container_on_put => true, - } - - glance_api_config { - 'glance_store/stores': value => 'glance.store.swift.Store'; - } - - if $role == 'primary-controller' { + if 'primary-controller' in $role { notice("Update a keystone user for Swift Cluster: ${tenant}:${swift_user}") class {'swift::keystone::auth': - auth_name => $swift_user, - password => $swift_password, - tenant => $tenant, - port => '80', - public_protocol => 'http', - public_address => $api_address, - admin_protocol => 'http', - admin_address => $api_address, - endpoint_prefix => 'KEY', + auth_name => $swift_user, + password => $swift_password, + tenant => $tenant, + region => $region, + port => $swift_port, + public_protocol => $public_protocol, + public_address => $api_address, + admin_protocol => $admin_protocol, + admin_address => $api_address, + internal_protocol => $internal_protocol, + internal_address => $api_address, + endpoint_prefix => 'KEY', } Class['swift::keystone::auth'] ~> Service['glance-api'] } notice("Start Glance API Service") service { 'glance-api': - name => $glance_api, ensure => "running", + hasrestart => true, hasstatus => true, } - Exec['Stop glance-api'] -> Class['glance::backend::swift'] ~> Service['glance-api'] - Exec['Stop glance-api'] -> Glance_api_config<||> ~> Service['glance-api'] - - if $deployment_mode == 'ha_compact' { - service { 'swift-proxy': - name => $swift_proxy, - ensure => "stopped", - enable => false, - hasstatus => true, - } - - service { 'swift-object': - name => $swift_object, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-object-auditor': - name => $swift_object_auditor, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-object-replicator': - name => $swift_object_replicator, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-container': - name => $swift_container, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-container-auditor': - name => $swift_container_auditor, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-container-replicator': - name => $swift_container_replicator, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-container-updater': - name => $swift_container_updater, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-container-sync': - name => $swift_container_sync, - ensure => "stopped", - enable => false, - hasstatus => true, - } - - - service { 'swift-account': - name => $swift_account, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-account-auditor': - name => $swift_account_auditor, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-account-replicator': - name => $swift_account_replicator, - ensure => "stopped", - enable => false, - hasstatus => true, - } - service { 'swift-account-reaper': - name => $swift_account_reaper, - ensure => "stopped", - enable => false, - hasstatus => true, - } + if $swift_as_glance_backend { + Class['glance::backend::swift'] ~> Service['glance-api'] + Glance_api_config<||> ~> Service['glance-api'] } } diff --git a/deployment_scripts/upload_cirros.rb b/deployment_scripts/upload_cirros.rb deleted file mode 100755 index ba3e67d..0000000 --- a/deployment_scripts/upload_cirros.rb +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env ruby -require 'hiera' - -ENV['LANG'] = 'C' - -hiera = Hiera.new(:config => '/etc/hiera.yaml') -test_vm_images = hiera.lookup 'test_vm_image', {}, {} -glanced = hiera.lookup 'glance', {} , {} -auth_addr = hiera.lookup 'internal_address', nil, {} - -ENV['OS_TENANT_NAME']="services" -ENV['OS_USERNAME']="glance" -ENV['OS_PASSWORD']="#{glanced['user_password']}" -ENV['OS_AUTH_URL']="http://#{auth_addr}:5000/v2.0" -ENV['OS_ENDPOINT_TYPE'] = "internalURL" - -raise 'Not test_vm_image data!' unless [Array, Hash].include?(test_vm_images.class) && test_vm_images.any? - -test_vm_images = [test_vm_images] unless test_vm_images.is_a? Array - -test_vm_images.each do |image| - %w( - disk_format - img_path - img_name - os_name - public - container_format - min_ram - ).each do |f| - raise "Data field '#{f}' is missing!" unless image[f] - end -end - -def image_list - stdout = `glance image-list` - return_code = $?.exitstatus - images = [] - uuid = [] - stdout.split("\n").each do |line| - fields = line.split('|').map { |f| f.chomp.strip } - next if fields[1] == 'ID' - next unless fields[2] - images << fields[2] - uuid << fields[1] - end - {:images => images, :uuid => uuid, :exit_code => return_code} -end - -def image_create(image_hash) - command = <<-EOF -/usr/bin/glance image-create \ ---name '#{image_hash['img_name']}' \ ---is-public '#{image_hash['public']}' \ ---container-format='#{image_hash['container_format']}' \ ---disk-format='#{image_hash['disk_format']}' \ ---min-ram='#{image_hash['min_ram']}' \ -#{image_hash['glance_properties']} \ ---file '#{image_hash['img_path']}' -EOF - puts command - stdout = `#{command}` - return_code = $?.exitstatus - [ stdout, return_code ] -end - -# check if Glance is online -# waited until the glance is started because when vCenter used as a glance -# backend launch may takes up to 1 minute. -def wait_for_glance - 5.times.each do |retries| - sleep 10 if retries > 0 - return if image_list[:exit_code] == 0 - end - raise 'Could not get a list of glance images!' -end - -# upload image to Glance -# if it have not been already uploaded -def upload_image(image) - list_of_images = image_list - if list_of_images[:images].include?(image['img_name']) && list_of_images[:exit_code] == 0 - # Check the image is stored in swift - stdout = `swift post glance` - stdout = `swift list glance | grep #{list_of_images[:uuid][0]}` - return_code = $?.exitstatus - if return_code == 0 - puts "Image '#{image['img_name']}' is already present!" - return 0 - else - stdout = `glance image-delete #{list_of_images[:uuid][0]}` - return_code = $?.exitstatus - [ stdout, return_code ] - end - end - - stdout, return_code = image_create(image) - if return_code == 0 - puts "Image '#{image['img_name']}' was uploaded from '#{image['img_path']}'" - else - puts "Image '#{image['img_name']}' upload from '#{image['img_path']}' have FAILED!" - end - puts stdout - return return_code -end - -######################## - -wait_for_glance -errors = 0 - -test_vm_images.each do |image| - errors += upload_image(image) -end - -exit 1 unless errors == 0 - diff --git a/deployment_tasks.yaml b/deployment_tasks.yaml new file mode 100644 index 0000000..f0c0478 --- /dev/null +++ b/deployment_tasks.yaml @@ -0,0 +1,34 @@ +- id: swift + type: skipped + +- id: primary-swift + type: skipped + +- id: openstack-haproxy-swift + type: skipped + +- id: swift-rebalance-cron + type: skipped + +- id: swift-keystone + type: skipped + +- id: swift_zone + type: skipped + +- id: upload_cirros + type: shell + role: ['primary-controller'] + condition: "settings:swiftstack.upload_cirros_test.value == true" + +- id: swiftstack_configure_swift_endpoint + role: ['primary-controller','controller'] + required_for: [post_deployment_end] + requires: [post_deployment_start] + type: puppet + parameters: + puppet_manifest: puppet/manifests/sscluster.pp + puppet_modules: "puppet/modules:/etc/puppet/modules/" + timeout: 420 + + diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..edfccd7 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,223 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) + $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " epub3 to make an epub3" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SwiftStackPluginforFuel80.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SwiftStackPluginforFuel80.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/SwiftStackPluginforFuel80" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SwiftStackPluginforFuel80" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: epub3 +epub3: + $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 + @echo + @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000..5161b4f --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# +# SwiftStack Plugin for Fuel documentation build configuration file, created by +# sphinx-quickstart on Sun Apr 3 14:11:54 2016. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import datetime + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'SwiftStack Plugin for Fuel 8.0' +copyright = u'2015–%s, SwiftStack' % datetime.date.today().year +author = u'Charles Hsu' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'0.2.0' +# The full version, including alpha/beta/rc tags. +release = u'0.2-0.2.0-1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +#html_theme = 'flask' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. +# " v documentation" by default. +html_title = 'SwiftStack Plugin for Fuel (v0.2.0)' + +# A shorter title for the navigation bar. Default is the same as html_title. +html_short_title = 'SwiftStack Plugin for Fuel' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (relative to this directory) to use as a favicon of +# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not None, a 'Last updated on:' timestamp is inserted at every page +# bottom, using the given strftime format. +# The empty string is equivalent to '%b %d, %Y'. +#html_last_updated_fmt = None + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} +html_sidebars = { + '**': ['localtoc.html', 'relations.html', + 'sourcelink.html', 'searchbox.html'] +} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# 'ja' uses this config value. +# 'zh' user can custom change `jieba` dictionary path. +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'SwiftStackPluginforFueldoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'SwiftStackPluginforFuel.tex', u'SwiftStack Plugin for Fuel Documentation', + u'SwiftStack Inc.', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'swiftstackpluginforfuel', u'SwiftStack Plugin for Fuel Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# make latex stop printing blank pages between sections +# http://stackoverflow.com/questions/5422997/sphinx-docs-remove-blank-pages-from-generated-pdfs +latex_elements = { 'classoptions': ',openany,oneside', 'babel' : '\\usepackage[english]{babel}' } + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'SwiftStackPluginforFuel', u'SwiftStack Plugin for Fuel Documentation', + author, 'SwiftStackPluginforFuel', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/doc/images/1_add_nodes.png b/doc/images/1_add_nodes.png new file mode 100644 index 0000000..26b9645 Binary files /dev/null and b/doc/images/1_add_nodes.png differ diff --git a/doc/images/2_enable_plugin.png b/doc/images/2_enable_plugin.png new file mode 100644 index 0000000..aa22a9d Binary files /dev/null and b/doc/images/2_enable_plugin.png differ diff --git a/doc/images/3-1_proxy_outwarding-facing.png b/doc/images/3-1_proxy_outwarding-facing.png new file mode 100644 index 0000000..3e20efa Binary files /dev/null and b/doc/images/3-1_proxy_outwarding-facing.png differ diff --git a/doc/images/3-2_swift_api_ip.png b/doc/images/3-2_swift_api_ip.png new file mode 100644 index 0000000..7471736 Binary files /dev/null and b/doc/images/3-2_swift_api_ip.png differ diff --git a/doc/images/3_config_network.png b/doc/images/3_config_network.png new file mode 100644 index 0000000..5ef33ce Binary files /dev/null and b/doc/images/3_config_network.png differ diff --git a/doc/images/4_config_interfaces.png b/doc/images/4_config_interfaces.png new file mode 100644 index 0000000..5ef8a52 Binary files /dev/null and b/doc/images/4_config_interfaces.png differ diff --git a/doc/images/5_config_key1.png b/doc/images/5_config_key1.png new file mode 100644 index 0000000..b4b7c93 Binary files /dev/null and b/doc/images/5_config_key1.png differ diff --git a/doc/images/6_config_key2.png b/doc/images/6_config_key2.png new file mode 100644 index 0000000..6b5bcf8 Binary files /dev/null and b/doc/images/6_config_key2.png differ diff --git a/doc/images/7_deploy_verify1.png b/doc/images/7_deploy_verify1.png new file mode 100644 index 0000000..32e24ae Binary files /dev/null and b/doc/images/7_deploy_verify1.png differ diff --git a/doc/images/8_deploy_verify2.png b/doc/images/8_deploy_verify2.png new file mode 100644 index 0000000..6429ec9 Binary files /dev/null and b/doc/images/8_deploy_verify2.png differ diff --git a/doc/images/use_on_prem.png b/doc/images/use_on_prem.png new file mode 100644 index 0000000..0fa4633 Binary files /dev/null and b/doc/images/use_on_prem.png differ diff --git a/doc/images/use_platform.png b/doc/images/use_platform.png new file mode 100644 index 0000000..baa6219 Binary files /dev/null and b/doc/images/use_platform.png differ diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..34b98b2 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,11 @@ + +Guide to the Swiftstack plugin for Fuel ver. 0.2-0.2.0-1 +======================================================== + +.. toctree:: + :maxdepth: 2 + + overview + install + user + troubleshoot diff --git a/doc/install.rst b/doc/install.rst new file mode 100644 index 0000000..10539ec --- /dev/null +++ b/doc/install.rst @@ -0,0 +1,42 @@ +Installation Guide +================== + + + +Prepare Fuel Environment +------------------------ +#. Prepare a Fuel Master node to install `MOS 8.0`_ + +#. Download plugin from `Fuel Plugins Catalog`_ + +.. _MOS 8.0: http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-install-guide/install_install_fuel.html +.. _Fuel Plugins Catalog: https://www.mirantis.com/validated-solution-integrations/fuel-plugins/ + + +Install Plugin +-------------- + +#. Copy plugin to the Fuel Master node + + .. code-block:: bash + + $ scp swiftstack-0.2-0.2.0-1.noarch.rpm root@:/tmp/ + +#. Install SwiftStack plugin + + .. code-block:: bash + + [root@fuel ~]$ fuel plugins --install swiftstack-0.2-0.2.0-1.noarch.rpm + +#. List all Fuel plugins and make sure it’s running + + .. code-block:: bash + + [root@fuel ~]$ fuel plugins + + id | name | version | package_version + ---|------------|---------|---------------- + 2 | swiftstack | 0.2.0 | 3.0.0 + + + diff --git a/doc/overview.rst b/doc/overview.rst new file mode 100644 index 0000000..fca1022 --- /dev/null +++ b/doc/overview.rst @@ -0,0 +1,24 @@ +SwiftStack Fuel Plugin +====================== + +Allow Mirantis OpenStack environment able to use a running Swift cluster managed by SwiftStack Controller. SwiftStack fuel plugin disables the default Swift cluster that deployed on the Controller or Primary-Controller nodes, and then reconfigures Swift API endpoints, Keystone and Glance settings to the running SwiftStack Swift cluster. + +Requirements +----------- + ++-----------------------------------+---------------------------------------------+ +|Requirement | Version | ++===================================+=============================================+ +|Mirantis OpenStack compatibility | 8.0 | ++-----------------------------------+---------------------------------------------+ +|A running SwiftStack Swift cluster | All versions | +| | | +| | Please enable **Keystone Auth** and | +| | **Keystone Auth Token Support** middlewares | ++-----------------------------------+---------------------------------------------+ + +Limitations +----------- + +The plugin only supports a running SwiftStack Swift, able to reach from the OpenStack environment. +Make sure you have correct network configuration for the Swift cluster and OpenStack environment before you enable this plugin. diff --git a/doc/troubleshoot.rst b/doc/troubleshoot.rst new file mode 100644 index 0000000..a8b0325 --- /dev/null +++ b/doc/troubleshoot.rst @@ -0,0 +1,95 @@ +Troubleshooting Guide +===================== + + +Source file (~/openrc) +---------------------- +If you try run swift cli in controller nodes, please check OS_AUTH_URL is correct. +If the value is ``http://:5000/``, please correct it to ``http://:5000/v2.0`` as following. + + .. code-block:: python + + root@node-17:~# cat openrc + #!/bin/sh + ... + export OS_AUTH_URL='http://:5000/v2.0' + ... + + + +External Load Balancer +---------------------- + +If there is a external load balancer in front of you Swift cluster, and you confgiure the swift cluster with it. +Please fill the external LB IP for ``Swift API IP Address`` in :ref:`plugin page `. + + +Swift endpoint in Keystone DB +----------------------------- + +Before you upload any VM image to Glance, we suggest to check the Swift endpoint in Keystone DB first. Make sure the Swift endpoint is correct. + +For swift endpoint, please make sure the endpoints (``publicurl`` and ``internalurl``) look like ``http://:80/v1/KEY_%(tenant_id)s``. + + .. code-block:: python + + $ openstack endpoint list | grep swift + + +401 Unauthorized issue from clients +----------------------------------- + +If any client runs into ``401 Unauthorized`` issue, please use Swift CLI verify it again and make sure the settings of middlewares in Swift cluster are correct. + +For example, if you get a error with ``swift stat``. + + .. code-block:: python + + $ swift stat + Account HEAD failed: http://10.200.5.5:80/v1/KEY_32f0b6cd7299412e9f7966b324 + fb6aea + 401 Unauthorized + +Try to use ``--debug`` to get more details. + + .. code-block:: python + + $ swift --debug stat -v + .... + INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection + (1): 10.200.5.5 + DEBUG:requests.packages.urllib3.connectionpool:"HEAD /v1/KEY_32f0b6cd72994 + 12e9f7966b324fb6aea HTTP/1.1" 401 0 + INFO:swiftclient:REQ: curl -i http://10.200.5.5:80/v1/KEY_32f0b6cd7299412e + 9f7966b324fb6aea -I -H "X-Auth-Token: gAAAAABXMe1s87mzqZK1Ee8hyJQ86fv9 + NDcSChKCLk-PTQfa353J5t3N4EL-OCHbZuqt6hRFBJehUozgF4FNNd5Q_rfXBejo817U_F + f6mAy6-hP2l0KWbxON1mfZL_UCfjjWclrSD2-bK38JvTfrqWdM99cqfdMBDZS-wqHn1dZz + O0g2r-Kzxcc" + INFO:swiftclient:RESP STATUS: 401 Unauthorized + INFO:swiftclient:RESP HEADERS: [('Content-Length', '0'), ('Connection', + 'keep-alive'), ('X-Trans-Id', 'txecd82ae98e714ef0b4c0c-005731ed6c') , + ('Date', 'Tue, 10 May 2016 14:17:16 GMT'), ('Content-Type', 'text/htm + l; charset=UTF-8'), ('Www-Authenticate', 'Swift realm="KEY_32f0b6cd72 + 99412e9f7966b324fb6aea", Keystone uri=\'http://10.200.7.2:5000/\'')] + ERROR:swiftclient:Account HEAD failed: http://10.200.5.5:80/v1/KEY_32f0b6c + d7299412e9f7966b324fb6aea 401 Unauthorized + Traceback (most recent call last): + File "/usr/lib/pymodules/python2.7/swiftclient/client.py", line 1261, + in _retry + rv = func(self.url, self.token, *args, **kwargs) + File "/usr/lib/pymodules/python2.7/swiftclient/client.py", line 541, + in head_account + http_response_content=body) + ClientException: Account HEAD failed: http://10.200.5.5:80/v1/KEY_32f0b6cd + 7299412e9f7966b324fb6aea 401 Unauthorized + Account HEAD failed: http://10.200.5.5:80/v1/KEY_32f0b6cd7299412e9f7966b32 + 4fb6aea 401 Unauthorized + + + +If the keystone IP and Swift user and password are correct, please :ref:`find the password +from deployment yaml files` +and :ref:`config Swift middlewares ` first. Once that're done, +please :ref:`verify it with Swift CLI`. + + diff --git a/doc/user.rst b/doc/user.rst new file mode 100644 index 0000000..0845cb8 --- /dev/null +++ b/doc/user.rst @@ -0,0 +1,398 @@ +User Guide +========== + +SwiftStack provides **On-Premises** and **Public(Platform)** Controller to manage +Swift clusters. Here is an overview for network topology between SwiftStack cluster, +controller and Fuel slave nodes. + + + +SwiftStack Swift Cluster +------------------------ + +In SwiftStack Swift cluster, that have three network interfaces need to configure for each node. + + #. Outward-facing interface + The clients traffic come into this interface, so if you consider putting an external + load balancer in front of the cluster, you should add these outward-facing IPs to the load + balancer pool. + + #. Cluster-facing interface + The interface for Swift internal traffic likes proxy-server from/to object-server. + + #. Data replication interface + This interface is dedicated for object replication. + +If the node only has one network interface, you can assign all network interfaces to this +interface, but it'll be mixed all traffic together. So we suggest using dedicated interface for +these three network. Check `Configure network`_ to get more detail. + +.. _Configure network: https://swiftstack.com/docs/admin/node_management/configure_network.html#network + + +SwiftStack Controller +--------------------- + +SwiftStack provide two types of controllers, first one is **public controller** (we called `platform controller`) +and the second one is **On-Premises controller**. The public controller is for customers they don't want to setup +a SwiftStack Controller on their data center and also allow the nodes have internet connectivity for management +purpose. So, if you don't have an controller account yet, `try to create it`_ . + +In On-Premises controller, you need to get the setup script and tarball from SwiftStack sales, and they'll help +you to setup an on-premises controller. + +And make sure you have an account can login to controller and able to setup a swift cluster before you start +to test the plugin, + +The network configuration in SwiftStack Controller is quite simple, just check the SwiftStack Nodes can reach +SwiftStack controller because SwiftStack Nodes communciate with controller over OpenVPN connections. But if +you have a firewall in the middle; please check `SwiftStack Controller Security`_ and `SwiftStack Node Security`_ +to configure the firewall. + +.. _platform controller: https://platform.swiftstack.com +.. _try to create it: https://www.swiftstack.com/try-it-now/ + +.. _SwiftStack Controller Security: https://swiftstack.com/docs/security/controller.html#swiftstack-controller-security +.. _SwiftStack Node Security: https://swiftstack.com/docs/security/node.html#swiftstack-node-security + + +Fuel Slave Nodes +---------------- + +Fuel slave nodes have three network interfaces to configure, so if SwiftStack Nodes are connected to these +three networks and use same IP range of `fuel's configuration`_, you need to skip the IPs that used for SwiftStack +Nodes. The reason is the fuel master doesn't know which IP is taken from SwiftStack Nodes. + +The SwiftStack Swift cluster is a standalone cluster, and each client should come from Outward-facing network. +So connected to the fuel slave nodes with Outward-facing network should be enough. + +.. _fuel's configuration: http://docs.openstack.org/developer/fuel-docs/userdocs/fuel-install-guide/install/install_change_network_interface.html#configure-a-network-interface-for-the-fuel-web-ui + +Network summary +--------------- + +Please make sure the network configuration like: + + 1. Fuel controller nodes (Keystone, Glance) can talk to Swift Proxy-server (i.e., + Proxy-only, PAC, PACO node) for :ref:`Outward-facing IP`. + 2. Clients can talk to :ref:`Swift API IP Address` (Swift Proxy or External/Internal Load Balancer) + 3. SwiftStack nodes can talk to SwiftStack Controller + + .. note:: + + We only use one PACO (Proxy/Account/Comtainer/Object) nodes to deploy a all-in-one + Swift cluster in this document and is a minimum deployment. + In real environment, you might setup ten nodes or more for a Swift cluster, + so follow the roles can help you do integration. + + + +Use SwiftStack On-Premises Controller +------------------------------------- + + * 1 Controller Node + * 1 Compute Node (have **Compute** and **Storage - Cinder** roles) + * 1 Swift cluster + * 1 SwiftStack On-Premises controller + + .. note:: + In this diagram, the Swift cluster is also connected to management and public network, + for our use case, just make sure the storage network is connected should be enough, + Other interfaces of SwiftStack Nodes, should be used for cluster-facing and replication + networks. + + + .. image:: images/use_on_prem.png + + +Use SwiftStack Public Controller (Platform) +------------------------------------------- + + * 1 Controller Node + * 1 Compute Node (have **Compute** and **Storage - Cinder** roles) + * 1 Swift cluster + + .. note:: + In this diagram, the Swift cluster is also connected to management and public network, + for our use case, just make sure the storage network is connected should be enough, + Other interfaces of SwiftStack Nodes, should be used for cluster-facing and replication + networks. + + .. image:: images/use_platform.png + + +Deploying Mirantis OpenStack with a SwiftStack Swift cluster +------------------------------------------------------------ + +#. Create a new environment with two nodes: + + * Select **Liberty on Ubuntu Trusty (14.04)** as the distribution + * Select **Neutron with VLAN segmentation** as the networking setup + * Use all default settings + * 1 Controller Node (has **Controller** and **Storage - Cinder** roles) + * 1 Compute Node (has **Compute** role) + + .. image:: images/1_add_nodes.png + + .. _swift_api_ip_address: + + +#. Go to the Settings tab of the Fuel Web UI, + scroll down to **Storage** section, select **Enable SwiftStack Swift Cluster Integration** checkbox + and fill up all parameters. + + #. **Enable TLS for Swift endpoints**: + + This option will use HTTPS for swift endpoints include public, admin and internal urls. + + #. **Swift API IP Address** and **Swift API hostname**: + + The IP address is the default value for Swift endpoints, if you fill up the API hostname, that + overwrites Swift endpoints with hostname. + + #. **Use Swift as Glance backend** and **Enable upload test**: + + These two options for Glance integration + + .. note:: + If **Use Swift as Glance backend** is disabled, + please consider to enable **Ceph RBD for images (Glance)** or other storage for Glance backend. + + If **Enable upload test** is disabled, Fuel won't upload testVM image(cirros-testvm) + to Glance and store in Swift cluster. That means some **Functional tests** won't pass: + ``Create volume and boot instance from it``. + + The settings in below, + + #. Swift API IP Address: ``192.168.1.100``. + #. Use Swift as Glance backend: ``Checked`` + #. Enable upload test: ``Checked`` + + .. image:: images/2_enable_plugin.png + +#. Go to the **Networks** tab, scroll down to **Storage** section and then + uncheck **Use VLAN tagging** and modify **IP Range** to skip the Swift Proxy IP + (Outwarding-facing) and Swift API IP Address. + + .. image:: images/3_config_network.png + + If you install SwiftStack node on fuel slave nodes with role ``Operating System``, + please also skip the IPs in Public and Managent IP ranges, because the fuel master + doesn't know which IP addresses used for SwiftStack nodes. + + .. _proxy_outward_facing_ip: + .. _swift_api_ip: + + .. note:: + If you have more than one Proxy server (Proxy-only, PAC, PACO nodes), + or you use external/internal load balancer (Swift API IP Address) for + your swift cluster, please consider to skip these IPs. + + * ``Outtward-facing IP from SwiftStack Controller UI`` + + .. image:: images/3-1_proxy_outwarding-facing.png + + * ``Swift API IP address(Load balancer IP) from SwiftStack Controller UI`` + + .. image:: images/3-2_swift_api_ip.png + + +#. Go to the **Nodes** tab of the Fuel Web UI, + drag **Storage** interface to **eth2** for all nodes: + + .. image:: images/4_config_interfaces.png + + .. _find_keystone_password: + +#. Find the settings from deployment information: + * Keystone IP Address (management_vip) + * Swift password + + Please login to the fuel master and create a script file called **swiftstack.sh** + with contents in below, + + .. code-block:: bash + + #!/bin/bash + cd /root + fuel env + echo -e "\n\n" + read -p "Which environment?" environment + + # Export environment + fuel deployment --env $environment --default + + # put error checking here + SwiftIP=$(sed -e '/vips:/,/ipaddr:/!d' \ + deployment_*/primary-controller*.yaml \ + | grep ipaddr | awk '{print $2}') + SwiftPW=$(sed -e '/swift:/,/user_password:/!d' \ + deployment_*/primary-controller*.yaml \ + | grep user_password| awk '{print $2}') + + echo "Configure Keystone Auth Token Support middleware with the parameters below :" + echo "----------------------------------------------------------------------------" + echo " identity URL : http://$SwiftIP:35357/" + echo " auth_url : http://$SwiftIP:5000/" + echo " admin_user : swift" + echo " admin_password : $SwiftPW" + + Change permissions and run it. + + .. code-block:: bash + + [root@fuel ~]$ chmod +x swiftstack.sh + [root@fuel ~]$ ./swiftstack.sh + + id | status | name | release_id | pending_release_id + ---|--------|---------|------------|------------------- + 5 | new | MOS 8.0 | 2 | None + + + Which environment?5 + Default deployment info was downloaded to /root/deployment_5 + Configure Keystone Auth Token Support middleware with the parameters below : + ---------------------------------------------------------------------------- + identity URL : http://192.168.0.2:35357/ + auth_url : http://192.168.0.2:5000/ + admin_user : swift + admin_password : Ym35Y7j43K6LgsY9xYkJ5TbW + + .. _setup_swift_middleware: + +#. Once we get Keystone IP (192.168.0.2) and Swift user’s password (``Ym35Y7j43K6LgsY9xYkJ5TbW``), \ + let’s login to SwiftStack Controller UI to configure Swift cluster + + * Go to the **Middleware** tab, enable and configure **Keystone Auth Token Support** middleware as below: + + .. code-block:: bash + + identity_url: http://192.168.0.2:35357/ + auth_url: http://192.168.0.2:5000/ + admin_user: swift + admin_password: Ym35Y7j43K6LgsY9xYkJ5TbW + admin_tenant_name: services + + + .. image:: images/5_config_key1.png + + * Enable and configure **Keystone Auth** middleware as below: + + .. code-block:: bash + + reseller_admin_role: admin + + + .. image:: images/6_config_key2.png + + +#. Push configure settings to SwiftStack Swift cluster. + +#. Get back to the Fuel Web UI and deploy your OpenStack environment. + +#. Once Mirantis OpenStack environment is done, you will see the SwiftStack plugin is also deployed. + +.. image:: images/7_deploy_verify1.png + +Verification +++++++++++++ + +Please run the verification steps below to ensure your Swiftstack plugin is configured properly: + +#. Check API endpoints from OpenStack Dashboard: + + .. image:: images/8_deploy_verify2.png + + +.. _verity_cluster_swift_cli: + +#. Verify Swift cluster, Keystone and Glance integration through Swift cli + + * Check admin account + + .. code-block:: bash + + # Login to one of nodes of Swift cluster. + + # Test admin account + ~$ cat rc.admin + export ST_AUTH=http://192.168.0.2:5000/v2.0 + export ST_USER=admin:admin + export ST_KEY=admin + export ST_AUTH_VERSION=2 + + ~$ source rc.admin + ~$ swift stat -v + StorageURL: http://192.168.1.100:80/v1/KEY_c59857e + 9f07a44e691e1a12d3ef71d59 + Auth Token: gAAAAABW77vTlydZxpTB0yiRimVlTorg6IC9GR + lB5moChyd-P6NlsQ_rJva114IecQxxHB4YR5cd + RECCY4VQZnDSP9wgneG-xSi6P4XKwLDmX9lQKb + YGpCb1l19JyiuBdRZyoc3JC0uiFtW6YfQ0mvPp + VOEWgQJ02tL-vBqfFNcuiiWthn20Rok + Account: KEY_c59857e9f07a44e691e1a12d3ef71d59 + Containers: 0 + Objects: 0 + Bytes: 0 + Containers in policy "standard-replica": 0 + Objects in policy "standard-replica": 0 + Bytes in policy "standard-replica": 0 + Accept-Ranges: bytes + X-Account-Project-Domain-Id: default + X-Timestamp: 1458550300.21393 + X-Trans-Id: tx1d579f93ee7846fab0eaa-0056efbbd3 + Content-Type: text/plain; charset=utf-8 + + + + * Check glance account when **Use Swift as Glance backend** is enabled + + .. code-block:: bash + + # Find glance password from deployment yaml + [root@fuel ~]$ sed -e '/glance:/,/user_password:/!d' \ + deployment_*/primary-controller*.yaml + glance: + db_password: XkyxjTF4LKu7FgaY2YyXlUMI + image_cache_max_size: '13928339865' + user_password: ZHFGFM7ivEi0XPuL7l4tt5jE + + + + # Test glance account + ~$ cat rc.glance + export ST_AUTH=http://192.168.0.2:5000/v2.0 + export ST_USER=services:glance + export ST_KEY=ZHFGFM7ivEi0XPuL7l4tt5jE + export ST_AUTH_VERSION=2 + + ~$ swift stat -v + StorageURL: http://192.168.1.100:80/v1/KEY_fc5bc05137 + 09448da632c525728cf79 + Auth Token: gAAAAABW77t5VpWr7tzqAtOhYhWiQOo11kqeoSS_0 + mnX1WgNprVkAl5Sj8Ut0DuHYnBcg7UdwH00OHfotq + sS9PmetqQSP-RTuQwmwVLH8JAHtpZLm5CFa0ocIJj + o35oFavevzrjsokY4MefxyNlIhByshPelV6Dp3RD0 + C9aBygH96gedpOEUw + Account: KEY_fc5bc0513709448da632c525728cf794 + Containers: 1 + Objects: 1 + Bytes: 13287936 + Containers in policy "standard-replica": 1 + Objects in policy "standard-replica": 1 + Bytes in policy "standard-replica": 13287936 + Accept-Ranges: bytes + X-Account-Project-Domain-Id: default + X-Timestamp: 1458547227.84808 + X-Trans-Id: txac14e38486ea45c98bc6d-0056efbb8d + Content-Type: text/plain; charset=utf-8 + + + + +Appendix +-------- + + * SwiftStack docs can be found at https://swiftstack.com/docs/ + + diff --git a/environment_config.yaml b/environment_config.yaml index 068a80a..4050643 100644 --- a/environment_config.yaml +++ b/environment_config.yaml @@ -1,10 +1,65 @@ attributes: + metadata: + toggleable: true + group: 'storage' + restrictions: + - condition: "settings:storage.objects_ceph.value == true" + action: disable + swift_api_address: value: '192.168.1.100' label: 'Swift API IP Address' - description: 'Swift cluster API IP Address' - weight: 30 + description: | + If enabled, + * Swift deployment in controller nodes will be disabled + * Swift API endpoint in Keysthone DB will redirect to external Swift cluster. + weight: 10 type: "text" regex: - source: '^((?:\d|1?\d\d|2[0-4]\d|25[0-5])(?:\.(?:\d|1?\d\d|2[0-4]\d|25[0-5])){3})|(?:^)$' - error: "Invalid IP address" + source: '^((?:\d|1?\d\d|2[0-4]\d|25[0-5])(?:\.(?:\d|1?\d\d|2[0-4]\d|25[0-5])){3})|(?:^)$' + error: "Invalid IP address" + restrictions: + - condition: "settings:swiftstack.swift_api_fqdn.value != ''" + action: disable + message: "Configures Swift endpoint with hostname" + + swift_api_fqdn: + value: '' + label: 'Swift API Hostname' + description: "Swift API Hostname" + weight: 15 + type: "text" + + swift_tls_enabled: + weight: 5 + type: "checkbox" + value: False + label: "Enable TLS for Swift endpoints" + description: | + Configures all Swift endpoint urls (public/internal/admin) with TLS support. + restrictions: + - condition: "settings:public_ssl.services.value == true" + message: "TLS for OpenStack public endpoints is enabled" + action: none + + swift_as_glance_backend: + weight: 20 + type: "checkbox" + value: false + label: "Use Swift as Glance backend" + description: "Config Glance backend storage to Swift cluster" + restrictions: + - condition: "settings:storage.images_ceph.value == true" + action: disable + + upload_cirros_test: + weight: 30 + type: "checkbox" + value: false + label: "Enable upload test" + description: "Upload cirros base image to Glance and store it in Swift when the depoloyment is done" + restrictions: + - condition: "settings:swiftstack.swift_as_glance_backend.value == false" + action: disable + + diff --git a/metadata.yaml b/metadata.yaml index 915e5dd..45fb437 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -3,33 +3,28 @@ name: swiftstack # Human-readable name for your plugin title: Enable SwiftStack Swift cluster integration # Plugin version -version: '0.1.0' +version: '0.2.0' # Description -description: Integrate Keystone, Glance and existing SwiftStack Swift cluster +description: Integrate Keystone, Glance and an existing SwiftStack Swift cluster # Required fuel version -fuel_version: ['6.1'] +fuel_version: ['8.0'] # The plugin is compatible with releases in the list releases: - os: ubuntu - version: 2014.2-6.1 - mode: ['ha', 'multinode'] + version: liberty-8.0 + mode: ['ha'] deployment_scripts_path: deployment_scripts/ repository_path: repositories/ubuntu - - os: centos - version: 2014.2-6.1 - mode: ['ha', 'multinode'] - deployment_scripts_path: deployment_scripts/ - repository_path: repositories/centos # Version of plugin package -package_version: '2.0.0' +package_version: '3.0.0' # Licences licenses: ['Apache License Version 2.0'] # Specify author or company name authors: ['SwiftStack Inc.'] # A link to the plugin homepage -homepage: 'https://github.com/stackforge/fuel-plugin-swiftstack' +homepage: 'https://github.com/openstack/fuel-plugin-swiftstack' groups: ['storage'] diff --git a/pre_build_hook b/pre_build_hook index 09433b5..2e530c4 100755 --- a/pre_build_hook +++ b/pre_build_hook @@ -6,12 +6,26 @@ MODULES="${ROOT}"/deployment_scripts/puppet/modules RPM_REPO="${ROOT}"/repositories/centos/ DEB_REPO="${ROOT}"/repositories/ubuntu/ - # Puppet manifests from fuel-lib -FUEL_LIB_VERSION="6.1" -FUEL_LIB_TARBALL_URL="https://github.com/stackforge/fuel-library/archive/${FUEL_LIB_VERSION}.tar.gz" +FUEL_LIB_VERSION="7.0" +FUEL_LIB_TARBALL_URL="https://github.com/openstack/fuel-library/archive/${FUEL_LIB_VERSION}.tar.gz" + +# Puppet std library +STDLIB_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-stdlib-4.7.0.tar.gz" +INIFILE_TARBALL_URL="https://forgeapi.puppetlabs.com/v3/files/puppetlabs-inifile-1.4.2.tar.gz" + + +rm -rf "${MODULES:?}"/{openstacklib,glance,swift,keystone,stdlib,inifile} # Include dependent manifests from fuel-library wget -qO- "${FUEL_LIB_TARBALL_URL}" | \ tar -C "${MODULES}" --strip-components=3 -zxvf - \ - fuel-library-${FUEL_LIB_VERSION}/deployment/puppet/{stdlib,concat,lvm,glance,swift,inifile,keystone} + fuel-library-${FUEL_LIB_VERSION}/deployment/puppet/{openstacklib,glance,swift,keystone} + + +mkdir -p "${MODULES}"/{stdlib,inifile} +wget -qO- "${STDLIB_TARBALL_URL}" | tar -C "${MODULES}/stdlib" --strip-components=1 -xz +wget -qO- "${INIFILE_TARBALL_URL}" | tar -C "${MODULES}/inifile" --strip-components=1 -xz + + + diff --git a/tasks.yaml b/tasks.yaml deleted file mode 100644 index 3943a15..0000000 --- a/tasks.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# 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: ['primary-controller'] - stage: post_deployment/6000 - type: shell - parameters: - cmd: ruby delete_entrypoint.rb - timeout: 120 - -- role: ['primary-controller','controller'] - stage: post_deployment/6100 - type: puppet - parameters: - puppet_manifest: puppet/manifests/sscluster.pp - puppet_modules: puppet/modules - timeout: 420 - -- role: ['primary-controller'] - stage: post_deployment/6200 - type: shell - parameters: - cmd: ruby upload_cirros.rb - retries: 3 - interval: 20 - timeout: 180 -