128 lines
5.0 KiB
Python
128 lines
5.0 KiB
Python
# Copyright 2018 Red Hat
|
|
#
|
|
# 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 logging
|
|
import urllib3
|
|
import time
|
|
|
|
from kubernetes.client.api import CustomObjectsApi
|
|
|
|
from nodepool.driver.utils_k8s import get_client
|
|
from nodepool.driver.utils import NodeDeleter
|
|
from nodepool.driver.openshift.provider import OpenshiftProvider
|
|
from nodepool.driver.openshiftvms import handler
|
|
|
|
urllib3.disable_warnings()
|
|
|
|
|
|
class OpenshiftVmsProvider(OpenshiftProvider):
|
|
log = logging.getLogger("nodepool.driver.openshiftvms."
|
|
"OpenshiftVmsProvider")
|
|
|
|
def __init__(self, provider, *args):
|
|
self.provider = provider
|
|
self.ready = False
|
|
_, _, self.k8s_client, self.custom_client = get_client(
|
|
self.log, provider.context, CustomObjectsApi)
|
|
self.vm_names = set()
|
|
for pool in provider.pools.values():
|
|
self.vm_names.update(pool.labels.keys())
|
|
|
|
def start(self, zk_conn):
|
|
self.log.debug("Starting")
|
|
self._zk = zk_conn
|
|
if self.ready or not self.custom_client:
|
|
return
|
|
self.ready = True
|
|
|
|
def listNodes(self):
|
|
servers = []
|
|
|
|
class FakeServer:
|
|
def __init__(self, pool, vm, provider, valid_names):
|
|
# self.id = "%s-%s" % (pool, vm['metadata']['name'])
|
|
self.id = vm['metadata']['name']
|
|
self.name = self.id
|
|
self.metadata = {}
|
|
|
|
if [True for valid_name in valid_names
|
|
if vm['metadata']['name'].startswith("%s-" % valid_name)]:
|
|
node_id = vm['metadata']['name'].split('-')[-1]
|
|
try:
|
|
# Make sure last component of name is an id
|
|
int(node_id)
|
|
self.metadata['nodepool_provider_name'] = provider
|
|
self.metadata['nodepool_node_id'] = node_id
|
|
except Exception:
|
|
# Probably not a managed project, let's skip metadata
|
|
pass
|
|
|
|
def get(self, name, default=None):
|
|
return getattr(self, name, default)
|
|
|
|
if self.ready:
|
|
for pool in self.provider.pools.keys():
|
|
for vm in self.custom_client.list_namespaced_custom_object(group='kubevirt.io', plural='virtualmachines', version='v1', namespace=pool)['items']:
|
|
servers.append(FakeServer(
|
|
pool, vm, self.provider.name, self.vm_names))
|
|
return servers
|
|
|
|
def getProjectVmName(self, server_id):
|
|
for pool in self.provider.pools.keys():
|
|
if server_id.startswith("%s-" % pool):
|
|
vm_name = server_id[len(pool) + 1:]
|
|
return pool, vm_name
|
|
return None, None
|
|
|
|
def startNodeCleanup(self, node):
|
|
t = NodeDeleter(self._zk, self, node)
|
|
t.start()
|
|
return t
|
|
|
|
def cleanupNode(self, server_id):
|
|
if not self.ready:
|
|
return
|
|
# Look for pool name
|
|
project_name, vm_name = self.getProjectVmName(server_id)
|
|
if not project_name:
|
|
self.log.exception("%s: unknown pool" % server_id)
|
|
return
|
|
self.log.debug("%s: removing vm" % vm_name)
|
|
try:
|
|
self.custom_client.delete_namespaced_custom_object(group='kubevirt.io', plural='virtualmachines', version='v1', name=vm_name, namespace=project_name)
|
|
self.log.info("%s: vm removed" % server_id)
|
|
except Exception:
|
|
# TODO: implement better exception handling
|
|
self.log.exception("Couldn't remove vm %s" % server_id)
|
|
self.log.debug("%s: removing service" % vm_name)
|
|
try:
|
|
service = self.k8s_client.list_namespaced_service(project_name, label_selector="vm={}".format(vm_name)).items[0]
|
|
service_name = service.metadata.name
|
|
self.k8s_client.delete_namespaced_service(service_name, project_name)
|
|
self.log.info("%s: service removed" % service_name)
|
|
except Exception:
|
|
self.log.exception("Couldn't remove service %s" % service_name)
|
|
|
|
def waitForNodeCleanup(self, server_id):
|
|
project_name, vm_name = self.getProjectVmName(server_id)
|
|
for retry in range(300):
|
|
try:
|
|
self.custom_client.get_namespaced_custom_object(group='kubevirt.io', plural='virtualmachines', version='v1', name=vm_name, namespace=project_name)
|
|
except Exception:
|
|
break
|
|
time.sleep(1)
|
|
|
|
def getRequestHandler(self, poolworker, request):
|
|
return handler.OpenshiftVmRequestHandler(poolworker, request)
|