Add support for placement service

Change-Id: If2b71c4d54d990dd8144a837ddaf7ee3facb2bad
This commit is contained in:
Mohammed Naser 2020-08-17 13:58:24 -04:00
parent fb6fde762d
commit 882b4f2747
16 changed files with 460 additions and 26 deletions

View File

@ -5,6 +5,7 @@ configMap:
ceilometer: ceilometer:
dbUri: "sqlite:///:memory:" dbUri: "sqlite:///:memory:"
glance: {} glance: {}
placement: {}
horizon: horizon:
hostAliases: hostAliases:
- hostnames: - hostnames:

View File

@ -14,6 +14,7 @@ data:
heat: {} heat: {}
magnum: {} magnum: {}
chronyd: {} chronyd: {}
placement: {}
backup: backup:
secretName: aws-backup secretName: aws-backup
url: s3://backups/ url: s3://backups/

72
devstack/lib/placement Normal file
View File

@ -0,0 +1,72 @@
#!/bin/bash
#
# Copyright 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
function cleanup_placement {
echo noop
}
export -f cleanup_placement
function create_placement_conf {
iniset $PLACEMENT_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
iniset $PLACEMENT_CONF api auth_strategy $PLACEMENT_AUTH_STRATEGY
kubernetes_ensure_resource secret/placement-mysql
PLACEMENT_DATABASE_USER=$(get_data_from_secret placement-mysql openstack USER)
PLACEMENT_DATABASE_PASSWORD=$(get_data_from_secret placement-mysql openstack PASSWORD)
PLACEMENT_DATABASE_NAME=$(get_data_from_secret placement-mysql openstack DATABASE)
iniset $PLACEMENT_CONF placement_database connection "mysql+pymysql://$PLACEMENT_DATABASE_USER:$PLACEMENT_DATABASE_PASSWORD@placement-mysql-master/$PLACEMENT_DATABASE_NAME?charset=utf8"
kubernetes_ensure_resource secret/placement-application-credential
PLACEMENT_APPLICATION_CREDENTIAL_SECRET=$(get_data_from_secret placement-application-credential openstack secret)
PLACEMENT_APPLICATION_CREDENTIAL_ID=$(get_data_from_secret placement-application-credential openstack id)
iniset $PLACEMENT_CONF keystone_authtoken auth_url $KEYSTONE_AUTH_URI_V3
iniset $PLACEMENT_CONF keystone_authtoken auth_type v3applicationcredential
iniset $PLACEMENT_CONF keystone_authtoken application_credential_id $PLACEMENT_APPLICATION_CREDENTIAL_ID
iniset $PLACEMENT_CONF keystone_authtoken application_credential_secret $PLACEMENT_APPLICATION_CREDENTIAL_SECRET
}
export -f create_placement_conf
function configure_placement {
sudo install -d -o $STACK_USER $PLACEMENT_CONF_DIR
create_placement_conf
kubectl create secret generic placement-config --from-file=${PLACEMENT_CONF} -n openstack
proxy_pass_to_kubernetes /placement placement placement-api
}
export -f configure_placement
function init_placement {
# NOTE(mnaser): For some reason, DevStack configures Nova to actually
# use the placement service user to talk to it. Let's
# create the user for now and drop it later.
create_service_user "placement" "admin"
}
export -f init_placement
function install_placement {
echo noop
}
export -f install_placement
function start_placement {
echo noop
}
export -f start_placement
function stop_placement {
echo noop
}
export -f stop_placement

View File

@ -21,4 +21,5 @@ source $DEST/openstack-operator/devstack/lib/barbican
source $DEST/openstack-operator/devstack/lib/glance source $DEST/openstack-operator/devstack/lib/glance
source $DEST/openstack-operator/devstack/lib/horizon source $DEST/openstack-operator/devstack/lib/horizon
source $DEST/openstack-operator/devstack/lib/keystone source $DEST/openstack-operator/devstack/lib/keystone
source $DEST/openstack-operator/devstack/lib/placement
source $DEST/openstack-operator/devstack/lib/rpc_backend source $DEST/openstack-operator/devstack/lib/rpc_backend

View File

@ -0,0 +1,21 @@
# Copyright (c) 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM vexxhost/python-builder as builder
FROM vexxhost/python-base AS placement
COPY placement-api /usr/local/bin/placement-api
EXPOSE 8780
ENV UWSGI_HTTP_SOCKET=:8780 UWSGI_WSGI_FILE=/usr/local/bin/placement-api
CMD ["/usr/local/bin/uwsgi", "--ini", "/etc/uwsgi/uwsgi.ini"]

View File

@ -0,0 +1,2 @@
gcc [compile]
libc-dev [compile]

View File

@ -0,0 +1 @@
--constraint https://releases.openstack.org/constraints/upper/ussuri

32
images/placement/placement-api Executable file
View File

@ -0,0 +1,32 @@
#!/usr/local/bin/python
# Copyright (c) 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pkg_resources
import sentry_sdk
from placement.wsgi import init_application
from sentry_sdk.integrations import wsgi
VERSION = pkg_resources.get_distribution("openstack-placement").version
sentry_sdk.init(
release="placement@%s" % VERSION,
traces_sample_rate=0.1
)
application = init_application()
application = wsgi.SentryWsgiMiddleware(application)

View File

@ -0,0 +1,5 @@
uWSGI
PyMySQL
python-memcached
sentry-sdk
git+https://opendev.org/openstack/placement@stable/ussuri

View File

@ -35,6 +35,7 @@ from openstack_operator import horizon
from openstack_operator import keystone from openstack_operator import keystone
from openstack_operator import libvirtd_exporter from openstack_operator import libvirtd_exporter
from openstack_operator import magnum from openstack_operator import magnum
from openstack_operator import placement
from openstack_operator import utils from openstack_operator import utils
@ -91,6 +92,9 @@ def deploy(name, namespace, new, **_):
if "keystone" in config: if "keystone" in config:
spec = set_service_config(config, "keystone") spec = set_service_config(config, "keystone")
keystone.create_or_resume("keystone", spec) keystone.create_or_resume("keystone", spec)
if "placement" in config:
spec = set_service_config(config, "placement")
placement.create_or_resume("placement", spec)
if "horizon" in config: if "horizon" in config:
spec = set_service_config(config, "horizon") spec = set_service_config(config, "horizon")
horizon.create_or_resume("horizon", spec) horizon.create_or_resume("horizon", spec)

View File

@ -0,0 +1,70 @@
# Copyright 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Placement service
This code takes care of doing the operations of the OpenStack Placement API
service.
"""
from openstack_operator import database
from openstack_operator import identity
from openstack_operator import utils
MEMCACHED = True
def create_or_resume(name, spec, **_):
"""Create and re-sync a placement instance
This function is called when a new resource is created but also when we
start the service up for the first time.
"""
# deploy mysql for placement
if "mysql" not in spec:
database.ensure_mysql_cluster("placement", {})
else:
database.ensure_mysql_cluster("placement", spec["mysql"])
# deploy placement api
utils.create_or_update('placement/daemonset.yml.j2', spec=spec)
utils.create_or_update('placement/service.yml.j2', spec=spec)
# Create application credential
identity.ensure_application_credential(name="placement")
url = None
if "ingress" in spec:
utils.create_or_update('placement/ingress.yml.j2',
name=name, spec=spec)
url = spec["ingress"]["host"]
if "endpoint" not in spec:
spec["endpoint"] = True
if spec["endpoint"]:
identity.ensure_service(name="placement", service_type="placement",
url=url, desc="Placement Service")
def update(name, spec, **_):
"""Update a placement
This function updates the deployment for placement if there are any
changes that happen within it.
"""
if "ingress" in spec:
utils.create_or_update('placement/ingress.yml.j2',
name=name, spec=spec)

View File

@ -0,0 +1,95 @@
---
# Copyright 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: placement
namespace: openstack
labels:
{{ labels("placement") | indent(4) }}
spec:
updateStrategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
selector:
matchLabels:
{{ labels("placement") | indent(6) }}
template:
metadata:
labels:
{{ labels("placement") | indent(8) }}
spec:
automountServiceAccountToken: false
initContainers:
- name: db-sync
image: vexxhost/placement:latest
imagePullPolicy: Always
command:
- placement-manage
- db
- sync
volumeMounts:
- mountPath: /etc/placement
name: config
containers:
- name: placement
image: vexxhost/placement:latest
imagePullPolicy: Always
env:
{% if 'sentryDSN' in spec %}
- name: SENTRY_DSN
value: {{ spec.sentryDSN }}
{% endif %}
ports:
- name: placement
protocol: TCP
containerPort: 8780
livenessProbe:
tcpSocket:
port: placement
readinessProbe:
tcpSocket:
port: placement
securityContext:
runAsUser: 1001
volumeMounts:
- name: ceph
mountPath: /etc/ceph
- name: config
mountPath: /etc/placement
- name: uwsgi-config
mountPath: /etc/uwsgi
volumes:
- name: ceph
secret:
secretName: ceph-config
- name: config
secret:
secretName: placement-config
- name: uwsgi-config
configMap:
defaultMode: 420
name: uwsgi-default
nodeSelector:
node-role.kubernetes.io/master: ""
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
{% if 'hostAliases' in spec %}
hostAliases:
{{ spec.hostAliases | to_yaml | indent(8) }}
{% endif %}

View File

@ -0,0 +1,55 @@
---
# Copyright 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: placement
namespace: openstack
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
certmanager.k8s.io/cluster-issuer: "letsencrypt-prod"
spec:
{% if spec.ingress.host is defined %}
rules:
- host: {{ spec.ingress.host }}
http:
paths:
- path: /
backend:
serviceName: placement
servicePort: 80
tls:
- hosts:
- {{ spec.ingress.host }}
secretName: placement-tls
{% else %}
rules:
{% for v in spec.ingress %}
- host: {{ v.host }}
http:
paths:
- path: /
backend:
serviceName: placement
servicePort: 80
{% endfor %}
tls:
- hosts:
{% for v in spec.ingress %}
- {{ v.host }}
{% endfor %}
secretName: placement-tls
{% endif %}

View File

@ -0,0 +1,28 @@
---
# Copyright 2020 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: placement
namespace: openstack
spec:
ports:
- name: placement
port: 80
protocol: TCP
targetPort: placement
selector:
{{ labels("placement") | indent(4) }}

View File

@ -60,57 +60,61 @@
jobs: jobs:
- openstack-operator:functional: - openstack-operator:functional:
dependencies: dependencies:
- name: openstack-operator:images:build:mcrouter-exporter - name: openstack-operator:images:build:heat
soft: true soft: true
- name: openstack-operator:images:build:horizon - name: openstack-operator:images:build:barbican
soft: true
- name: openstack-operator:images:build:magnum
soft: true
- name: openstack-operator:images:build:glance
soft: true
- name: openstack-operator:images:build:rabbitmq
soft: true soft: true
- name: openstack-operator:images:build:ceilometer - name: openstack-operator:images:build:ceilometer
soft: true soft: true
- name: openstack-operator:images:build:memcached-exporter - name: openstack-operator:images:build:rabbitmq
soft: true
- name: openstack-operator:images:build:memcached
soft: true soft: true
- name: openstack-operator:images:build:keystone - name: openstack-operator:images:build:keystone
soft: true soft: true
- name: openstack-operator:images:build:horizon
soft: true
- name: openstack-operator:images:build:memcached
soft: true
- name: openstack-operator:images:build:mcrouter - name: openstack-operator:images:build:mcrouter
soft: true soft: true
- openstack-operator:images:build:openstack-operator - openstack-operator:images:build:openstack-operator
- name: openstack-operator:images:build:barbican - name: openstack-operator:images:build:glance
soft: true soft: true
- name: openstack-operator:images:build:heat - name: openstack-operator:images:build:mcrouter-exporter
soft: true
- name: openstack-operator:images:build:memcached-exporter
soft: true
- name: openstack-operator:images:build:magnum
soft: true
- name: openstack-operator:images:build:placement
soft: true soft: true
gate: gate:
jobs: jobs:
- openstack-operator:functional: - openstack-operator:functional:
dependencies: dependencies:
- name: openstack-operator:images:upload:mcrouter-exporter - name: openstack-operator:images:upload:heat
soft: true soft: true
- name: openstack-operator:images:upload:horizon - name: openstack-operator:images:upload:barbican
soft: true
- name: openstack-operator:images:upload:magnum
soft: true
- name: openstack-operator:images:upload:glance
soft: true
- name: openstack-operator:images:upload:rabbitmq
soft: true soft: true
- name: openstack-operator:images:upload:ceilometer - name: openstack-operator:images:upload:ceilometer
soft: true soft: true
- name: openstack-operator:images:upload:memcached-exporter - name: openstack-operator:images:upload:rabbitmq
soft: true
- name: openstack-operator:images:upload:memcached
soft: true soft: true
- name: openstack-operator:images:upload:keystone - name: openstack-operator:images:upload:keystone
soft: true soft: true
- name: openstack-operator:images:upload:horizon
soft: true
- name: openstack-operator:images:upload:memcached
soft: true
- name: openstack-operator:images:upload:mcrouter - name: openstack-operator:images:upload:mcrouter
soft: true soft: true
- openstack-operator:images:upload:openstack-operator - openstack-operator:images:upload:openstack-operator
- name: openstack-operator:images:upload:barbican - name: openstack-operator:images:upload:glance
soft: true soft: true
- name: openstack-operator:images:upload:heat - name: openstack-operator:images:upload:mcrouter-exporter
soft: true
- name: openstack-operator:images:upload:memcached-exporter
soft: true
- name: openstack-operator:images:upload:magnum
soft: true
- name: openstack-operator:images:upload:placement
soft: true soft: true

View File

@ -0,0 +1,42 @@
- job:
name: openstack-operator:images:build:placement
parent: vexxhost-build-docker-image
provides: openstack-operator:image:placement
nodeset: &id001
nodes:
- name: ubuntu-bionic
label: ubuntu-bionic-vexxhost
vars: &id002
docker_images:
- context: images/placement
repository: vexxhost/placement
target: placement
dependencies:
- openstack-operator:images:build:openstack-operator
files: &id003
- ^images/placement/.*
- job:
name: openstack-operator:images:upload:placement
parent: vexxhost-upload-docker-image
provides: openstack-operator:image:placement
nodeset: *id001
vars: *id002
dependencies:
- openstack-operator:images:upload:openstack-operator
files: *id003
- job:
name: openstack-operator:images:promote:placement
parent: vexxhost-promote-docker-image
nodeset: *id001
vars: *id002
files: *id003
- project:
check:
jobs:
- openstack-operator:images:build:placement
gate:
jobs:
- openstack-operator:images:upload:placement
promote:
jobs:
- openstack-operator:images:promote:placement