コード例 #1
0
ファイル: anarchyruntime.py プロジェクト: darthlukan/anarchy
 def get_vars(self, obj):
     if not obj:
         return
     merged_vars = copy.deepcopy(obj.vars)
     for var_secret in obj.var_secrets:
         secret_name = var_secret.get('name', None)
         secret_namespace = var_secret.get('namespace', None)
         if secret_name:
             try:
                 secret_data = self.get_secret_data(secret_name,
                                                    secret_namespace)
                 var_name = var_secret.get('var', None)
                 if var_name:
                     deep_update(merged_vars, {var_name: secret_data})
                 else:
                     deep_update(merged_vars, secret_data)
             except kubernetes.client.rest.ApiException as e:
                 if e.status != 404:
                     raise
                 operator_logger.warning(
                     'varSecrets references missing secret, %s',
                     secret_name)
         else:
             operator_logger.warning('varSecrets has entry with no name')
     return merged_vars
コード例 #2
0
    def patch(self, patch, runtime):
        '''
        Patch AnarchySubject resource and status.
        '''
        resource_patch = {}
        result = None

        if 'metadata' in patch or 'spec' in patch:
            if 'metadata' in patch:
                resource_patch['metadata'] = patch['metadata']
            if 'spec' in patch:
                resource_patch['spec'] = patch['spec']
                deep_update(self.spec, patch['spec'])
            if patch.get('skip_update_processing', False):
                # Set spec-sha256 annotation to indicate skip processing
                if 'metadata' not in resource_patch:
                    resource_patch['metadata'] = {}
                if 'annotations' not in resource_patch['metadata']:
                    resource_patch['metadata']['annotations'] = {}
                resource_patch['metadata']['annotations'][
                    runtime.operator_domain +
                    '/spec-sha256'] = self.spec_sha256

            result = runtime.custom_objects_api.patch_namespaced_custom_object(
                runtime.operator_domain, runtime.api_version,
                runtime.operator_namespace, 'anarchysubjects', self.name,
                resource_patch)
        if 'status' in patch:
            result = runtime.custom_objects_api.patch_namespaced_custom_object_status(
                runtime.operator_domain, runtime.api_version,
                runtime.operator_namespace, 'anarchysubjects', self.name,
                {'status': patch['status']})
        return result
コード例 #3
0
    def manage_runner_pods(self, runtime):
        '''
        Manage Pods for AnarchyRunner
        '''

        #deployment_name = 'anarchy-runner-' + self.name
        #deployment_namespace = self.pod_namespace or runtime.operator_namespace

        pod_template = copy.deepcopy(self.pod_template)
        if 'metadata' not in pod_template:
            pod_template['metadata'] = {}
        if 'labels' not in pod_template['metadata']:
            pod_template['metadata']['labels'] = {}
        if 'spec' not in pod_template:
            pod_template['spec'] = {}
        if 'serviceAccountName' not in pod_template['spec']:
            pod_template['spec'][
                'serviceAccountName'] = self.service_account_name(runtime)
        if not 'containers' in pod_template['spec']:
            pod_template['spec']['containers'] = [{}]
        pod_template['metadata']['generateName'] = '{}-runner-{}-'.format(
            runtime.anarchy_service_name, self.name)
        pod_template['metadata']['labels'][runtime.runner_label] = self.name
        pod_template['metadata']['ownerReferences'] = [{
            'apiVersion': runtime.api_group_version,
            'controller': True,
            'kind': 'AnarchyRunner',
            'name': self.name,
            'uid': self.uid,
        }]

        runner_container = pod_template['spec']['containers'][0]
        if 'name' not in runner_container:
            runner_container['name'] = 'runner'
        if not runner_container.get('image'):
            image = os.environ.get('RUNNER_IMAGE', '')
            if image != '':
                runner_container['image'] = image
            else:
                runner_container['image'] = runtime.pod.spec.containers[
                    0].image
        if not 'env' in runner_container:
            runner_container['env'] = []
        runner_container['env'].extend([{
            'name': 'ANARCHY_COMPONENT',
            'value': 'runner'
        }, {
            'name':
            'ANARCHY_URL',
            'value':
            'http://{}.{}.svc:5000'.format(runtime.anarchy_service_name,
                                           runtime.operator_namespace)
        }, {
            'name': 'ANARCHY_DOMAIN',
            'value': runtime.operator_domain
        }, {
            'name': 'POD_NAME',
            'valueFrom': {
                'fieldRef': {
                    'apiVersion': 'v1',
                    'fieldPath': 'metadata.name'
                }
            }
        }, {
            'name': 'RUNNER_NAME',
            'value': self.name
        }, {
            'name': 'RUNNER_TOKEN',
            'value': self.runner_token
        }])

        pod_count = 0
        for name, pod in self.pods.items():
            pod_dict = runtime.api_client.sanitize_for_serialization(pod)
            if pod.metadata.labels.get(
                    runtime.runner_terminating_label) == 'true':
                # Ignore pod marked for termination
                pass
            elif pod_dict == deep_update(copy.deepcopy(pod_dict),
                                         pod_template):
                pod_count += 1
            else:
                # Pod does not match template, need to terminate pod
                runtime.core_v1_api.patch_namespaced_pod(
                    pod.metadata.name, pod.metadata.namespace, {
                        'metadata': {
                            'labels': {
                                runtime.runner_terminating_label: 'true'
                            }
                        }
                    })
                operator_logger.info(
                    'Labeled AnarchyRunner %s runner pod %s for termination',
                    self.name, pod.metadata.name)

        for i in range(self.min_replicas - pod_count):
            pod = None
            while pod == None:
                try:
                    pod = runtime.core_v1_api.create_namespaced_pod(
                        runtime.operator_namespace, pod_template)
                    break
                except kubernetes.client.rest.ApiException as e:
                    if 'retry after the token is automatically created' in json.loads(
                            e.body).get('message', ''):
                        time.sleep(1)
                    else:
                        raise
            operator_logger.info("Started runner pod %s for AnarchyRunner %s",
                                 pod.metadata.name, self.name)
コード例 #4
0
ファイル: anarchyrunner.py プロジェクト: mikecali/anarchy
    def manage_runner_deployment(self, runtime):
        """Manage Deployment for AnarchyRunner pods"""
        self.manage_runner_service_account(runtime)
        deployment_name = 'anarchy-runner-' + self.name
        deployment_namespace = self.pod_namespace or runtime.operator_namespace
        deployment_definition = {
            'apiVersion': 'apps/v1',
            'kind': 'Deployment',
            'metadata': {
                'name': deployment_name,
                'namespace': deployment_namespace,
                'labels': {
                    runtime.runner_label: self.name
                }
            },
            'spec': {
                'selector': {
                    'matchLabels': {
                        runtime.runner_label: self.name
                    }
                },
                'template': {
                    'metadata': {
                        'labels': {
                            runtime.runner_label: self.name
                        }
                    },
                    'spec': {
                        'serviceAccountName':
                        self.service_account_name,
                        'containers': [{
                            'name':
                            'runner',
                            'env': [{
                                'name':
                                'ANARCHY_URL',
                                'value':
                                'http://{}.{}.svc:5000'.format(
                                    runtime.anarchy_service,
                                    runtime.operator_namespace)
                            }, {
                                'name': 'OPERATOR_DOMAIN',
                                'value': runtime.operator_domain
                            }, {
                                'name': 'POD_NAME',
                                'valueFrom': {
                                    'fieldRef': {
                                        'apiVersion': 'v1',
                                        'fieldPath': 'metadata.name'
                                    }
                                }
                            }, {
                                'name': 'RUNNER_NAME',
                                'value': self.name
                            }, {
                                'name': 'RUNNER_TOKEN',
                                'value': self.runner_token
                            }],
                            'image':
                            self.image,
                            'imagePullPolicy':
                            self.image_pull_policy,
                            'resources':
                            self.resources
                        }]
                    }
                }
            }
        }

        deployment = None
        try:
            deployment = runtime.custom_objects_api.get_namespaced_custom_object(
                'apps', 'v1', deployment_namespace, 'deployments',
                deployment_name)
        except kubernetes.client.rest.ApiException as e:
            if e.status != 404:
                raise

        if deployment:
            updated_deployment = copy.deepcopy(deployment)
            deep_update(updated_deployment, deployment_definition)
            if updated_deployment['spec']['replicas'] < self.min_replicas:
                updated_deployment['spec']['replicas'] = self.min_replicas
            if updated_deployment['spec']['replicas'] > self.max_replicas:
                updated_deployment['spec']['replicas'] = self.max_replicas
            # FIXME - Scale based on queue size
            if deployment != updated_deployment:
                runtime.custom_objects_api.replace_namespaced_custom_object(
                    'apps', 'v1', deployment_namespace, 'deployments',
                    deployment_name, updated_deployment)
        else:
            deployment_definition['spec']['replicas'] = self.min_replicas
            runtime.custom_objects_api.create_namespaced_custom_object(
                'apps', 'v1', deployment_namespace, 'deployments',
                deployment_definition)