0

Hi Have created custom IoT edge modules which require read and write operations to files inside a directory present in IoT edge server. Earlier I was using Docker desktop to build the modules so I was able to give read/write permission to the modules by referring this doc - Add local storage to Azure IoT Edge modules using Docker Bind But now when I am building similar IoT edge Module requiring read/write operation, with podman desktop so now the container is not even starting. on the IoT Edge Server when I checked the container, it gives the following error -

Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: rootfs_linux.go:75: mounting "/var/SampleModule" to rootfs at "/app/SampleModule" caused: mount through procfd: open o_path procfd: open /var/lib/docker/overlay2/871b2e9e4e03.../merged/app/SampleModule: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type

Below is the deployment.template.json used for build and deployment

{
  "$schema-template": "4.0.0",
  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "runtime": {
          "type": "docker",
          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {
              "<Container Registry Name>": {
                "username": "$CONTAINER_REGISTRY_USERNAME_<Container Registry Name>",
                "password": "$CONTAINER_REGISTRY_PASSWORD_<Container Registry Name>",
                "address": "<Container Registry hostname>"
              }
            }
          }
        },
        "systemModules": {
          "edgeAgent": {
            "type": "docker",
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-agent:1.4",
              "createOptions": {}
            }
          },
          "edgeHub": {
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-hub:1.4",
              "createOptions": {
                "HostConfig": {
                  "PortBindings": {
                    "5671/tcp": [
                      {
                        "HostPort": "5671"
                      }
                    ],
                    "443/tcp": [
                      {
                        "HostPort": "443"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "modules": {
          "SampleModule": {
            "version": "1.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "${MODULES.SampleModule}",
              "createOptions": {
                "HostConfig": {
                  "Binds": [
                    "/var/SampleModule/data:/app/SampleModule/data"
                  ]
                }
              }
            }
          },
          "SimulatedTemperatureSensor": {
            "version": "1.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.4",
              "createOptions": {}
            }
          }
        }
      }
    },
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.2",
        "routes": {
          "SampleModuleToIoTHub": "FROM /messages/modules/SampleModule/outputs/* INTO $upstream",
          "sensorToSampleModule": "FROM /messages/modules/SimulatedTemperatureSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/SampleModule/inputs/input1\")"
        },
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 7200
        }
      }
    }
  }
}

How can I resolve this issue?

1 Answers1

1

The error message shows that the container is not starting because it is trying to mount a directory onto a file or vice versa.

Use environment variables and create options to enable module access to IoT Edge device local storage.

enter image description here

"systemModules": {
    "edgeAgent": {
        "settings": {
            "image": "mcr.microsoft.com/azureiotedge-agent:1.4",
            "createOptions": {
                "HostConfig": {
                    "Binds":["<HostStoragePath>:<ModuleStoragePath>"]
                }
            }
        },
        "type": "podman",
        "env": {
            "storageFolder": {
                "value": "<ModuleStoragePath>"
            }
        }
    },
    "edgeHub": {
        "settings": {
            "image": "mcr.microsoft.com/azureiotedge-hub:1.4",
            "createOptions": {
                "HostConfig": {
                    "Binds":["<HostStoragePath>:<ModuleStoragePath>"],
                    "PortBindings":{
                        "5671/tcp":[{"HostPort":"5671"}],
                        "8883/tcp":[{"HostPort":"8883"}],
                        "443/tcp":[{"HostPort":"443"}]
                    }
                }
            }
        },
        "type": "docker",
        "env": {
            "storageFolder": {
                "value": "<ModuleStoragePath>"
            }
        },
        "status": "running",
        "restartPolicy": "always"
    }
}

enter image description here

Configure system modules to use existed storage by adding an environment variable called storage Folder that points to a directory in the module and configured in the module.

Steps to follow:

  • Check read/write permissions for the directory you want to mount on the IoT Edge server. Create if it doesn't exist.

Command to create a directory.

sudo mkdir -p /var/SampleModule
  • Check the permissions of the directory using the ls command.
ls -ld /var/SampleModule
  • Make changes to the configuration of your IoT Edge module to use the correct mount path.

In your case, it seems like you are mounting the /var/SampleModule directory inside the container at /app/SampleModule. Make sure the mount path in your Podman command or Podman Compose file is correct.

And if you are using a Podman Compose file, the volumes section should be as mentioned below.

volumes:
  - /var/SampleModule:/app/SampleModule

If you are using a Podman command, the mount option should be specified like this:

podman run -v /var/SampleModule:/app/SampleModule ...

After updating the configuration, try building and running your IoT Edge module with Podman again.

For further information refer to the Blog and Iot- devices -in-rootless -containers.

Rajesh Mopati
  • 1,329
  • 1
  • 2
  • 7
  • Thanks for your response, When I tried to change the type from docker to podman in deployment.template.json, I am facing this issue - There are errors in deployment json file: data.modulesContent.$edgeAgent['properties.desired'].runtime.type should be equal to one of the allowed values, data.modulesContent.$edgeAgent['properties.desired'].systemModules.edgeAgent.type should be equal to one of the allowed values, data.modulesContent.$edgeAgent['properties.desired'].systemModules.edgeHub.type should be equal to one of the allowed values, – Satyam Chauhan Jun 20 '23 at 05:29
  • I have added the current deployment.template.json file. – Satyam Chauhan Jun 20 '23 at 05:43
  • The error message indicates that the deployment manifest is expecting the runtime type to be one of the allowed values. When you changed the type from docker to podman, the deployment manifest is no longer valid. Check this [Routes in IOT Edge](https://learn.microsoft.com/en-us/azure/iot-edge/module-composition?view=iotedge-1.4) – Rajesh Mopati Jun 20 '23 at 06:20
  • Thanks @Rajesh-M, I am building the module using Podman desktop,and podman command - **podman build and podman push** the IoT edge module is C# .net 6. by default which is using Dockerfile.amd64 to build and push the modules. The modules are pushed to Azure container registry. But in the IoT Edge Server we have used moby-engine and mody cli for running docker commands, so in the IoT Edge server I am calling docker pull . I am using combination of both docker and podman, podman for build and push and docker for pull and run in IoT edge server. Can you help on this? – Satyam Chauhan Jun 20 '23 at 12:34