Switch to using snap for simplestreams tools
Switch over to using the new simplestreams snap instead of using the largely unmaintained packaging in distro (and various PPA's). This drops direct integration with the simplestreams codebase in preference to just calling the sstream-mirror-glance command with the correct parameters. This commit includes refactoring of 'custom_properties' handling which was actually broken - there was no loading of the yaml formatted list, which was probably overkill, so the option now takes a space separated list of key=value pairs, for example: custom_properties="hw_firmware_type=uefi hw_vif_multiqueue_enabled=true" Fix version comparison in script wrapper. Drop Trusty support - snaps on Trusty are awkward requiring new kernel versions and trusty support was only retained for upgrade purposes anyway. Drop unsupported Xenial OpenStack versions. Fixup CA cert handling to use any charm installed CA cert (including that provided via the certificates relation) and install cert to snap compatible location for simplestreams to use. Add basic action to perform image sync on demand an refactor the glance simplestreams sync wrapper to work within a hook context to support the action. Disable automatic scheduling of image syncs by default as this tends to be racey during deployment resulting in images being synced to glance unit local storage. Add bionic-ussuri bundle and make it the default smoke test. Deprecate source and key options - no longer required for deployment with snap. Change-Id: I730df6b7f5955ddfeea5b8de15490ac083823f5a Func-Test-PR: https://github.com/openstack-charmers/zaza-openstack-tests/pull/321
This commit is contained in:
parent
5338427047
commit
fd3d2b7610
2
actions.yaml
Normal file
2
actions.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
sync-images:
|
||||||
|
description: "Sync all images into local OpenStack Cloud"
|
5
actions/sync-images
Executable file
5
actions/sync-images
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
/usr/share/glance-simplestreams-sync/glance-simplestreams-sync.sh
|
29
config.yaml
29
config.yaml
@ -4,14 +4,14 @@ options:
|
|||||||
default: "[{url: 'http://cloud-images.ubuntu.com/releases/',
|
default: "[{url: 'http://cloud-images.ubuntu.com/releases/',
|
||||||
name_prefix: 'ubuntu:released',
|
name_prefix: 'ubuntu:released',
|
||||||
path: 'streams/v1/index.sjson', max: 1,
|
path: 'streams/v1/index.sjson', max: 1,
|
||||||
item_filters: ['release~(trusty|xenial|bionic)', 'arch~(x86_64|amd64)', 'ftype~(disk1.img|disk.img)']}]"
|
item_filters: ['release~(trusty|xenial|bionic|focal)', 'arch~(x86_64|amd64)', 'ftype~(disk1.img|disk.img)']}]"
|
||||||
description: >
|
description: >
|
||||||
YAML-formatted list of simplestreams mirrors and their configuration
|
YAML-formatted list of simplestreams mirrors and their configuration
|
||||||
properties. Defaults to downloading the released images from
|
properties. Defaults to downloading the released images from
|
||||||
cloud-images.ubuntu.com.
|
cloud-images.ubuntu.com.
|
||||||
run:
|
run:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: True
|
default: False
|
||||||
description: "Should the sync be running or not?"
|
description: "Should the sync be running or not?"
|
||||||
use_swift:
|
use_swift:
|
||||||
type: boolean
|
type: boolean
|
||||||
@ -41,10 +41,11 @@ options:
|
|||||||
description: "This is prefixed to the object name when uploading to glance."
|
description: "This is prefixed to the object name when uploading to glance."
|
||||||
custom_properties:
|
custom_properties:
|
||||||
type: string
|
type: string
|
||||||
default: ""
|
default:
|
||||||
description: >
|
description: >
|
||||||
YAML-formatted list of any custom properties to be set in glance
|
Space separated list of custom properties (format key=value) to be
|
||||||
for the synced image, e.g. architecture, hypervisor_type.
|
set in glance for all synced images e.g. hw_firmware_type,
|
||||||
|
hw_vif_multiqueue_enabled.
|
||||||
content_id_template:
|
content_id_template:
|
||||||
type: string
|
type: string
|
||||||
default: "auto.sync"
|
default: "auto.sync"
|
||||||
@ -99,21 +100,11 @@ options:
|
|||||||
source:
|
source:
|
||||||
type: string
|
type: string
|
||||||
default:
|
default:
|
||||||
description: |
|
description: DEPRECATED - option no longer used and will be removed
|
||||||
Optional configuration to support use of additional sources such as:
|
|
||||||
|
|
||||||
- ppa:myteam/ppa
|
|
||||||
- cloud:trusty-proposed/kilo
|
|
||||||
- http://my.archive.com/ubuntu main
|
|
||||||
|
|
||||||
The last option should be used in conjunction with the key configuration
|
|
||||||
option.
|
|
||||||
key:
|
key:
|
||||||
type: string
|
type: string
|
||||||
default:
|
default:
|
||||||
description: |
|
description: DEPRECATED - option no longer used and will be removed
|
||||||
Key ID to import to the apt keyring to support use with arbitary source
|
|
||||||
configuration from outside of Launchpad archives or PPA's.
|
|
||||||
hypervisor_mapping:
|
hypervisor_mapping:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
@ -121,3 +112,7 @@ options:
|
|||||||
Enable configuration of hypervisor-type on synced images.
|
Enable configuration of hypervisor-type on synced images.
|
||||||
.
|
.
|
||||||
This is useful in multi-hypervisor clouds supporting both LXD and KVM.
|
This is useful in multi-hypervisor clouds supporting both LXD and KVM.
|
||||||
|
snap-channel:
|
||||||
|
type: string
|
||||||
|
default: stable
|
||||||
|
description: Snap channel to install simplestreams snap from
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -z "$HOME" ]; then
|
||||||
|
export HOME=/root
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
if [ -f /etc/profile.d/juju-proxy.sh ]; then
|
if [ -f /etc/profile.d/juju-proxy.sh ]; then
|
||||||
source /etc/profile.d/juju-proxy.sh
|
source /etc/profile.d/juju-proxy.sh
|
||||||
elif [ -f /etc/juju-proxy.conf ]; then
|
elif [ -f /etc/juju-proxy.conf ]; then
|
||||||
@ -8,10 +15,10 @@ elif [ -f /home/ubuntu/.juju-proxy ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
source /etc/lsb-release
|
source /etc/lsb-release
|
||||||
if [[ $DISTRIB_RELEASE > "18.04" ]]; then
|
if dpkg --compare-versions $DISTRIB_RELEASE gt "18.04"; then
|
||||||
PYTHON=python3
|
PYTHON=python3
|
||||||
else
|
else
|
||||||
PYTHON=python
|
PYTHON=python
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$PYTHON /usr/share/glance-simplestreams-sync/glance-simplestreams-sync.py
|
$PYTHON /usr/share/glance-simplestreams-sync/glance_simplestreams_sync.py
|
||||||
|
@ -27,6 +27,8 @@ import base64
|
|||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
def setup_logging():
|
def setup_logging():
|
||||||
@ -59,10 +61,6 @@ from keystoneclient.v2_0 import client as keystone_client
|
|||||||
from keystoneclient.v3 import client as keystone_v3_client
|
from keystoneclient.v3 import client as keystone_v3_client
|
||||||
import keystoneclient.exceptions as keystone_exceptions
|
import keystoneclient.exceptions as keystone_exceptions
|
||||||
import kombu
|
import kombu
|
||||||
from simplestreams.mirrors import glance, UrlMirrorReader
|
|
||||||
from simplestreams.objectstores.swift import SwiftObjectStore
|
|
||||||
from simplestreams.objectstores import FileStore
|
|
||||||
from simplestreams.util import read_signed, path_from_mirror_url
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
@ -92,7 +90,11 @@ PRODUCT_STREAMS_SERVICE_DESC = 'Ubuntu Product Streams'
|
|||||||
|
|
||||||
CRON_POLL_FILENAME = '/etc/cron.d/glance_simplestreams_sync_fastpoll'
|
CRON_POLL_FILENAME = '/etc/cron.d/glance_simplestreams_sync_fastpoll'
|
||||||
|
|
||||||
CACERT_FILE = os.path.join(CONF_FILE_DIR, 'cacert.pem')
|
SSTREAM_SNAP_COMMON = '/var/snap/simplestreams/common'
|
||||||
|
SSTREAM_LOG_FILE = os.path.join(SSTREAM_SNAP_COMMON,
|
||||||
|
'sstream-mirror-glance.log')
|
||||||
|
|
||||||
|
CACERT_FILE = os.path.join(SSTREAM_SNAP_COMMON, 'cacert.pem')
|
||||||
SYSTEM_CACERT_FILE = '/etc/ssl/certs/ca-certificates.crt'
|
SYSTEM_CACERT_FILE = '/etc/ssl/certs/ca-certificates.crt'
|
||||||
|
|
||||||
# TODOs:
|
# TODOs:
|
||||||
@ -103,63 +105,6 @@ SYSTEM_CACERT_FILE = '/etc/ssl/certs/ca-certificates.crt'
|
|||||||
# - figure out what content_id is and whether we should allow users to
|
# - figure out what content_id is and whether we should allow users to
|
||||||
# set it
|
# set it
|
||||||
|
|
||||||
try:
|
|
||||||
from simplestreams.util import ProgressAggregator
|
|
||||||
SIMPLESTREAMS_HAS_PROGRESS = True
|
|
||||||
except ImportError:
|
|
||||||
class ProgressAggregator:
|
|
||||||
"Dummy class to allow charm to load with old simplestreams"
|
|
||||||
SIMPLESTREAMS_HAS_PROGRESS = False
|
|
||||||
|
|
||||||
|
|
||||||
class GlanceMirrorWithCustomProperties(glance.GlanceMirror):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
custom_properties = kwargs.pop('custom_properties', {})
|
|
||||||
super(GlanceMirrorWithCustomProperties, self).__init__(*args, **kwargs)
|
|
||||||
self.custom_properties = custom_properties
|
|
||||||
|
|
||||||
def prepare_glance_arguments(self, *args, **kwargs):
|
|
||||||
|
|
||||||
glance_args = (super(GlanceMirrorWithCustomProperties, self)
|
|
||||||
.prepare_glance_arguments(*args, **kwargs))
|
|
||||||
|
|
||||||
if self.custom_properties:
|
|
||||||
log.info('Setting custom image properties: {}'.format(
|
|
||||||
self.custom_properties))
|
|
||||||
props = glance_args.get('properties', {})
|
|
||||||
props.update(self.custom_properties)
|
|
||||||
glance_args['properties'] = props
|
|
||||||
|
|
||||||
return glance_args
|
|
||||||
|
|
||||||
|
|
||||||
class StatusMessageProgressAggregator(ProgressAggregator):
|
|
||||||
def __init__(self, remaining_items, send_status_message):
|
|
||||||
super(StatusMessageProgressAggregator, self).__init__(remaining_items)
|
|
||||||
self.send_status_message = send_status_message
|
|
||||||
|
|
||||||
def emit(self, progress):
|
|
||||||
size = float(progress['size'])
|
|
||||||
written = float(progress['written'])
|
|
||||||
cur = self.total_image_count - len(self.remaining_items) + 1
|
|
||||||
totpct = float(self.total_written) / self.total_size
|
|
||||||
msg = "{name} {filepct:.0%}\n"\
|
|
||||||
"({cur} of {tot} images) total: "\
|
|
||||||
"{totpct:.0%}".format(name=progress['name'],
|
|
||||||
filepct=(written / size),
|
|
||||||
cur=cur,
|
|
||||||
tot=self.total_image_count,
|
|
||||||
totpct=totpct)
|
|
||||||
self.send_status_message(dict(status="Syncing",
|
|
||||||
message=msg))
|
|
||||||
|
|
||||||
|
|
||||||
def policy(content, path):
|
|
||||||
if path.endswith('sjson'):
|
|
||||||
return read_signed(content, keyring=KEYRING)
|
|
||||||
else:
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
def read_conf(filename):
|
def read_conf(filename):
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
@ -292,54 +237,68 @@ def do_sync(charm_conf, status_exchange):
|
|||||||
# user_agent = charm_conf.get("user_agent")
|
# user_agent = charm_conf.get("user_agent")
|
||||||
|
|
||||||
for mirror_info in charm_conf['mirror_list']:
|
for mirror_info in charm_conf['mirror_list']:
|
||||||
mirror_url, initial_path = path_from_mirror_url(mirror_info['url'],
|
# NOTE: output directory must be under HOME
|
||||||
mirror_info['path'])
|
# or snap cannot access it for stream files
|
||||||
|
tmpdir = tempfile.mkdtemp(dir=os.environ['HOME'])
|
||||||
|
try:
|
||||||
|
log.info("Configuring sync for url {}".format(mirror_info))
|
||||||
|
content_id = charm_conf['content_id_template'].format(
|
||||||
|
region=charm_conf['region'])
|
||||||
|
|
||||||
log.info("configuring sync for url {}".format(mirror_info))
|
sync_command = [
|
||||||
|
"/snap/bin/simplestreams.sstream-mirror-glance",
|
||||||
|
"-vv",
|
||||||
|
"--keep",
|
||||||
|
"--max", str(mirror_info['max']),
|
||||||
|
"--content-id", content_id,
|
||||||
|
"--cloud-name", charm_conf['cloud_name'],
|
||||||
|
"--path", mirror_info['path'],
|
||||||
|
"--name-prefix", charm_conf['name_prefix'],
|
||||||
|
"--keyring", KEYRING,
|
||||||
|
"--log-file", SSTREAM_LOG_FILE,
|
||||||
|
]
|
||||||
|
|
||||||
smirror = UrlMirrorReader(
|
if charm_conf['use_swift']:
|
||||||
mirror_url, policy=policy)
|
sync_command += [
|
||||||
|
'--output-swift',
|
||||||
|
SWIFT_DATA_DIR
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
sync_command += [
|
||||||
|
"--output-dir",
|
||||||
|
tmpdir
|
||||||
|
]
|
||||||
|
|
||||||
if charm_conf['use_swift']:
|
if charm_conf.get('hypervisor_mapping', False):
|
||||||
store = SwiftObjectStore(SWIFT_DATA_DIR)
|
sync_command += [
|
||||||
else:
|
'--hypervisor-mapping'
|
||||||
# Use the local apache server to serve product streams
|
]
|
||||||
store = FileStore(prefix=APACHE_DATA_DIR)
|
if charm_conf.get('custom_properties'):
|
||||||
|
custom_properties = charm_conf.get('custom_properties').split()
|
||||||
|
for custom_property in custom_properties:
|
||||||
|
sync_command += [
|
||||||
|
'--custom-property',
|
||||||
|
custom_property
|
||||||
|
]
|
||||||
|
|
||||||
content_id = charm_conf['content_id_template'].format(
|
sync_command += [
|
||||||
region=charm_conf['region'])
|
mirror_info['url'],
|
||||||
|
]
|
||||||
|
sync_command += mirror_info['item_filters']
|
||||||
|
|
||||||
config = {'max_items': mirror_info['max'],
|
log.info("calling sstream-mirror-glance")
|
||||||
'modify_hook': charm_conf['modify_hook_scripts'],
|
log.debug("command: {}".format(" ".join(sync_command)))
|
||||||
'keep_items': True,
|
subprocess.check_call(sync_command)
|
||||||
'content_id': content_id,
|
|
||||||
'cloud_name': charm_conf['cloud_name'],
|
|
||||||
'item_filters': mirror_info['item_filters'],
|
|
||||||
'hypervisor_mapping': charm_conf.get('hypervisor_mapping',
|
|
||||||
False)}
|
|
||||||
|
|
||||||
mirror_args = dict(config=config, objectstore=store,
|
if not charm_conf['use_swift']:
|
||||||
name_prefix=charm_conf['name_prefix'])
|
# Sync output directory to APACHE_DATA_DIR
|
||||||
mirror_args['custom_properties'] = charm_conf.get('custom_properties',
|
subprocess.check_call([
|
||||||
{})
|
'rsync', '-avz',
|
||||||
|
os.path.join(tmpdir, charm_conf['region'], 'streams'),
|
||||||
if SIMPLESTREAMS_HAS_PROGRESS:
|
APACHE_DATA_DIR
|
||||||
log.info("Calling DryRun mirror to get item list")
|
])
|
||||||
|
finally:
|
||||||
drmirror = glance.ItemInfoDryRunMirror(config=config,
|
shutil.rmtree(tmpdir)
|
||||||
objectstore=store)
|
|
||||||
drmirror.sync(smirror, path=initial_path)
|
|
||||||
p = StatusMessageProgressAggregator(drmirror.items,
|
|
||||||
status_exchange.send_message)
|
|
||||||
mirror_args['progress_callback'] = p.progress_callback
|
|
||||||
else:
|
|
||||||
log.info("Detected simplestreams version without progress"
|
|
||||||
" update support. Only limited feedback available.")
|
|
||||||
|
|
||||||
tmirror = GlanceMirrorWithCustomProperties(**mirror_args)
|
|
||||||
|
|
||||||
log.info("calling GlanceMirror.sync")
|
|
||||||
tmirror.sync(smirror, path=initial_path)
|
|
||||||
|
|
||||||
|
|
||||||
def update_product_streams_service(ksc, services, region):
|
def update_product_streams_service(ksc, services, region):
|
||||||
@ -367,18 +326,32 @@ def update_product_streams_service(ksc, services, region):
|
|||||||
|
|
||||||
|
|
||||||
def juju_run_cmd(cmd):
|
def juju_run_cmd(cmd):
|
||||||
'''Execute the passed commands under the local unit context'''
|
'''Execute the passed commands under the local unit context if required'''
|
||||||
id_conf, _ = get_conf()
|
# NOTE: determine whether juju-run is actually required
|
||||||
unit_name = id_conf['unit_name']
|
# supporting execution via actions.
|
||||||
_cmd = ['juju-run', unit_name, ' '.join(cmd)]
|
if not os.environ.get('JUJU_CONTEXT_ID'):
|
||||||
|
id_conf, _ = get_conf()
|
||||||
|
unit_name = id_conf['unit_name']
|
||||||
|
_cmd = ['juju-run', unit_name, ' '.join(cmd)]
|
||||||
|
else:
|
||||||
|
_cmd = cmd
|
||||||
log.info("Executing command: {}".format(_cmd))
|
log.info("Executing command: {}".format(_cmd))
|
||||||
return subprocess.check_output(_cmd)
|
return subprocess.check_output(_cmd)
|
||||||
|
|
||||||
|
|
||||||
def status_set(status, message):
|
def status_set(status, message):
|
||||||
try:
|
try:
|
||||||
juju_run_cmd(['status-set', status,
|
# NOTE: format of message is different for out of
|
||||||
'"{}"'.format(message)])
|
# context execution.
|
||||||
|
if not os.environ.get('JUJU_CONTEXT_ID'):
|
||||||
|
juju_run_cmd(['status-set', status,
|
||||||
|
'"{}"'.format(message)])
|
||||||
|
else:
|
||||||
|
subprocess.check_output([
|
||||||
|
'status-set',
|
||||||
|
status,
|
||||||
|
message
|
||||||
|
])
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
log.info(message)
|
log.info(message)
|
||||||
|
|
@ -14,6 +14,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import base64
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
@ -32,6 +33,7 @@ def _add_path(path):
|
|||||||
_add_path(_root)
|
_add_path(_root)
|
||||||
|
|
||||||
from charmhelpers.fetch import add_source, apt_install, apt_update
|
from charmhelpers.fetch import add_source, apt_install, apt_update
|
||||||
|
from charmhelpers.fetch.snap import snap_install
|
||||||
from charmhelpers.core import hookenv
|
from charmhelpers.core import hookenv
|
||||||
from charmhelpers.payload.execd import execd_preinstall
|
from charmhelpers.payload.execd import execd_preinstall
|
||||||
|
|
||||||
@ -66,7 +68,7 @@ USR_SHARE_DIR = '/usr/share/glance-simplestreams-sync'
|
|||||||
MIRRORS_CONF_FILE_NAME = os.path.join(CONF_FILE_DIR, 'mirrors.yaml')
|
MIRRORS_CONF_FILE_NAME = os.path.join(CONF_FILE_DIR, 'mirrors.yaml')
|
||||||
ID_CONF_FILE_NAME = os.path.join(CONF_FILE_DIR, 'identity.yaml')
|
ID_CONF_FILE_NAME = os.path.join(CONF_FILE_DIR, 'identity.yaml')
|
||||||
|
|
||||||
SYNC_SCRIPT_NAME = "glance-simplestreams-sync.py"
|
SYNC_SCRIPT_NAME = "glance_simplestreams_sync.py"
|
||||||
SCRIPT_WRAPPER_NAME = "glance-simplestreams-sync.sh"
|
SCRIPT_WRAPPER_NAME = "glance-simplestreams-sync.sh"
|
||||||
|
|
||||||
CRON_D = '/etc/cron.d/'
|
CRON_D = '/etc/cron.d/'
|
||||||
@ -76,16 +78,18 @@ CRON_POLL_FILEPATH = os.path.join(CRON_D, CRON_POLL_FILENAME)
|
|||||||
|
|
||||||
ERR_FILE_EXISTS = 17
|
ERR_FILE_EXISTS = 17
|
||||||
|
|
||||||
PACKAGES = ['python-simplestreams', 'python-glanceclient',
|
PACKAGES = ['python-glanceclient',
|
||||||
'python-yaml', 'python-keystoneclient',
|
'python-yaml', 'python-keystoneclient',
|
||||||
'python-kombu',
|
'python-kombu',
|
||||||
'python-swiftclient', 'ubuntu-cloudimage-keyring']
|
'python-swiftclient', 'ubuntu-cloudimage-keyring', 'snapd']
|
||||||
|
|
||||||
PY3_PACKAGES = ['python3-simplestreams', 'python3-glanceclient',
|
PY3_PACKAGES = ['python3-glanceclient',
|
||||||
'python3-yaml', 'python3-keystoneclient',
|
'python3-yaml', 'python3-keystoneclient',
|
||||||
'python3-kombu',
|
'python3-kombu',
|
||||||
'python3-swiftclient']
|
'python3-swiftclient']
|
||||||
|
|
||||||
|
JUJU_CA_CERT = "/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt"
|
||||||
|
|
||||||
hooks = hookenv.Hooks()
|
hooks = hookenv.Hooks()
|
||||||
|
|
||||||
|
|
||||||
@ -110,8 +114,12 @@ class SSLIdentityServiceContext(IdentityServiceContext):
|
|||||||
def __call__(self):
|
def __call__(self):
|
||||||
ctxt = super(SSLIdentityServiceContext, self).__call__()
|
ctxt = super(SSLIdentityServiceContext, self).__call__()
|
||||||
ssl_ca = hookenv.config('ssl_ca')
|
ssl_ca = hookenv.config('ssl_ca')
|
||||||
if ctxt and ssl_ca:
|
if ctxt:
|
||||||
ctxt['ssl_ca'] = ssl_ca
|
if ssl_ca:
|
||||||
|
ctxt['ssl_ca'] = ssl_ca
|
||||||
|
elif os.path.exists(JUJU_CA_CERT):
|
||||||
|
with open(JUJU_CA_CERT, 'rb') as ca_cert:
|
||||||
|
ctxt['ssl_ca'] = base64.b64encode(ca_cert.read()).decode()
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
|
|
||||||
@ -184,6 +192,12 @@ def get_configs():
|
|||||||
return configs
|
return configs
|
||||||
|
|
||||||
|
|
||||||
|
def install_gss_wrappers():
|
||||||
|
"""Installs wrapper scripts for execution of simplestreams sync."""
|
||||||
|
for fn in [SYNC_SCRIPT_NAME, SCRIPT_WRAPPER_NAME]:
|
||||||
|
shutil.copy(os.path.join("files", fn), USR_SHARE_DIR)
|
||||||
|
|
||||||
|
|
||||||
def install_cron_script():
|
def install_cron_script():
|
||||||
"""Installs cron job in /etc/cron.$frequency/ for repeating sync
|
"""Installs cron job in /etc/cron.$frequency/ for repeating sync
|
||||||
|
|
||||||
@ -191,9 +205,6 @@ def install_cron_script():
|
|||||||
up-to-date.
|
up-to-date.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for fn in [SYNC_SCRIPT_NAME, SCRIPT_WRAPPER_NAME]:
|
|
||||||
shutil.copy(os.path.join("files", fn), USR_SHARE_DIR)
|
|
||||||
|
|
||||||
config = hookenv.config()
|
config = hookenv.config()
|
||||||
installed_script = os.path.join(USR_SHARE_DIR, SCRIPT_WRAPPER_NAME)
|
installed_script = os.path.join(USR_SHARE_DIR, SCRIPT_WRAPPER_NAME)
|
||||||
linkname = '/etc/cron.{f}/{s}'.format(f=config['frequency'],
|
linkname = '/etc/cron.{f}/{s}'.format(f=config['frequency'],
|
||||||
@ -283,6 +294,11 @@ def install():
|
|||||||
|
|
||||||
apt_install(_packages)
|
apt_install(_packages)
|
||||||
|
|
||||||
|
snap_install('simplestreams',
|
||||||
|
*['--channel={}'.format(hookenv.config('snap-channel'))])
|
||||||
|
|
||||||
|
install_gss_wrappers()
|
||||||
|
|
||||||
hookenv.log('end install hook.')
|
hookenv.log('end install hook.')
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ tags:
|
|||||||
- misc
|
- misc
|
||||||
- openstack
|
- openstack
|
||||||
series:
|
series:
|
||||||
- trusty
|
|
||||||
- xenial
|
- xenial
|
||||||
- bionic
|
- bionic
|
||||||
- focal
|
- focal
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
series: xenial
|
series: bionic
|
||||||
|
|
||||||
comment:
|
comment:
|
||||||
- 'machines section to decide order of deployment. database sooner = faster'
|
- 'machines section to decide order of deployment. database sooner = faster'
|
||||||
|
|
||||||
machines:
|
machines:
|
||||||
'0':
|
'0':
|
||||||
constraints: mem=3072M
|
|
||||||
'1':
|
'1':
|
||||||
'2':
|
'2':
|
||||||
'3':
|
'3':
|
||||||
@ -43,24 +42,24 @@ applications:
|
|||||||
to:
|
to:
|
||||||
- '2'
|
- '2'
|
||||||
keystone:
|
keystone:
|
||||||
|
series: bionic
|
||||||
charm: cs:~openstack-charmers-next/keystone
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
num_units: 1
|
num_units: 1
|
||||||
options:
|
options:
|
||||||
openstack-origin: cloud:xenial-pike
|
openstack-origin: cloud:bionic-ussuri
|
||||||
to:
|
to:
|
||||||
- '3'
|
- '3'
|
||||||
glance:
|
glance:
|
||||||
charm: cs:~openstack-charmers-next/glance
|
charm: cs:~openstack-charmers-next/glance
|
||||||
num_units: 1
|
num_units: 1
|
||||||
options:
|
options:
|
||||||
openstack-origin: cloud:xenial-pike
|
openstack-origin: cloud:bionic-ussuri
|
||||||
to:
|
to:
|
||||||
- '4'
|
- '4'
|
||||||
glance-simplestreams-sync:
|
glance-simplestreams-sync:
|
||||||
charm: ../../glance-simplestreams-sync
|
charm: ../../glance-simplestreams-sync
|
||||||
num_units: 1
|
num_units: 1
|
||||||
options:
|
options:
|
||||||
source: ppa:simplestreams-dev/trunk
|
|
||||||
use_swift: False
|
use_swift: False
|
||||||
to:
|
to:
|
||||||
- '5'
|
- '5'
|
@ -1,59 +0,0 @@
|
|||||||
series: trusty
|
|
||||||
|
|
||||||
comment:
|
|
||||||
- 'machines section to decide order of deployment. database sooner = faster'
|
|
||||||
- 'no ssl for this bundle since charm-vault does not support trusty'
|
|
||||||
|
|
||||||
machines:
|
|
||||||
'0':
|
|
||||||
constraints: mem=3072M
|
|
||||||
# series "trusty" not supported by mysql charm
|
|
||||||
series: xenial
|
|
||||||
'1':
|
|
||||||
'2':
|
|
||||||
'3':
|
|
||||||
'4':
|
|
||||||
|
|
||||||
relations:
|
|
||||||
- ['keystone:shared-db', 'mysql:shared-db']
|
|
||||||
- ['glance:shared-db', 'mysql:shared-db']
|
|
||||||
- ['glance:amqp', 'rabbitmq-server:amqp']
|
|
||||||
- ['glance-simplestreams-sync:amqp', 'rabbitmq-server:amqp']
|
|
||||||
- ['glance:identity-service', 'keystone:identity-service']
|
|
||||||
- ['glance-simplestreams-sync:identity-service', 'keystone:identity-service']
|
|
||||||
|
|
||||||
applications:
|
|
||||||
mysql:
|
|
||||||
charm: cs:~openstack-charmers-next/percona-cluster
|
|
||||||
# series "trusty" not supported by mysql charm
|
|
||||||
series: xenial
|
|
||||||
num_units: 1
|
|
||||||
to:
|
|
||||||
- '0'
|
|
||||||
rabbitmq-server:
|
|
||||||
charm: cs:~openstack-charmers-next/rabbitmq-server
|
|
||||||
num_units: 1
|
|
||||||
to:
|
|
||||||
- '1'
|
|
||||||
keystone:
|
|
||||||
charm: cs:~openstack-charmers-next/keystone
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: cloud:trusty-mitaka
|
|
||||||
to:
|
|
||||||
- '2'
|
|
||||||
glance:
|
|
||||||
charm: cs:~openstack-charmers-next/glance
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: cloud:trusty-mitaka
|
|
||||||
to:
|
|
||||||
- '3'
|
|
||||||
glance-simplestreams-sync:
|
|
||||||
charm: ../../glance-simplestreams-sync
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
source: ppa:simplestreams-dev/trunk
|
|
||||||
use_swift: False
|
|
||||||
to:
|
|
||||||
- '4'
|
|
@ -1,66 +0,0 @@
|
|||||||
series: xenial
|
|
||||||
|
|
||||||
comment:
|
|
||||||
- 'machines section to decide order of deployment. database sooner = faster'
|
|
||||||
|
|
||||||
machines:
|
|
||||||
'0':
|
|
||||||
constraints: mem=3072M
|
|
||||||
'1':
|
|
||||||
'2':
|
|
||||||
'3':
|
|
||||||
'4':
|
|
||||||
'5':
|
|
||||||
|
|
||||||
relations:
|
|
||||||
- ['vault:shared-db', 'mysql:shared-db']
|
|
||||||
- ['keystone:shared-db', 'mysql:shared-db']
|
|
||||||
- ['glance:shared-db', 'mysql:shared-db']
|
|
||||||
- ['glance:amqp', 'rabbitmq-server:amqp']
|
|
||||||
- ['glance-simplestreams-sync:amqp', 'rabbitmq-server:amqp']
|
|
||||||
- ['keystone:certificates', 'vault:certificates']
|
|
||||||
- ['glance:certificates', 'vault:certificates']
|
|
||||||
- ['glance-simplestreams-sync:certificates', 'vault:certificates']
|
|
||||||
- ['glance:identity-service', 'keystone:identity-service']
|
|
||||||
- ['glance-simplestreams-sync:identity-service', 'keystone:identity-service']
|
|
||||||
|
|
||||||
applications:
|
|
||||||
mysql:
|
|
||||||
charm: cs:~openstack-charmers-next/percona-cluster
|
|
||||||
num_units: 1
|
|
||||||
to:
|
|
||||||
- '0'
|
|
||||||
rabbitmq-server:
|
|
||||||
charm: cs:~openstack-charmers-next/rabbitmq-server
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
ssl: 'on' # must be str(in quote), otherwise it's bool
|
|
||||||
to:
|
|
||||||
- '1'
|
|
||||||
vault:
|
|
||||||
charm: cs:~openstack-charmers-next/vault
|
|
||||||
num_units: 1
|
|
||||||
to:
|
|
||||||
- '2'
|
|
||||||
keystone:
|
|
||||||
charm: cs:~openstack-charmers-next/keystone
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: cloud:xenial-ocata
|
|
||||||
to:
|
|
||||||
- '3'
|
|
||||||
glance:
|
|
||||||
charm: cs:~openstack-charmers-next/glance
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: cloud:xenial-ocata
|
|
||||||
to:
|
|
||||||
- '4'
|
|
||||||
glance-simplestreams-sync:
|
|
||||||
charm: ../../glance-simplestreams-sync
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
source: ppa:simplestreams-dev/trunk
|
|
||||||
use_swift: False
|
|
||||||
to:
|
|
||||||
- '5'
|
|
@ -6,15 +6,13 @@ comment:
|
|||||||
# functest-run-suite ...
|
# functest-run-suite ...
|
||||||
# functest-deploy --bundle /path/to/gate/bundle
|
# functest-deploy --bundle /path/to/gate/bundle
|
||||||
gate_bundles:
|
gate_bundles:
|
||||||
- model_alias_trusty: trusty-mitaka
|
|
||||||
- xenial-mitaka
|
- xenial-mitaka
|
||||||
- xenial-ocata
|
|
||||||
- xenial-pike
|
|
||||||
- xenial-queens
|
- xenial-queens
|
||||||
- bionic-queens
|
- bionic-queens
|
||||||
- bionic-rocky
|
- bionic-rocky
|
||||||
- bionic-stein
|
- bionic-stein
|
||||||
- bionic-train
|
- bionic-train
|
||||||
|
- bionic-ussuri
|
||||||
- focal-ussuri
|
- focal-ussuri
|
||||||
|
|
||||||
tests_options:
|
tests_options:
|
||||||
@ -25,7 +23,7 @@ tests_options:
|
|||||||
# functest-deploy --bundle /path/to/smoke/bundle
|
# functest-deploy --bundle /path/to/smoke/bundle
|
||||||
# smoke bundle should (Ubuntu LTS latest)-(OpenStack latest)
|
# smoke bundle should (Ubuntu LTS latest)-(OpenStack latest)
|
||||||
smoke_bundles:
|
smoke_bundles:
|
||||||
- bionic-train
|
- bionic-ussuri
|
||||||
|
|
||||||
# functest-run-suite --dev ...
|
# functest-run-suite --dev ...
|
||||||
# functest-deploy --bundle /path/to/dev/bundle
|
# functest-deploy --bundle /path/to/dev/bundle
|
||||||
@ -43,14 +41,13 @@ target_deploy_status:
|
|||||||
glance-simplestreams-sync:
|
glance-simplestreams-sync:
|
||||||
# gss will be blocked since glance and rabbitmq don't have their
|
# gss will be blocked since glance and rabbitmq don't have their
|
||||||
# certificates yet. This should be fixed after vault initialization
|
# certificates yet. This should be fixed after vault initialization
|
||||||
workload-status: blocked
|
workload-status: unknown
|
||||||
workload-status-message: Image sync failed, retrying soon.
|
workload-status-message: ""
|
||||||
|
|
||||||
# functest-configure
|
# functest-configure
|
||||||
configure:
|
configure:
|
||||||
- zaza.openstack.charm_tests.vault.setup.auto_initialize
|
- zaza.openstack.charm_tests.vault.setup.auto_initialize
|
||||||
# skip vault init for trusty since vault doesn't suport trusty
|
- zaza.openstack.charm_tests.glance_simplestreams_sync.setup.sync_images
|
||||||
- model_alias_trusty: []
|
|
||||||
|
|
||||||
# functest-test
|
# functest-test
|
||||||
tests:
|
tests:
|
||||||
|
@ -57,6 +57,8 @@ class TestConfigChanged(CharmTestCase):
|
|||||||
|
|
||||||
setattr(self.test_config, "changed", lambda x: False)
|
setattr(self.test_config, "changed", lambda x: False)
|
||||||
config.return_value = self.test_config
|
config.return_value = self.test_config
|
||||||
|
self.test_config.set('run', True)
|
||||||
|
|
||||||
hooks.config_changed()
|
hooks.config_changed()
|
||||||
|
|
||||||
symlink.assert_any_call(os.path.join(self.sharedir,
|
symlink.assert_any_call(os.path.join(self.sharedir,
|
||||||
@ -92,10 +94,9 @@ class TestConfigChanged(CharmTestCase):
|
|||||||
nrpe_config.return_value = self.test_config
|
nrpe_config.return_value = self.test_config
|
||||||
|
|
||||||
setattr(self.test_config, "changed", lambda x: False)
|
setattr(self.test_config, "changed", lambda x: False)
|
||||||
self.test_config.config["custom_properties"] = {
|
self.test_config.config["custom_properties"] = (
|
||||||
'hypervisor_type': 'kvm',
|
"hypervisor_type=kvm hw_firmware_type=uefi"
|
||||||
'hw_firmware_type': 'uefi'
|
)
|
||||||
}
|
|
||||||
config.return_value = self.test_config
|
config.return_value = self.test_config
|
||||||
hooks.config_changed()
|
hooks.config_changed()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user