This patch add experimental s3 support for Trilio

This patch allows an s3 backend to be used to store Trilio artefacts.
Connection auth and endpoint are set via the s3 charm config options.
To use an s3 backend the backup-target-type should be set to
'experimental-s3'.

func-test-pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/516

Change-Id: I1dab03d25e6e583d88d69ea15e5b5119151c9676
This commit is contained in:
Liam Young 2021-03-04 17:34:52 +00:00
parent cb2e78c437
commit 8e36f135e6
8 changed files with 358 additions and 22 deletions

View File

@ -11,6 +11,7 @@
- focal-ussuri-41
- bionic-queens-40
- bionic-queens-41
- bionic-train-41-s3
vars:
needs_charm_build: true
charm_build_name: trilio-data-mover
@ -68,3 +69,9 @@
dependencies: *smoke-jobs
vars:
tox_extra_args: bionic-ussuri-41
- job:
name: bionic-train-41-s3
parent: func-target
dependencies: *smoke-jobs
vars:
tox_extra_args: bionic-train-41-s3

View File

@ -32,11 +32,11 @@ options:
# UNSUPPORTED
tv-s3-secret-key:
type: string
default: sample_s3_secret_key
default:
description: S3 secret access key
tv-s3-access-key:
type: string
default: sample_s3_access_key
default:
description: S3 access key
tv-s3-region-name:
type: string
@ -44,7 +44,7 @@ options:
description: S3 region name
tv-s3-bucket:
type: string
default: sample_s3_bucket_name
default:
description: S3 bucket name
tv-s3-endpoint-url:
type: string

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import os
import charmhelpers.core.hookenv as hookenv
@ -45,6 +46,14 @@ class DataMoverDBAdapter(os_adapters.DatabaseRelationAdapter):
return self.get_uri(prefix="dmapi")
@charms_openstack.adapters.config_property
def translated_backup_target_type(cls):
_type = hookenv.config("backup-target-type").lower()
if _type == "experimental-s3":
return 's3'
return _type
@os_adapters.config_property
def ceph_dir(ceph):
return os.path.join("/var/lib/charm", hookenv.service_name())
@ -94,13 +103,14 @@ class TrilioDataMoverBaseCharm(
data_mover_conf = "/etc/tvault-contego/tvault-contego.conf"
logrotate_conf = "/etc/logrotate.d/tvault-contego"
object_store_conf = "/etc/tvault-object-store/tvault-object-store.conf"
service_type = "data-mover"
default_service = "tvault-contego"
required_relations = ["amqp", "shared-db"]
packages = ["tvault-contego", "nfs-common", "contego"]
base_packages = ["tvault-contego", "nfs-common", "contego"]
# configuration file permissions
user = "root"
@ -114,6 +124,26 @@ class TrilioDataMoverBaseCharm(
os_release_pkg = "nova-common"
package_codenames = os_utils.PACKAGE_CODENAMES
@property
def backup_target_type(self):
# The main purpose of this property is to translate experimental-s3
# to s3 and s3 to UNKNOWN. This forces the deployer to
# use 'experimental-s3' for s3 support but the code can stay clean and
# refer to s3.
_type = hookenv.config("backup-target-type").lower()
if _type == 'experimental-s3':
return 's3'
if _type == 'nfs':
return 'nfs'
return 'UNKNOWN'
@property
def packages(self):
_pkgs = copy.deepcopy(self.base_packages)
if self.backup_target_type == 's3':
_pkgs.append('python3-s3-fuse-plugin')
return _pkgs
# Set ceph keyring prefix to charm specific location
@property
def ceph_keyring_path_prefix(self):
@ -169,25 +199,42 @@ class TrilioDataMoverBaseCharm(
@property
def services(self):
if hookenv.config("backup-target-type") == "s3":
if self.backup_target_type == "s3":
return ["tvault-contego", "tvault-object-store"]
return ["tvault-contego"]
@property
def restart_map(self):
if reactive.flags.is_flag_set("ceph.available"):
return {
self.data_mover_conf: self.services,
self.ceph_conf: self.services,
}
return {
_restart_map = {
self.data_mover_conf: self.services,
}
if reactive.flags.is_flag_set("ceph.available"):
_restart_map[self.ceph_conf] = self.services
if self.backup_target_type == 's3':
_restart_map[self.object_store_conf] = ['tvault-object-store']
return _restart_map
def custom_assess_status_check(self):
"""Check required configuration options are set"""
if not hookenv.config("nfs-shares"):
return "blocked", "nfs-shares configuration not set"
check_config_set = []
if self.backup_target_type == "nfs":
check_config_set = ['nfs-shares']
elif self.backup_target_type == "s3":
check_config_set = [
"tv-s3-secret-key",
"tv-s3-access-key",
"tv-s3-region-name",
"tv-s3-bucket",
"tv-s3-endpoint-url"]
unset_config = [c for c in check_config_set if not hookenv.config(c)]
if unset_config:
return "blocked", "{} configuration not set".format(
', '.join(unset_config))
# For s3 support backup-target-type should be set to 'experimental-s3'
# as s3 support is pre-production. The self.backup_target_type
# property will do any transaltion needed.
if self.backup_target_type not in ["nfs", "s3"]:
return "blocked", "Backup target type not supported"
return None, None
def request_access_to_groups(self, ceph):
@ -216,7 +263,7 @@ class TrilioDataMoverRockyCharm(TrilioDataMoverBaseCharm):
# Python version used to execute installed workload
python_version = 3
packages = ["python3-tvault-contego", "nfs-common", "contego"]
base_packages = ["python3-tvault-contego", "nfs-common", "contego"]
@classmethod
def trilio_version_package(cls):

View File

@ -13,13 +13,13 @@ dmapi_transport_url = {{ amqp.transport_url }}
rabbit_virtual_host = {{ amqp.vhost }}
{% endif -%}
{% if options.backup_target_type == 'nfs' -%}
{% if options.translated_backup_target_type == 'nfs' -%}
# NFS
vault_storage_nfs_export = {{ options.nfs_shares }}
vault_storage_nfs_options = {{ options.nfs_options }}
{% endif -%}
{% if options.backup_target_type == 's3' -%}
{% if options.translated_backup_target_type == 's3' -%}
# S3
vault_storage_nfs_export = TrilioVault
vault_s3_auth_version = DEFAULT
@ -31,7 +31,7 @@ vault_s3_endpoint_url = {{ options.tv_s3_endpoint_url }}
{% endif -%}
# MISC
vault_storage_type = {{ options.backup_target_type }}
vault_storage_type = {{ options.translated_backup_target_type }}
vault_data_directory_old = {{ options.tv_data_dir_old }}
vault_data_directory = {{ options.tv_data_dir }}

View File

@ -0,0 +1,19 @@
[DEFAULT]
verbose = {{ options.verbose }}
debug = {{ options.debug }}
log_file = /var/log/tvault-object-store/tvault-object-store.log
vault_storage_nfs_export = TrilioVault
vault_data_directory = /var/triliovault-mounts
vault_data_directory_old = /var/triliovault
vault_storage_type = {{ options.translated_backup_target_type }}
vault_storage_nfs_export = TrilioVault
vault_s3_auth_version = DEFAULT
vault_s3_access_key_id = {{ options.tv_s3_access_key }}
vault_s3_secret_access_key = {{ options.tv_s3_secret_key }}
vault_s3_region_name = {{ options.tv_s3_region_name }}
vault_s3_bucket = {{ options.tv_s3_bucket }}
vault_s3_endpoint_url = {{ options.tv_s3_endpoint_url }}
[s3fuse_sys_admin]
helper_command = sudo /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf privsep-helper

View File

@ -0,0 +1,249 @@
local_overlay_enabled: False
variables:
openstack-origin: &openstack-origin 'cloud:bionic-train'
triliovault-pkg-source: &triliovault-pkg-source 'deb [trusted=yes] https://apt.fury.io/triliodata-4-1/ /'
series: &series bionic
relations:
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'neutron-gateway:amqp'
- 'rabbitmq-server:amqp'
- - 'neutron-gateway:amqp-nova'
- 'rabbitmq-server:amqp'
- - 'keystone:shared-db'
- 'mysql:shared-db'
- - 'cinder:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'neutron-api:identity-service'
- 'keystone:identity-service'
- - 'neutron-openvswitch:neutron-plugin-api'
- 'neutron-api:neutron-plugin-api'
- - 'cinder:shared-db'
- 'mysql:shared-db'
- - 'neutron-api:shared-db'
- 'mysql:shared-db'
- - 'cinder:amqp'
- 'rabbitmq-server:amqp'
- - 'neutron-api:amqp'
- 'rabbitmq-server:amqp'
- - 'neutron-gateway:neutron-plugin-api'
- 'neutron-api:neutron-plugin-api'
- - 'glance:shared-db'
- 'mysql:shared-db'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:quantum-network-service'
- 'neutron-gateway:quantum-network-service'
- - 'nova-compute:neutron-plugin'
- 'neutron-openvswitch:neutron-plugin'
- - 'neutron-openvswitch:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:shared-db'
- 'mysql:shared-db'
- - 'nova-cloud-controller:neutron-api'
- 'neutron-api:neutron-api'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'trilio-wlm:shared-db'
- 'mysql:shared-db'
- - 'trilio-wlm:amqp'
- 'rabbitmq-server:amqp'
- - 'trilio-wlm:identity-service'
- 'keystone:identity-service'
- - 'glance:ceph'
- 'ceph-mon:client'
- - 'ceph-mon:osd'
- 'ceph-osd:mon'
- - 'ceph-osd:secrets-storage'
- 'vault:secrets'
- - 'cinder:storage-backend'
- 'cinder-ceph:storage-backend'
- - 'cinder-ceph:ceph'
- 'ceph-mon:client'
- - 'cinder-ceph:ceph-access'
- 'nova-compute:ceph-access'
- - 'vault:shared-db'
- 'mysql:shared-db'
- - 'vault:certificates'
- 'keystone:certificates'
- - 'vault:certificates'
- 'neutron-api:certificates'
- - 'vault:certificates'
- 'cinder:certificates'
- - 'vault:certificates'
- 'glance:certificates'
- - 'vault:certificates'
- 'nova-cloud-controller:certificates'
- - 'placement:shared-db'
- 'mysql:shared-db'
- - 'placement:identity-service'
- 'keystone:identity-service'
- - 'placement:placement'
- 'nova-cloud-controller:placement'
- - 'vault:certificates'
- 'placement:certificates'
- - 'vault:certificates'
- 'trilio-wlm:certificates'
- - 'trilio-data-mover:amqp'
- 'rabbitmq-server:amqp'
- - 'trilio-data-mover:juju-info'
- 'nova-compute:juju-info'
- - 'trilio-dm-api:identity-service'
- 'keystone:identity-service'
- - 'trilio-dm-api:shared-db'
- 'mysql:shared-db'
- - 'trilio-dm-api:amqp'
- 'rabbitmq-server:amqp'
- - 'trilio-dm-api:certificates'
- 'vault:certificates'
- - 'trilio-horizon-plugin:dashboard-plugin'
- 'openstack-dashboard:dashboard-plugin'
- - 'openstack-dashboard:identity-service'
- 'keystone:identity-service'
- - 'trilio-data-mover:ceph'
- 'ceph-mon:client'
- - 'trilio-data-mover:shared-db'
- 'mysql:shared-db'
- - 'ceph-radosgw:mon'
- 'ceph-mon:radosgw'
- - 'ceph-radosgw:identity-service'
- 'keystone:identity-service'
- - 'ceph-radosgw:certificates'
- 'vault:certificates'
applications:
ceph-radosgw:
charm: cs:~openstack-charmers-next/ceph-radosgw
num_units: 1
options:
source: *openstack-origin
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *openstack-origin
cinder:
charm: cs:~openstack-charmers-next/cinder
num_units: 1
options:
openstack-origin: *openstack-origin
block-device: "None"
glance-api-version: 2
keystone:
charm: cs:~openstack-charmers-next/keystone
series: bionic
num_units: 1
options:
openstack-origin: *openstack-origin
admin-password: openstack
mysql:
charm: cs:~openstack-charmers-next/percona-cluster
num_units: 1
options:
innodb-buffer-pool-size: 256M
max-connections: 1000
neutron-api:
charm: cs:~openstack-charmers-next/neutron-api
num_units: 1
options:
openstack-origin: *openstack-origin
flat-network-providers: physnet1
neutron-security-groups: true
neutron-gateway:
charm: cs:~openstack-charmers-next/neutron-gateway
num_units: 1
options:
openstack-origin: *openstack-origin
bridge-mappings: physnet1:br-ex
neutron-openvswitch:
charm: cs:~openstack-charmers-next/neutron-openvswitch
num_units: 0
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
openstack-origin: *openstack-origin
network-manager: Neutron
debug: true
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 3
constraints: mem=4G
options:
openstack-origin: *openstack-origin
config-flags: default_ephemeral_format=ext4
enable-live-migration: true
enable-resize: true
migration-auth-type: ssh
debug: true
cpu-model: kvm64
cpu-mode: custom
# Allow for more retries when testing ontop of openstack
config-flags: block_device_allocate_retries=120
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
trilio-data-mover:
charm: ../../../trilio-data-mover
options:
triliovault-pkg-source: *triliovault-pkg-source
backup-target-type: experimental-s3
trilio-dm-api:
charm: cs:~openstack-charmers-next/trilio-dm-api
num_units: 1
options:
openstack-origin: *openstack-origin
triliovault-pkg-source: *triliovault-pkg-source
trilio-horizon-plugin:
charm: cs:~openstack-charmers-next/trilio-horizon-plugin
options:
triliovault-pkg-source: *triliovault-pkg-source
trilio-wlm:
charm: cs:~openstack-charmers-next/trilio-wlm
num_units: 1
options:
openstack-origin: *openstack-origin
triliovault-pkg-source: *triliovault-pkg-source
backup-target-type: experimental-s3
ceph-mon:
charm: cs:~openstack-charmers-next/ceph-mon
num_units: 3
options:
source: *openstack-origin
expected-osd-count: 3
ceph-osd:
charm: cs:~openstack-charmers-next/ceph-osd
constraints: mem=1G
num_units: 3
options:
source: *openstack-origin
osd-encrypt-keymanager: vault
osd-encrypt: True
storage:
osd-devices: cinder,40G
cinder-ceph:
charm: cs:~openstack-charmers-next/cinder-ceph
vault:
num_units: 1
charm: cs:~openstack-charmers-next/vault
placement:
charm: cs:~openstack-charmers-next/placement
num_units: 1
options:
openstack-origin: *openstack-origin
openstack-dashboard:
charm: cs:~openstack-charmers-next/openstack-dashboard
num_units: 1
options:
openstack-origin: *openstack-origin

View File

@ -1,15 +1,26 @@
charm_name: trilio-data-mover
tests:
- zaza.openstack.charm_tests.trilio.tests.TrilioDataMoverTest
- zaza.openstack.charm_tests.trilio.tests.TrilioDataMoverNFSTest
- s3:
- zaza.openstack.charm_tests.trilio.tests.TrilioDataMoverS3Test
configure:
- zaza.openstack.charm_tests.trilio.setup.basic_setup
- s3:
- zaza.openstack.charm_tests.vault.setup.auto_initialize
- zaza.openstack.charm_tests.trilio.setup.basic_setup
- zaza.openstack.charm_tests.glance.setup.add_cirros_image
- zaza.openstack.charm_tests.glance.setup.add_lts_image
- zaza.openstack.charm_tests.neutron.setup.basic_overcloud_network
- zaza.openstack.charm_tests.nova.setup.create_flavors
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
- zaza.openstack.charm_tests.vault.setup.auto_initialize
- zaza.openstack.charm_tests.trilio.setup.basic_setup
- zaza.openstack.charm_tests.glance.setup.add_cirros_image
- zaza.openstack.charm_tests.glance.setup.add_lts_image
- zaza.openstack.charm_tests.neutron.setup.basic_overcloud_network
- zaza.openstack.charm_tests.nova.setup.create_flavors
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
gate_bundles:
- s3: bionic-train-41-s3
- bionic-stein-40
- bionic-stein-41
- bionic-train-40
@ -35,10 +46,13 @@ target_deploy_status:
workload-status-message: "Ceph broker request incomplete"
trilio-wlm:
workload-status: blocked
workload-status-message: "nfs-shares configuration not set"
workload-status-message-regex: "configuration not set|Unit is ready"
trilio-data-mover:
workload-status: blocked
workload-status-message: "nfs-shares configuration not set"
workload-status-message-regex: "configuration not set|Unit is ready"
glance:
workload-status: waiting
workload-status-message: "Incomplete relations: storage-backend"
ceph-radosgw:
workload-status: waiting
workload-status-message: "Incomplete relations: mon"

View File

@ -39,7 +39,7 @@ class TestTrilioDataMoverRockyCharms(Helper):
def test_services_s3(self):
dm_charm = trilio_dm.TrilioDataMoverRockyCharm()
self.patch_object(trilio_dm.hookenv, "config")
self.config.return_value = "s3"
self.config.return_value = "experimental-s3"
self.assertEqual(
dm_charm.services, ["tvault-contego", "tvault-object-store"]
)