get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/127145/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 127145,
    "url": "http://patchwork.dpdk.org/api/patches/127145/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dts/patch/20230522081016.6430-1-daxuex.gao@intel.com/",
    "project": {
        "id": 3,
        "url": "http://patchwork.dpdk.org/api/projects/3/?format=api",
        "name": "DTS",
        "link_name": "dts",
        "list_id": "dts.dpdk.org",
        "list_email": "dts@dpdk.org",
        "web_url": "",
        "scm_url": "git://dpdk.org/tools/dts",
        "webscm_url": "http://git.dpdk.org/tools/dts/",
        "list_archive_url": "https://inbox.dpdk.org/dts",
        "list_archive_url_format": "https://inbox.dpdk.org/dts/{}",
        "commit_url_format": ""
    },
    "msgid": "<20230522081016.6430-1-daxuex.gao@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dts/20230522081016.6430-1-daxuex.gao@intel.com",
    "date": "2023-05-22T08:10:16",
    "name": "[v1] framework: fix container vm port conflict",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "539a5e03b96ba8832d49b223a26b89a0490bb2fd",
    "submitter": {
        "id": 2427,
        "url": "http://patchwork.dpdk.org/api/people/2427/?format=api",
        "name": "Gao, DaxueX",
        "email": "daxuex.gao@intel.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.dpdk.org/project/dts/patch/20230522081016.6430-1-daxuex.gao@intel.com/mbox/",
    "series": [
        {
            "id": 28100,
            "url": "http://patchwork.dpdk.org/api/series/28100/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dts/list/?series=28100",
            "date": "2023-05-22T08:10:16",
            "name": "[v1] framework: fix container vm port conflict",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/28100/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/127145/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/127145/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dts-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 4318D42B6F;\n\tMon, 22 May 2023 10:10:21 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 18E7E410DD;\n\tMon, 22 May 2023 10:10:21 +0200 (CEST)",
            "from mga06.intel.com (mga06b.intel.com [134.134.136.31])\n by mails.dpdk.org (Postfix) with ESMTP id C3ADE410D1\n for <dts@dpdk.org>; Mon, 22 May 2023 10:10:18 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 22 May 2023 01:10:17 -0700",
            "from unknown (HELO localhost.localdomain) ([10.239.252.161])\n by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 22 May 2023 01:10:16 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1684743018; x=1716279018;\n h=from:to:cc:subject:date:message-id;\n bh=bwtiADQ0W90M23n2WIniVdvFQRbXZX6LuHcb0t5Q89o=;\n b=Y5sjYQJfB3RsmbFMRNC7W8QlN5Hmjdscn0ELZj46wKAGnWHUe7wLVyVC\n KAqu99cQjKnvX8akKVa9IM2YAfKgoF6uGyOxn0rzlCKJJ74DYCQdhnSLK\n 9EFSC5aCXWKf3SfOjmZgOz7zIugZTxPvvBSV3FknzgaKNVWfk7wGYtCUs\n bwq1/DWSN9JKObOksFXIpX3ZRLhYsmO40lLXnyi7UqLgNdFsTzfaIluzI\n x5E5eEGxL/N1uV6UQOjjb4pLOTP71K1sy1J6BRI0KqdGxNDwR5Bp0Undy\n mb2x4XzkL4MJ1PwptifB94+uYD1CQZ1zwVj23GSa65vO7a0GEdeguJHJ4 Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10717\"; a=\"416321750\"",
            "E=Sophos;i=\"6.00,183,1681196400\"; d=\"scan'208\";a=\"416321750\"",
            "E=McAfee;i=\"6600,9927,10717\"; a=\"1033524865\"",
            "E=Sophos;i=\"6.00,183,1681196400\"; d=\"scan'208\";a=\"1033524865\""
        ],
        "X-ExtLoop1": "1",
        "From": "Daxue Gao <daxuex.gao@intel.com>",
        "To": "dts@dpdk.org",
        "Cc": "Daxue Gao <daxuex.gao@intel.com>",
        "Subject": "[PATCH v1] framework: fix container vm port conflict",
        "Date": "Mon, 22 May 2023 16:10:16 +0800",
        "Message-Id": "<20230522081016.6430-1-daxuex.gao@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "X-BeenThere": "dts@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "test suite reviews and discussions <dts.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dts>,\n <mailto:dts-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dts/>",
        "List-Post": "<mailto:dts@dpdk.org>",
        "List-Help": "<mailto:dts-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dts>,\n <mailto:dts-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dts-bounces@dpdk.org"
    },
    "content": "Fix the problem that the container vm port conflict causes the vm to fail to start.\nCapture the port conflict by exception, and assign a new port number to start the vm.\nThe port conflict includes tcp forward/vnc/telnet/migrate port.\n\nSigned-off-by: Daxue Gao <daxuex.gao@intel.com>\n---\n framework/exception.py     | 11 +++++++++++\n framework/qemu_kvm.py      | 25 ++++++++++++++++++++-----\n framework/virt_base.py     |  7 +++----\n framework/virt_resource.py | 12 ++++++------\n 4 files changed, 40 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/framework/exception.py b/framework/exception.py\nindex fb0fa72e..09012d43 100644\n--- a/framework/exception.py\n+++ b/framework/exception.py\n@@ -146,3 +146,14 @@ class VirtVmOperationException(Exception):\n \n class VirtHostPrepareException(Exception):\n     pass\n+\n+\n+class VmPortConflictException(Exception):\n+    \"\"\"\n+    Start VM vnc port or vm port conflict failed.\n+    \"\"\"\n+    def __init__(self, error):\n+        self.error = error\n+\n+    def __str__(self):\n+        pass\ndiff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py\nindex 0131abcc..b656675c 100644\n--- a/framework/qemu_kvm.py\n+++ b/framework/qemu_kvm.py\n@@ -6,7 +6,7 @@ import os\n import re\n import time\n \n-from .exception import StartVMFailedException\n+from .exception import StartVMFailedException, VmPortConflictException\n from .settings import DTS_PARALLEL_SETTING, get_host_ip, load_global_setting\n from .utils import RED, parallel_lock\n from .virt_base import ST_NOTSTART, ST_PAUSE, ST_RUNNING, ST_UNKNOWN, VirtBase\n@@ -1404,16 +1404,20 @@ class QEMUKvm(VirtBase):\n     @parallel_lock(num=4)\n     def __send_qemu_cmd(self, qemu_boot_line, dut_id):\n         # add more time for qemu start will be slow when system is busy\n-        ret = self.host_session.send_expect(\n-            qemu_boot_line, \"# \", verify=True, timeout=30\n-        )\n+        ret = self.host_session.send_expect(qemu_boot_line, \"# \", timeout=30)\n+        ret_status = int(self.host_session.send_expect(\"echo $?\", \"#\", timeout=30))\n \n         # record start time\n         self.start_time = time.time()\n \n         # wait for qemu process ready\n         time.sleep(2)\n-        if type(ret) is int and ret != 0:\n+        if type(ret_status) is int and ret_status != 0:\n+            if self.vm_port_conflict(ret):\n+                self.qemu_boot_line = \"\"\n+                self.pt_idx = 0\n+                delattr(self, \"hostfwd_addr\")\n+                raise VmPortConflictException(self)\n             raise StartVMFailedException(\"Start VM failed!!!\")\n \n     def _quick_start_vm(self):\n@@ -2043,3 +2047,14 @@ class QEMUKvm(VirtBase):\n             map = list(zip(threads, lcores))\n         for thread, lcore in map:\n             self.host_session.send_expect(\"taskset -pc %s %s\" % (lcore, thread), \"#\")\n+\n+    def vm_port_conflict(self, ret):\n+        \"\"\"\n+        check for vm port conflict\n+        \"\"\"\n+        status = None\n+        if \"Could not set up host forwarding rule\" in ret:\n+            status = True\n+        elif \"Failed to find an available port: Address already in use\" in ret:\n+            status = True\n+        return status\ndiff --git a/framework/virt_base.py b/framework/virt_base.py\nindex 24f50d0f..e8c34b09 100644\n--- a/framework/virt_base.py\n+++ b/framework/virt_base.py\n@@ -279,6 +279,7 @@ class VirtBase(object):\n         \"\"\"\n         Start VM and instantiate the VM with VirtDut.\n         \"\"\"\n+        vm_dut = None\n         try:\n             if load_config is True:\n                 self.load_config()\n@@ -293,9 +294,8 @@ class VirtBase(object):\n                 vm_dut = self.instantiate_vm_dut(\n                     set_target, cpu_topo, bind_dev=bind_dev, autodetect_topo=True\n                 )\n-            else:\n-                vm_dut = None\n-\n+        except exception.VmPortConflictException:\n+            vm_dut = self.start()\n         except Exception as vm_except:\n             if self.handle_exception(vm_except):\n                 print(utils.RED(\"Handled exception \" + str(type(vm_except))))\n@@ -305,7 +305,6 @@ class VirtBase(object):\n             if callable(self.callback):\n                 self.callback()\n \n-            return None\n         return vm_dut\n \n     def quick_start(self, load_config=True, set_target=True, cpu_topo=\"\"):\ndiff --git a/framework/virt_resource.py b/framework/virt_resource.py\nindex 3bc4b87b..231cdebc 100644\n--- a/framework/virt_resource.py\n+++ b/framework/virt_resource.py\n@@ -2,7 +2,7 @@\n # Copyright(c) 2010-2015 Intel Corporation\n #\n \n-from random import randint\n+from random import randint, randrange\n \n from .utils import RED, get_obj_funcs, parallel_lock\n \n@@ -344,15 +344,15 @@ class VirtResource(object):\n         if vm == \"\":\n             print(\"Alloc host port request vitual machine name!!!\")\n             return None\n-\n+        offset = randrange(0, 1000, 200)\n         if port_type == \"connect\":\n-            port = INIT_FREE_PORT\n+            port = INIT_FREE_PORT + offset\n         elif port_type == \"serial\":\n-            port = INIT_SERIAL_PORT\n+            port = INIT_SERIAL_PORT + offset\n         elif port_type == \"migrate\":\n-            port = INIT_MIGRATE_PORT\n+            port = INIT_MIGRATE_PORT + offset\n         elif port_type == \"display\":\n-            port = INIT_DISPLAY_PORT + 5900\n+            port = INIT_DISPLAY_PORT + 5900 + offset\n \n         while True:\n             if (\n",
    "prefixes": [
        "v1"
    ]
}