def _create_nic_def(vmi_id, vmi_mac=None, vmi_ip=None):
     nic = {}
     if uuid.UUID(vmi_id).int:
         nic['uuid'] = validate_uuid(vmi_id)
         if vmi_mac:
             nic['mac'] = netaddr.EUI(vmi_mac, dialect=netaddr.mac_unix)
         else:
             nic['mac'] = None
         if vmi_ip:
             nic['ip'] = netaddr.IPNetwork(vmi_ip)
         else:
             nic['ip'] = None
     return nic
 def _create_nic_def(vmi_id, vmi_mac=None, vmi_ip=None):
     nic = {}
     if uuid.UUID(vmi_id).int:
         nic['uuid'] = validate_uuid(vmi_id)
         if vmi_mac:
             nic['mac'] = netaddr.EUI(vmi_mac, dialect=netaddr.mac_unix)
         else:
             nic['mac'] = None
         if vmi_ip:
             nic['ip'] = netaddr.IPNetwork(vmi_ip)
         else:
             nic['ip'] = None
     return nic
 def destroy(self):
     vm_name = validate_uuid(self.args.vm_id)
     self._stop(vm_name, self.args.vmi_left_id, self.args.vmi_right_id,
                self.args.vmi_management_id)
     self._client.remove_container(vm_name)
    def create(self):
        vm_name = validate_uuid(self.args.vm_id)
        image_name = self.args.image
        if self.args.instance_data:
            instance_data = json.loads(self.args.instance_data)
        else:
            instance_data = {}

        try:
            image = self._client.inspect_image(image_name)
        except APIError as e:
            if e.response.status_code == 404:
                self._client.pull(image_name)
                image = self._client.inspect_image(image_name)
            else:
                raise
        if self.args.command is not None:
            command = self.args.command
        elif "command" in instance_data:
            command = instance_data["command"]
        else:
            command = image["ContainerConfig"]["Cmd"]
        docker_id = None
        try:
            result = self._client.create_container(
                image=image_name,
                name=vm_name,
                command=command,
                detach=True,
                stdin_open=True,
                tty=True)  # keep the container running
            docker_id = result["Id"]
            self._stop(vm_name, self.args.vmi_left_id, self.args.vmi_right_id,
                       self.args.vmi_management_id)
        except APIError as e:
            if e.response.status_code == 409:
                if self.args.update:
                    container = self._client.inspect_container(vm_name)
                    docker_id = container["Id"]
                else:
                    raise

        if self.args.vmi_left_id is not None:
            nic_left = self._create_nic_def(self.args.vmi_left_id,
                                            self.args.vmi_left_mac,
                                            self.args.vmi_left_ip)
        else:
            nic_left = None

        if self.args.vmi_right_id is not None:
            nic_right = self._create_nic_def(self.args.vmi_right_id,
                                             self.args.vmi_right_mac,
                                             self.args.vmi_right_ip)
        else:
            nic_right = None

        if self.args.vmi_management_id is not None:
            nic_management = self._create_nic_def(self.args.vmi_management_id,
                                                  self.args.vmi_management_mac,
                                                  self.args.vmi_management_ip)
            nic_management['name'] = (
                "mng-" + nic_management['uuid'])[:NetnsManager.DEV_NAME_LEN]
            nic_management = [nic_management]
        else:
            nic_management = []

        self._client.start(docker_id, network_mode='none')
        docker_pid = self._client.inspect_container(docker_id)['State']['Pid']
        netns_mgr = NetnsManager(vm_name,
                                 nic_left,
                                 nic_right,
                                 other_nics=nic_management,
                                 namespace_name=str(docker_pid))

        if not os.path.exists("/var/run/netns/"):
            os.makedirs("/var/run/netns/")
        if netns_mgr.is_netns_already_exists():
            # If the netns already exists, destroy it to be sure to set it
            # with new parameters like another external network
            netns_mgr.unplug_namespace_interface()
            netns_mgr.destroy()

        # connect docker network stack as new netns on which we will work
        os.symlink("/proc/%s/ns/net" % docker_pid,
                   "/var/run/netns/%s" % docker_pid)
        netns_mgr.create()
        netns_mgr.plug_namespace_interface()
 def destroy(self):
     vm_name = validate_uuid(self.args.vm_id)
     self._stop(vm_name, self.args.vmi_left_id, self.args.vmi_right_id,
                self.args.vmi_management_id)
     self._client.remove_container(vm_name)
    def create(self):
        vm_name = validate_uuid(self.args.vm_id)
        image_name = self.args.image
        if self.args.instance_data:
            instance_data = json.loads(self.args.instance_data)
        else:
            instance_data = {}

        try:
            self._client.inspect_image(image_name)
        except APIError as e:
            if e.response.status_code == 404:
                self._client.pull(image_name)
                self._client.inspect_image(image_name)
            else:
                raise
        if self.args.command is not None:
            command = self.args.command
        elif "command" in instance_data:
            command = instance_data["command"]
        else:
            # use container default
            command = None
        docker_id = None
        try:
            result = self._client.create_container(
                image=image_name, name=vm_name, command=command, detach=True,
                stdin_open=True, tty=True)  # keep the container running
            docker_id = result["Id"]
            self._stop(vm_name, self.args.vmi_left_id, self.args.vmi_right_id,
                       self.args.vmi_management_id)
        except APIError as e:
            if e.response.status_code == 409:
                if self.args.update:
                    container = self._client.inspect_container(vm_name)
                    docker_id = container["Id"]
                else:
                    raise

        if self.args.vmi_left_id is not None:
            nic_left = self._create_nic_def(self.args.vmi_left_id,
                                            self.args.vmi_left_mac,
                                            self.args.vmi_left_ip)
        else:
            nic_left = None

        if self.args.vmi_right_id is not None:
            nic_right = self._create_nic_def(self.args.vmi_right_id,
                                             self.args.vmi_right_mac,
                                             self.args.vmi_right_ip)
        else:
            nic_right = None

        if self.args.vmi_management_id is not None:
            nic_management = self._create_nic_def(self.args.vmi_management_id,
                                                  self.args.vmi_management_mac,
                                                  self.args.vmi_management_ip)
            nic_management['name'] = ("mng-" + nic_management['uuid']
                                      )[:NetnsManager.DEV_NAME_LEN]
            nic_management = [nic_management]
        else:
            nic_management = []

        self._client.start(docker_id, network_mode='none')
        docker_pid = self._client.inspect_container(docker_id)['State']['Pid']
        netns_mgr = NetnsManager(vm_name, nic_left, nic_right,
                                 other_nics=nic_management,
                                 namespace_name=str(docker_pid))

        if not os.path.exists("/var/run/netns/"):
            os.makedirs("/var/run/netns/")
        if netns_mgr.is_netns_already_exists():
            # If the netns already exists, destroy it to be sure to set it
            # with new parameters like another external network
            netns_mgr.unplug_namespace_interface()
            netns_mgr.destroy()

        # connect docker network stack as new netns on which we will work
        os.symlink("/proc/%s/ns/net" % docker_pid,
                   "/var/run/netns/%s" % docker_pid)
        netns_mgr.create()
        netns_mgr.plug_namespace_interface()