Beispiel #1
0
    def _start_instance(self, resource_handler, node_def):
        """
        Start the VM instance.

        :param dict node_def: The resolved node definition to use.

        :Remark: This is a "wet method", the VM will not be started
            if the instance is in debug mode (``dry_run``).
        """
        image_id = node_def['resource']['image_id']
        flavor_name = node_def['resource']['flavor_name']
        context = node_def.get('context', None)
        sec_groups = node_def['resource'].get('security_groups', None)
        key_name = node_def['resource'].get('key_name', None)
        server_name = node_def['resource'].get('server_name',
                                               unique_vmname(node_def))
        network_id = node_def['resource'].get('network_id', None)
        nics = None
        if network_id is not None:
            nics = [{"net-id": network_id, "v4-fixed-ip": ''}]
        log.debug(
            "[%s] Creating new server using image ID %r and flavor name %r",
            resource_handler.name, image_id, flavor_name)
        try:
            server = None
            KBinterrupt = False
            with GracefulInterruptHandler() as h:
                log.debug('Server creation started for node %s...',
                          node_def['node_id'])
                server = self.conn.servers.create(server_name,
                                                  image_id,
                                                  flavor_name,
                                                  security_groups=sec_groups,
                                                  key_name=key_name,
                                                  userdata=context,
                                                  nics=nics)
                KBinterrupt = h.interrupted
                log.debug('Server creation finished for node %s: server: %r',
                          node_def['node_id'], server)
            if KBinterrupt:
                log.debug(
                    'Keyboard interrupt detected while VM was being created!')
                raise KeyboardInterrupt
        except KeyboardInterrupt:
            log.debug('Interrupting node creation!')
            if server is not None:
                log.debug('Rolling back...')
                try:
                    self.conn.servers.delete(server)
                except Exception as ex:
                    raise NodeCreationError(None, str(ex))
            raise
        except Exception as ex:
            raise NodeCreationError(None, str(ex))
        return server
Beispiel #2
0
    def _create_server(self, resource_handler, drv_id):
        """
        Start the VM instance.

        :Remark: This is a "wet method", the VM will not be started
            if the instance is in debug mode (``dry_run``).
        """
        descr = self.resolved_node_definition['resource']['description']
        context = self.resolved_node_definition.get('context', None)
        if context is not None:
            descr['meta'] = {
                'base64_fields': 'cloudinit-user-data',
                'cloudinit-user-data': base64.b64encode(context.encode('utf-8')).decode('utf-8')
            }
        if 'vnc_password' not in descr:
            descr['vnc_password'] = self.resolved_node_definition.get('node_id', "occopus")
        if 'name' not in descr:
            descr['name'] = unique_vmname(self.resolved_node_definition)
        if 'drivers' not in descr:
            descr['drives'] = []
        nd = {
            "boot_order": 1,
            "dev_channel": "0:0",
            "device": "virtio",
            "drive": str(drv_id)
        }
        descr['drives'].append(nd)
        json_data = {}
        json_data['objects'] = [descr]
        r = requests.post(resource_handler.endpoint + '/servers/',
            auth=get_auth(resource_handler.auth_data), json=json_data)
        retry=max_number_of_api_call_retries
        while r.status_code not in [201] and retry>0:
          error_msg = '[{0}] Failed to create server! HTTP response code/message: {1}/{2}. Server response: {3}.'.format(
                        resource_handler.name, r.status_code,
                        http.client.responses.get(r.status_code,"(undefined http code returned by CloudSigma API)"), r.text)
          log.debug(error_msg)
          log.debug('Returned json: {0}'.format(r.json().dumps()))
          log.debug('Retrying in {0} seconds...  {1} attempts left.'.format(wait_time_between_api_call_retries,retry))
          time.sleep(wait_time_between_api_call_retries)
          retry-=1
          r = requests.post(resource_handler.endpoint + '/servers/',
              auth=get_auth(resource_handler.auth_data), json=json_data)
        if r.status_code != 201:
            error_msg = '[{0}] Failed to create server! HTTP response code/message: {1}/{2}. Server response: {3}.'.format(
                        resource_handler.name, r.status_code,
                        http.client.responses.get(r.status_code,"(undefined http code returned by CloudSigma API)"), r.text)
            return None, error_msg
        srv_uuid = r.json()['objects'][0]['uuid']
        log.debug('[%s] Created server\'s UUID is: %s', resource_handler.name, srv_uuid)
        return srv_uuid, ""
Beispiel #3
0
 def _start_instance(self, resource_handler):
     log.debug('Starting Azure VM')
     self.resource_client.resource_groups.create_or_update(
         self.res['resource_group'], {'location': self.res['location']})
     nic = self._create_nic()
     vm_name = unique_vmname(self.node_def)
     resolved_context = self.node_def.get("context")
     if resolved_context == "":
         resolved_context = None
     customdata = base64.b64encode(resolved_context.encode('utf-8')).decode(
         'utf-8') if resolved_context else None
     vm = self._create_vm(nic, vm_name, customdata)
     log.debug('%r', vm)
     return vm_name
Beispiel #4
0
 def _create_vm_parameters(self, nic_id, customdata):
     """Create the VM parameters structure.
     """
     server_name = self.node_def['resource'].get(
         'server_name', unique_vmname(self.node_def))
     d = {
         'location': self.res['location'],
         'os_profile': {
             'computer_name': server_name,
             'admin_username': self.res['username'],
             'customData': customdata if customdata != None else ''
         },
         'hardware_profile': {
             'vm_size': self.res['vm_size']
         },
         'storage_profile': {
             'image_reference': {
                 'publisher': self.res['publisher'],
                 'offer': self.res['offer'],
                 'sku': self.res['sku'],
                 'version': self.res['version']
             },
         },
         'network_profile': {
             'network_interfaces': [{
                 'id': nic_id,
             }]
         },
     }
     if 'password' in self.res:
         d['os_profile']['admin_password'] = self.res['password']
     else:
         d['os_profile']['linux_configuration'] = {
             'disable_password_authentication': True,
             'ssh': {
                 'public_keys': [{
                     'path':
                     '/home/{}/.ssh/authorized_keys'.format(
                         self.res['username']),
                     'key_data':
                     self.res['ssh_key_data']
                 }]
             }
         }
     return d
Beispiel #5
0
    def _create_server(self, resource_handler, drv_id):
        """
        Start the VM instance.

        :Remark: This is a "wet method", the VM will not be started
            if the instance is in debug mode (``dry_run``).
        """
        descr = self.resolved_node_definition['resource']['description']
        context = self.resolved_node_definition.get('context', None)
        if context is not None:
            descr['meta'] = {
                'base64_fields': 'cloudinit-user-data',
                'cloudinit-user-data': base64.b64encode(context)
            }
        if 'vnc_password' not in descr:
            descr['vnc_password'] = self.resolved_node_definition.get(
                'node_id', "occopus")
        if 'name' not in descr:
            descr['name'] = unique_vmname(self.resolved_node_definition)
        if 'drivers' not in descr:
            descr['drives'] = []
        nd = {
            "boot_order": 1,
            "dev_channel": "0:0",
            "device": "virtio",
            "drive": str(drv_id)
        }
        descr['drives'].append(nd)
        json_data = {}
        json_data['objects'] = [descr]
        r = requests.post(resource_handler.endpoint + '/servers/',
                          auth=get_auth(resource_handler.auth_data),
                          json=json_data)
        if r.status_code != 201:
            error_msg = '[{0}] Failed to create server! HTTP response code/message: {1}/{2}. Server response: {3}.'.format(
                resource_handler.name, r.status_code,
                httplib.responses[r.status_code], r.text)
            return None, error_msg
        srv_uuid = r.json()['objects'][0]['uuid']
        log.debug('[%s] Created server\'s UUID is: %s', resource_handler.name,
                  srv_uuid)
        return srv_uuid, ""
Beispiel #6
0
    def _start_container(self, resource_handler):
        log.debug('Starting Azure ACI')
        location = self.res['location'].lower()
        self.resource_client.resource_groups.create_or_update(
            self.res['resource_group'], {'location': self.res['location']})
        container_group_name = unique_vmname(self.node_def)
        network_type = self.res['network_type']
        network_profile = None
        if 'gpu_type' in self.res:
            count = self.res['gpu_count'] if 'gpu_count' in self.res else 1
            gpu = GpuResource(count=count, sku=self.res['gpu_type'])
            container_resource_requests = ResourceRequests(
                memory_in_gb=self.res['memory'],
                cpu=self.res['cpu_cores'],
                gpu=gpu)
        else:
            container_resource_requests = ResourceRequests(
                memory_in_gb=self.res['memory'], cpu=self.res['cpu_cores'])
        container_resource_requirements = ResourceRequirements(
            requests=container_resource_requests)
        ports = []
        ipports = []
        for porte in self.res.get('ports', []):
            port = porte
            protocol = 'TCP'
            if isinstance(porte, str) and '/' in porte:
                (port, protocol) = port.split('/')
                port = int(port)
            ports.append(ContainerPort(port=port, protocol=protocol))
            ipports.append(Port(protocol=protocol, port=port))
        environment = []
        if network_type.lower() == 'public':
            pubip_var = EnvironmentVariable(name='_OCCOPUS_ALLOCATED_FQDN',
                                            value='%s.%s.azurecontainer.io' %
                                            (container_group_name, location))
            environment.append(pubip_var)
        for env in self.env:
            edata = env.split('=', 1)
            if len(edata) != 2: continue
            env_var = EnvironmentVariable(name=edata[0], value=edata[1])
            environment.append(env_var)
        container = Container(
            name=container_group_name,
            image=self.res['image'],
            resources=container_resource_requirements,
            ports=ports,
            command=self.command if self.command is not None else None,
            environment_variables=environment)
        if network_type.lower() == 'public':
            group_ip_address = IpAddress(ports=ipports,
                                         dns_name_label=container_group_name,
                                         type='Public')
            self.vnet_name = None
        elif network_type.lower() == 'private':
            vnet_name = unique_vmname(self.node_def) + '-vnet' if self.res.get(
                'vnet_name', None) == None else self.res['vnet_name']
            self.vnet_name = vnet_name
            subnet_name = unique_vmname(
                self.node_def) + '-subnet' if self.res.get(
                    'subnet_name', None) == None else self.res['subnet_name']
            network_profile_name = unique_vmname(self.node_def) + '-netprofile'
            if self.res.get('vnet_name', None) == None:
                log.debug('Creating vnet')
                async_vnet_creation = self.network_client.virtual_networks.create_or_update(
                    self.res['resource_group'], vnet_name, {
                        'location': location,
                        'address_space': {
                            'address_prefixes': ['10.0.0.0/16']
                        }
                    })
                async_vnet_creation.wait()
                self.created_resources['virtual_network'] = vnet_name
                log.debug('Created vnet')
            if self.res.get('subnet_name', None) == None:
                # Create Subnet
                log.debug('Creating Subnet')
                aci_delegation_service_name = "Microsoft.ContainerInstance/containerGroups"
                aci_delegation = Delegation(
                    name=aci_delegation_service_name,
                    service_name=aci_delegation_service_name)
                subnet = Subnet(name=subnet_name,
                                location=location,
                                address_prefix='10.0.0.0/24',
                                delegations=[aci_delegation])
                subnet_info = self.network_client.subnets.create_or_update(
                    self.res['resource_group'], vnet_name, subnet_name,
                    subnet).result()
                self.created_resources['subnet'] = subnet_name
                log.debug('Creatied Subnet')
            else:
                subnet_info = self.network_client.subnets.get(
                    self.res['resource_group'], vnet_name, subnet_name)
            default_network_profile_name = "aci-network-profile-{}-{}".format(
                vnet_name, subnet_name)
            network_profile_ops = self.network_client.network_profiles
            network_profile = NetworkProfile(
                name=default_network_profile_name,
                location=location,
                container_network_interface_configurations=[
                    ContainerNetworkInterfaceConfiguration(
                        name="eth0",
                        ip_configurations=[
                            IPConfigurationProfile(name="ipconfigprofile",
                                                   subnet=subnet_info)
                        ])
                ])
            network_profile = network_profile_ops.create_or_update(
                self.res['resource_group'], network_profile_name,
                network_profile).result()
            group_ip_address = IpAddress(ports=ipports, type='Private')
        else:
            errormsg = '[{0}] Network type "{1}" is not supported. Please use either "Public" or "Private"'.format(
                resource_handler.name, network_type)
            log.debug(errormsg)
            raise NodeCreationError(None, errormsg)

        cg_network_profile = None
        if network_profile:
            cg_network_profile = ContainerGroupNetworkProfile(
                id=network_profile.id)
            self.created_resources['network_profile'] = network_profile_name

        group = ContainerGroup(location=location,
                               containers=[container],
                               os_type=self.res['os_type'],
                               ip_address=group_ip_address,
                               network_profile=cg_network_profile)
        # Create the container group
        self.aci_client.container_groups.create_or_update(
            self.res['resource_group'], container_group_name, group)
        return container_group_name
Beispiel #7
0
    def _create_nic(self):
        # Create VNet
        vnet_name = unique_vmname(self.node_def) + '-vnet' if self.res.get(
            'vnet_name', None) == None else self.res['vnet_name']
        subnet_name = unique_vmname(self.node_def) + '-subnet' if self.res.get(
            'subnet_name', None) == None else self.res['subnet_name']
        nic_name = unique_vmname(self.node_def) + '-nic'
        self.vnet_name = vnet_name

        if self.res.get('vnet_name', None) == None:
            log.debug('Creating vnet')
            async_vnet_creation = self.network_client.virtual_networks.create_or_update(
                self.res['resource_group'], vnet_name, {
                    'location': self.res['location'],
                    'address_space': {
                        'address_prefixes': ['10.0.0.0/16']
                    }
                })
            async_vnet_creation.wait()
            self.created_resources['virtual_network'] = vnet_name

        if self.res.get('subnet_name', None) == None:
            # Create Subnet
            log.debug('Creating Subnet')
            async_subnet_creation = self.network_client.subnets.create_or_update(
                self.res['resource_group'], vnet_name, subnet_name,
                {'address_prefix': '10.0.0.0/24'})
            subnet_info = async_subnet_creation.result()
            self.created_resources['subnet'] = subnet_name
        else:
            subnet_info = self.network_client.subnets.get(
                self.res['resource_group'], vnet_name, subnet_name)

        pubip_info = None
        if self.res.get('public_ip_needed') == True:
            pubip_name = unique_vmname(self.node_def) + '-pubip'
            async_pubip_creation = self.network_client.public_ip_addresses.create_or_update(
                self.res['resource_group'], pubip_name, {
                    'location': self.res['location'],
                    'public_ip_allocation_method': 'Dynamic',
                    'public_ip_address_version': 'IPv4'
                })
            pubip_info = async_pubip_creation.result()
            self.created_resources['public_ip_address'] = pubip_name

        log.debug('Creating NIC')
        async_nic_creation = self.network_client.network_interfaces.create_or_update(
            self.res['resource_group'], nic_name, {
                'location':
                self.res['location'],
                'ip_configurations': [{
                    'name':
                    unique_vmname(self.node_def) + '-ipconfig',
                    'subnet': {
                        'id': subnet_info.id
                    },
                    'public_ip_address':
                    pubip_info if pubip_info is not None else ''
                }]
            })
        nic_info = async_nic_creation.result()
        self.created_resources['network_interface'] = nic_name
        return nic_info