OpenMediaVault-Plugin-Developers / openmediavault-docker-gui

Docker plugin for OpenMediaVault
32 stars 17 forks source link

Checking architecture before running container #62

Open subzero79 opened 6 years ago

subzero79 commented 6 years ago

OMV4 is close to being released. Several (start/stop button only) plugins are gonna be buried due to the lack of developers that are available to maintain them. Some plugins also carry the baggage of mono.

Docker comes to solve this. Repositories in Docker hub hosts images in several archs. Unfortunately i am not aware yet of a method for querying the register api to return arch before pulling. But official images (hello world, ubuntu) of docker automatically pull specific arch according to host.

From what i see repositories use tags sometimes to mark the arch. This is not very reliable.

If you run an image with different arch, docker outputs an error that doesn't say much or the end user doesn't understand

The image info json text returns the image architecture. So the most common strings are arm, arm64 and amd64

This is a proposed patch to check arch of the image vs host arch and raise an exception. ATM the runContainer will not display if archs are different, closing the dialog

commit 6b37b890f63c7955dc7afa12a38b2bf6167db3a8
Author: subzero79 <subzero79@users.noreply.github.com>
Date:   Sun Feb 18 11:51:58 2018 +1000

    Add architecture check before running images

diff --git a/usr/share/omvdocker/Image.php b/usr/share/omvdocker/Image.php
index 1b6f6aa..17f06ce 100644
--- a/usr/share/omvdocker/Image.php
+++ b/usr/share/omvdocker/Image.php
@@ -159,6 +159,7 @@ class OMVModuleDockerImage
                 array_push($this->_volumes, array($key));
             }
         }
+        $this->_imagearch = $imageData->Architecture; 

     }

@@ -251,6 +252,17 @@ class OMVModuleDockerImage
     }

     /**
+     * Get the image architecture
+     *
+     * @return array $_volumes
+     * @access public
+     */
+    public function getImageArch()
+    {
+        return $this->_imagearch;
+    }
+
+    /**
      * Get the timestamp when the image was created
      *
      * @return array $_timestamp
diff --git a/usr/share/openmediavault/engined/rpc/docker.inc b/usr/share/openmediavault/engined/rpc/docker.inc
index 4bf9f01..b0082a7 100644
--- a/usr/share/openmediavault/engined/rpc/docker.inc
+++ b/usr/share/openmediavault/engined/rpc/docker.inc
@@ -158,6 +158,13 @@ class OMVRpcServiceDocker extends ServiceAbstract
         return $arch;
     }

+    private function getHostArch()
+    {
+        $cmd = "dpkg --print-architecture";
+        $hostArch = exec($cmd, $output);
+        return $hostArch;
+    }
+
     /**
      * Get all Docker images
      *
@@ -403,8 +410,31 @@ class OMVRpcServiceDocker extends ServiceAbstract
             "size" => $image->getSize(),
             "ports" => $image->getPorts(),
             "envvars" => $image->getEnvVars(),
-            "imagevolumes" => $image->getVolumes()
+            "imagevolumes" => $image->getVolumes(),
+            "architecture" => $image->getImageArch()
         );
+
+        // Image information has an Architecture key
+        switch ($this->getHostArch()) {
+            case 'amd64':
+                if (($object['architecture'] = "arm") || ($object['architecture'] = "arm64")) {
+                    throw new OMVModuleDockerException("The host platform architecture is AMD64 and the image is " . 
+                        strtoupper($object['architecture']) . ". This image will fail to run");
+                }
+                break;
+            case 'arm64':
+                if ($object['architecture'] = "amd64") {
+                    throw new OMVModuleDockerException("The host platform architecture is ARM and the image is AMD64. This image will fail to run");
+                }
+                break;
+            case 'armhf':
+                if (($object['architecture'] = "amd64") || ($object['architecture'] = "arm64")) {
+                    throw new OMVModuleDockerException("The host platform architecture is ARM and the image is "
+                        . strtoupper($object['architecture']) . ". This image will fail to run");
+                }
+                break;
+        }
+
         return $object;
     }

@@ -449,11 +479,6 @@ class OMVRpcServiceDocker extends ServiceAbstract

         $cmd = "docker run -d ";

-        //Check if restart checkbox is enabled
-        //if ($params['restartpolicy']) {
-        //    $cmd .= "--restart=always ";
-        //}
-
         switch ($params['restartpolicy']) {
             case "always":
                 $cmd .= "--restart=always ";

amd64 host cannot run armhf or arm64 images and viceversa. armhf host can only run arm images arm64 host should be able to run both armhf and arm64 images. This is to be confirmed

subzero79 commented 6 years ago

It also comes to mind if we can do something on our side with DockerRepo from LS. I know linuxserver has a special whole hub node for arm, lsioarmhf