test suite reviews and discussions
 help / color / mirror / Atom feed
From: Daxue Gao <daxuex.gao@intel.com>
To: dts@dpdk.org
Cc: lijuan.tu@intel.com, qingx.sun@intel.com,
	Daxue Gao <daxuex.gao@intel.com>
Subject: [V1] framework: add docker container support
Date: Tue, 27 Dec 2022 13:51:11 +0800	[thread overview]
Message-ID: <20221227055111.11097-1-daxuex.gao@intel.com> (raw)

1.Remove commands which are not in container, such as: modprobe, lsmod.
2.Remove kernel build when building dpdk in the container.
3.Add checking mount hugepage in the container, and fixing failures for hugepages configure.
4.Judge by the environment variable CONTAINER, the storage overlay and the return value of the execution system command, it is a container.
5.Fix vm mapping port issue with ssh port is not 22.
 When crb uses a non-22 port, then start VM, 
 the mapping will be converted to dutIP:port:host_port to vm 22 port,
 such as 127.0.0.1:5000:600 --> vm:22, which cannot be mapped. 
 so change it to dutIP:host_port to vm 22 port.

Signed-off-by: Daxue Gao <daxuex.gao@intel.com>
Signed-off-by: Lijuan Tu <lijuan.tu@intel.com>
---
 framework/crb.py          | 30 +++++++++++++++++++++--
 framework/dut.py          |  3 ++-
 framework/project_dpdk.py | 50 +++++++++++++++++++++++----------------
 framework/qemu_kvm.py     | 12 +++++++---
 framework/qemu_libvirt.py | 11 +++++++--
 framework/tester.py       |  9 +++----
 framework/virt_base.py    |  2 ++
 7 files changed, 84 insertions(+), 33 deletions(-)

diff --git a/framework/crb.py b/framework/crb.py
index 3c93fdc4..48526ac1 100644
--- a/framework/crb.py
+++ b/framework/crb.py
@@ -62,6 +62,7 @@ class Crb(object):
             self.alt_session.init_log(self.logger)
         else:
             self.alt_session = None
+        self.is_container = self._is_container()
 
     def get_ip_address(self):
         """
@@ -211,8 +212,20 @@ class Crb(object):
         out = out.strip(" [PEXPECT]#")
         # only mount hugepage when no hugetlbfs mounted
         if not len(out):
-            self.send_expect("mkdir -p /mnt/huge", "# ")
-            self.send_expect("mount -t hugetlbfs nodev /mnt/huge", "# ")
+            if self.is_container:
+                raise ValueError(
+                    "container hugepage not mount, please check hugepage config"
+                )
+            else:
+                self.send_expect("mkdir -p /mnt/huge", "# ")
+                self.send_expect("mount -t hugetlbfs nodev /mnt/huge", "# ")
+                out = self.send_expect(
+                    "awk '/hugetlbfs/ { print $2 }' /proc/mounts", "# "
+                )
+                if not len(out.strip(" [PEXPECT]#")):
+                    raise ValueError(
+                        "hugepage config error, please check hugepage config"
+                    )
 
     def strip_hugepage_path(self):
         mounts = self.send_expect("cat /proc/mounts |grep hugetlbfs", "# ")
@@ -1035,3 +1048,16 @@ class Crb(object):
         link_status_matcher = r"Link detected: (\w+)"
         link_status = re.search(link_status_matcher, out).groups()[0]
         return "Up" if link_status == "yes" else "Down"
+
+    def _is_container(self):
+        if self.send_expect("export |grep -i CONTAINER ", "# "):
+            return True
+        elif self.send_expect("df -h / |grep overlay ", "# "):
+            return True
+        elif self.send_expect(
+            "systemd-detect-virt -c|egrep '(systemd-nspawn|lxc|docker|podman|rkt|wsl|container-other)$' ",
+            "# ",
+        ):
+            return True
+        else:
+            return False
diff --git a/framework/dut.py b/framework/dut.py
index b8c01f47..481c0cb6 100644
--- a/framework/dut.py
+++ b/framework/dut.py
@@ -423,7 +423,8 @@ class Dut(Crb):
                     timeout=30,
                 )
                 # bind to linux kernel driver
-                self.send_expect("modprobe %s" % driver, "# ")
+                if not self.is_container:
+                    self.send_expect("modprobe %s" % driver, "# ")
                 self.send_expect(
                     "echo %s > /sys/bus/pci/drivers/%s/bind" % (pci_bus, driver), "# "
                 )
diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
index c20aa044..3f34ee02 100644
--- a/framework/project_dpdk.py
+++ b/framework/project_dpdk.py
@@ -87,11 +87,12 @@ class DPDKdut(Dut):
 
     def setup_modules_linux(self, target, drivername, drivermode):
         if drivername == "vfio-pci":
-            self.send_expect("rmmod vfio_pci", "#")
-            self.send_expect("rmmod vfio_iommu_type1", "#")
-            self.send_expect("rmmod vfio", "#")
-            self.send_expect("modprobe vfio", "#")
-            self.send_expect("modprobe vfio-pci", "#")
+            if not self.is_container:
+                self.send_expect("rmmod vfio_pci", "#")
+                self.send_expect("rmmod vfio_iommu_type1", "#")
+                self.send_expect("rmmod vfio", "#")
+                self.send_expect("modprobe vfio", "#")
+                self.send_expect("modprobe vfio-pci", "#")
             if drivermode == "noiommu":
                 self.send_expect(
                     "echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode",
@@ -263,26 +264,32 @@ class DPDKdut(Dut):
             self.send_expect("export PKG_CONFIG_LIBDIR=%s" % pkg_path, "# ")
 
         self.send_expect("rm -rf " + target, "#")
-        out = self.send_expect(
-            "CC=%s meson -Denable_kmods=True -Dlibdir=lib %s --default-library=%s %s"
-            % (toolchain, extra_options, default_library, target),
-            "[~|~\]]# ",
-            build_time,
-        )
+        if self.is_container:
+            meson_build_cmd = (
+                "CC=%s meson -Denable_kmods=False -Dlibdir=lib %s --default-library=%s %s"
+                % (toolchain, extra_options, default_library, target)
+            )
+        else:
+            meson_build_cmd = (
+                "CC=%s meson -Denable_kmods=True -Dlibdir=lib %s --default-library=%s %s"
+                % (toolchain, extra_options, default_library, target)
+            )
+        out = self.send_expect(meson_build_cmd, "[~|~\]]# ", build_time)
         assert "FAILED" not in out, "meson setup failed ..."
 
         out = self.send_expect("ninja -C %s" % target, "[~|~\]]# ", build_time)
         assert "FAILED" not in out, "ninja complie failed ..."
 
         # copy kmod file to the folder same as make
-        out = self.send_expect(
-            "find ./%s/kernel/ -name *.ko" % target, "# ", verify=True
-        )
-        self.send_expect("mkdir -p %s/kmod" % target, "# ")
-        if not isinstance(out, int) and len(out) > 0:
-            kmod = out.split("\r\n")
-            for mod in kmod:
-                self.send_expect("cp %s %s/kmod/" % (mod, target), "# ")
+        if not self.is_container:
+            out = self.send_expect(
+                "find ./%s/kernel/ -name *.ko" % target, "# ", verify=True
+            )
+            self.send_expect("mkdir -p %s/kmod" % target, "# ")
+            if not isinstance(out, int) and len(out) > 0:
+                kmod = out.split("\r\n")
+                for mod in kmod:
+                    self.send_expect("cp %s %s/kmod/" % (mod, target), "# ")
 
     def build_install_dpdk_freebsd_meson(self, target, extra_options):
         # meson build same as linux
@@ -342,7 +349,7 @@ class DPDKdut(Dut):
                     self.session.copy_file_to("dep/" + p, dst_dir)
 
             # copy QMP file to dut
-            if ":" not in self.session.name:
+            if "virtdut" not in self.session.name:
                 out = self.send_expect("ls -d ~/QMP", "# ", verify=True)
                 if isinstance(out, int):
                     self.send_expect("mkdir -p ~/QMP", "# ")
@@ -575,7 +582,8 @@ class DPDKtester(Tester):
             out = self.send_expect("tar zxfm tclclient.tgz", "# ")
             assert "Error" not in out
 
-        self.send_expect("modprobe uio", "# ")
+        if not self.is_container:
+            self.send_expect("modprobe uio", "# ")
 
         self.tester_prerequisites()
 
diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py
index dd8e7857..0131abcc 100644
--- a/framework/qemu_kvm.py
+++ b/framework/qemu_kvm.py
@@ -244,6 +244,11 @@ class QEMUKvm(VirtBase):
         else:
             self.host_logger.warning("Hardware virtualization disabled on host!!!")
             return False
+        if self.host_is_container:
+            if self.host_session.send_expect("ls /dev/kvm || ls /sys/module/kvm", "# "):
+                return True
+            else:
+                return False
 
         out = self.host_session.send_expect("lsmod | grep kvm", "# ")
         if "kvm" in out and "kvm_intel" in out:
@@ -256,8 +261,9 @@ class QEMUKvm(VirtBase):
         """
         Load the virtual module of kernel to enable the virtual ability.
         """
-        self.host_session.send_expect("modprobe kvm", "# ")
-        self.host_session.send_expect("modprobe kvm_intel", "# ")
+        if not self.host_is_container:
+            self.host_session.send_expect("modprobe kvm", "# ")
+            self.host_session.send_expect("modprobe kvm_intel", "# ")
         return True
 
     def disk_image_is_ok(self, image):
@@ -596,7 +602,7 @@ class QEMUKvm(VirtBase):
         host_addr = field(opt_hostfwd, 1)
         if not host_addr:
             addr = str(self.host_dut.get_ip_address())
-            host_addr = get_host_ip(addr)
+            host_addr = get_host_ip(addr).split(":")[0]
 
         # get the host port in the option
         host_port = field(opt_hostfwd, 2).split("-")[0]
diff --git a/framework/qemu_libvirt.py b/framework/qemu_libvirt.py
index cf406bad..e99ce8fb 100644
--- a/framework/qemu_libvirt.py
+++ b/framework/qemu_libvirt.py
@@ -106,6 +106,12 @@ class LibvirtKvm(VirtBase):
             self.host_logger.warning("Hardware virtualization " "disabled on host!!!")
             return False
 
+        if self.host_is_container:
+            if self.host_session.send_expect("ls /dev/kvm || ls /sys/module/kvm"):
+                return True
+            else:
+                return False
+
         out = self.host_session.send_expect("lsmod | grep kvm", "# ")
         if "kvm" not in out or "kvm_intel" not in out:
             return False
@@ -117,8 +123,9 @@ class LibvirtKvm(VirtBase):
         return True
 
     def load_virtual_mod(self):
-        self.host_session.send_expect("modprobe kvm", "# ")
-        self.host_session.send_expect("modprobe kvm_intel", "# ")
+        if not self.host_is_container:
+            self.host_session.send_expect("modprobe kvm", "# ")
+            self.host_session.send_expect("modprobe kvm_intel", "# ")
 
     def unload_virtual_mod(self):
         self.host_session.send_expect("rmmod kvm_intel", "# ")
diff --git a/framework/tester.py b/framework/tester.py
index 9a228f14..89f654d4 100644
--- a/framework/tester.py
+++ b/framework/tester.py
@@ -312,10 +312,11 @@ class Tester(Crb):
         if self.skip_setup:
             return
 
-        self.send_expect("modprobe igb", "# ", 20)
-        self.send_expect("modprobe ixgbe", "# ", 20)
-        self.send_expect("modprobe e1000e", "# ", 20)
-        self.send_expect("modprobe e1000", "# ", 20)
+        if not self.is_container:
+            self.send_expect("modprobe igb", "# ", 20)
+            self.send_expect("modprobe ixgbe", "# ", 20)
+            self.send_expect("modprobe e1000e", "# ", 20)
+            self.send_expect("modprobe e1000", "# ", 20)
 
         try:
             for (pci_bus, pci_id) in self.pci_devices_info:
diff --git a/framework/virt_base.py b/framework/virt_base.py
index a7fc8c4e..24f50d0f 100644
--- a/framework/virt_base.py
+++ b/framework/virt_base.py
@@ -55,6 +55,8 @@ class VirtBase(object):
         # init the host resource pool for VM
         self.virt_pool = self.host_dut.virt_pool
 
+        self.host_is_container = dut.is_container
+
         if not self.has_virtual_ability():
             if not self.enable_virtual_ability():
                 raise Exception("Dut [ %s ] cannot have the virtual ability!!!")
-- 
2.17.1


             reply	other threads:[~2022-12-27  6:07 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-27  5:51 Daxue Gao [this message]
2023-01-04  0:59 ` lijuan.tu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221227055111.11097-1-daxuex.gao@intel.com \
    --to=daxuex.gao@intel.com \
    --cc=dts@dpdk.org \
    --cc=lijuan.tu@intel.com \
    --cc=qingx.sun@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).