Dear pipex,
thanks for the information
This is the state information I get.
{
"local": {
"name": "local",
"config": {
"SUPERVISOR_POLL_INTERVAL": "60000",
"SUPERVISOR_INSTANT_UPDATE_TRIGGER": "true",
"SUPERVISOR_LOCAL_MODE": "true",
"SUPERVISOR_CONNECTIVITY_CHECK": "true",
"SUPERVISOR_LOG_CONTROL": "true",
"SUPERVISOR_DELTA": "false",
"SUPERVISOR_DELTA_REQUEST_TIMEOUT": "30000",
"SUPERVISOR_DELTA_APPLY_TIMEOUT": "0",
"SUPERVISOR_DELTA_RETRY_COUNT": "30",
"SUPERVISOR_DELTA_RETRY_INTERVAL": "10000",
"SUPERVISOR_DELTA_VERSION": "2",
"SUPERVISOR_OVERRIDE_LOCK": "false",
"SUPERVISOR_PERSISTENT_LOGGING": "false",
"HOST_FIREWALL_MODE": "",
"HOST_DISCOVERABILITY": "true",
"SUPERVISOR_HARDWARE_METRICS": "true",
"SUPERVISOR_VPN_CONTROL": "false",
"HOST_CONFIG_gpu_mem": "16",
"HOST_CONFIG_enable_uart": "1",
"HOST_CONFIG_dtoverlay": "\"vc4-fkms-v3d\"",
"HOST_CONFIG_arm_64bit": "1",
"HOST_CONFIG_dtparam": "\"i2c_arm=on\",\"spi=on\",\"audio=on\"",
"HOST_CONFIG_disable_splash": "1"
},
"apps": {
"1": {
"appId": 1,
"commit": "localrelease",
"releaseId": 1,
"services": [
{
"imageId": 1,
"serviceName": "browser",
"appId": 1,
"releaseId": 1,
"serviceId": 1,
"imageName": "local_image_browser:latest",
"dependsOn": null,
"config": {
"environment": {
"KIOSK": "1",
"SHOW_CURSOR": "0",
"ENABLE_GPU": "1",
"BALENA_APP_ID": "1",
"BALENA_APP_NAME": "localapp",
"BALENA_SERVICE_NAME": "browser",
"BALENA_DEVICE_UUID": "758adc960cf7db7fe8c4c6efab134f91",
"BALENA_DEVICE_TYPE": "raspberrypi4-64",
"BALENA_DEVICE_ARCH": "aarch64",
"BALENA_HOST_OS_VERSION": "balenaOS 2.82.10+rev1",
"BALENA_APP_LOCK_PATH": "/tmp/balena/updates.lock",
"BALENA": "1",
"RESIN_APP_ID": "1",
"RESIN_APP_NAME": "localapp",
"RESIN_SERVICE_NAME": "browser",
"RESIN_DEVICE_UUID": "758adc960cf7db7fe8c4c6efab134f91",
"RESIN_DEVICE_TYPE": "raspberrypi4-64",
"RESIN_DEVICE_ARCH": "aarch64",
"RESIN_HOST_OS_VERSION": "balenaOS 2.82.10+rev1",
"RESIN_APP_LOCK_PATH": "/tmp/balena/updates.lock",
"RESIN": "1",
"RESIN_SERVICE_KILL_ME_PATH": "/tmp/balena/handover-complete",
"BALENA_SERVICE_HANDOVER_COMPLETE_PATH": "/tmp/balena/handover-complete",
"USER": "root",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LC_ALL": "C.UTF-8",
"DEBIAN_FRONTEND": "noninteractive",
"UDEV": "1",
"QEMU_CPU": "arm1176",
"PULSE_SERVER": "tcp:audio:4317"
},
"labels": {
"io.balena.supervised": "true",
"io.balena.app-id": "1",
"io.balena.service-id": "1",
"io.balena.service-name": "browser",
"io.balena.architecture": "rpi",
"io.balena.device-type": "raspberrypi",
"io.balena.qemu.version": ""
},
"restart": "always",
"networkMode": "host",
"privileged": true,
"volumes": [
"1_settings:/data",
"/tmp/balena-supervisor/services/1/browser:/tmp/resin",
"/tmp/balena-supervisor/services/1/browser:/tmp/balena"
],
"image": "sha256:fa7ca3bc2ac4314d5f68595bb8cb219c1b9259cffa39ae6f4617f1024543104c",
"running": true,
"hostname": "balena",
"command": [
"export DISPLAY=:0"
],
"entrypoint": [
"bash",
"start.sh"
],
"stopSignal": "SIGTERM",
"workingDir": "/usr/src/app",
"user": "",
"oomKillDisable": false,
"readOnly": false,
"sysctls": {},
"portMaps": [],
"capAdd": [],
"capDrop": [],
"cgroupParent": "",
"devices": [],
"deviceRequests": [],
"dnsOpt": [],
"extraHosts": [],
"expose": [],
"networks": {},
"dns": [],
"dnsSearch": [],
"ulimits": {},
"groupAdd": [],
"healthcheck": {
"test": [
"NONE"
]
},
"pid": "",
"pidsLimit": 0,
"securityOpt": [],
"stopGracePeriod": 10,
"tmpfs": [],
"usernsMode": "",
"cpuShares": 0,
"cpuQuota": 0,
"cpus": 0,
"cpuset": "",
"domainname": "",
"ipc": "shareable",
"macAddress": "",
"memLimit": 0,
"memReservation": 0,
"oomScoreAdj": 0,
"shmSize": 67108864,
"tty": true
}
},
{
"imageId": 2,
"serviceName": "nginx",
"appId": 1,
"releaseId": 1,
"serviceId": 2,
"imageName": "local_image_nginx:latest",
"dependsOn": null,
"config": {
"environment": {
"BALENA_APP_ID": "1",
"BALENA_APP_NAME": "localapp",
"BALENA_SERVICE_NAME": "nginx",
"BALENA_DEVICE_UUID": "758adc960cf7db7fe8c4c6efab134f91",
"BALENA_DEVICE_TYPE": "raspberrypi4-64",
"BALENA_DEVICE_ARCH": "aarch64",
"BALENA_HOST_OS_VERSION": "balenaOS 2.82.10+rev1",
"BALENA_APP_LOCK_PATH": "/tmp/balena/updates.lock",
"BALENA": "1",
"RESIN_APP_ID": "1",
"RESIN_APP_NAME": "localapp",
"RESIN_SERVICE_NAME": "nginx",
"RESIN_DEVICE_UUID": "758adc960cf7db7fe8c4c6efab134f91",
"RESIN_DEVICE_TYPE": "raspberrypi4-64",
"RESIN_DEVICE_ARCH": "aarch64",
"RESIN_HOST_OS_VERSION": "balenaOS 2.82.10+rev1",
"RESIN_APP_LOCK_PATH": "/tmp/balena/updates.lock",
"RESIN": "1",
"RESIN_SERVICE_KILL_ME_PATH": "/tmp/balena/handover-complete",
"BALENA_SERVICE_HANDOVER_COMPLETE_PATH": "/tmp/balena/handover-complete",
"USER": "root",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"LC_ALL": "C.UTF-8",
"DEBIAN_FRONTEND": "noninteractive",
"UDEV": "off"
},
"labels": {
"io.balena.local.image": "1",
"io.balena.local.service": "nginx",
"io.balena.supervised": "true",
"io.balena.app-id": "1",
"io.balena.service-id": "2",
"io.balena.service-name": "nginx",
"io.balena.architecture": "aarch64",
"io.balena.device-type": "jetson-tx2",
"io.balena.qemu.version": "4.0.0+balena2-aarch64"
},
"restart": "always",
"networkMode": "host",
"image": "sha256:59ce32259138fd949fa4eae1db58c7b9a46e9d352a3ffb5a965372df284dbc85",
"running": true,
"hostname": "balena",
"command": [
"nginx",
"-g",
"daemon off;"
],
"entrypoint": [
"/usr/bin/entry.sh"
],
"stopSignal": "SIGTERM",
"workingDir": "/usr/src/app",
"user": "",
"volumes": [
"/tmp/balena-supervisor/services/1/nginx:/tmp/resin",
"/tmp/balena-supervisor/services/1/nginx:/tmp/balena"
],
"oomKillDisable": false,
"readOnly": false,
"sysctls": {},
"portMaps": [
{
"ports": {
"internalStart": 80,
"internalEnd": 80,
"externalStart": 80,
"externalEnd": 80,
"host": "",
"protocol": "tcp"
}
}
],
"capAdd": [],
"capDrop": [],
"cgroupParent": "",
"devices": [],
"deviceRequests": [],
"dnsOpt": [],
"extraHosts": [],
"expose": [
"80/tcp"
],
"networks": {},
"dns": [],
"dnsSearch": [],
"ulimits": {},
"groupAdd": [],
"healthcheck": {
"test": [
"NONE"
]
},
"pid": "",
"pidsLimit": 0,
"securityOpt": [],
"stopGracePeriod": 10,
"tmpfs": [],
"usernsMode": "",
"cpuShares": 0,
"cpuQuota": 0,
"cpus": 0,
"cpuset": "",
"domainname": "",
"ipc": "shareable",
"macAddress": "",
"memLimit": 0,
"memReservation": 0,
"oomScoreAdj": 0,
"privileged": false,
"shmSize": 67108864,
"tty": true
}
}
],
"volumes": {
"settings": {
"name": "settings",
"appId": 1,
"config": {
"driverOpts": {},
"driver": "local",
"labels": {
"io.balena.supervised": "true"
}
}
}
},
"networks": {
"default": {
"name": "default",
"appId": 1,
"config": {
"driver": "bridge",
"ipam": {
"driver": "default",
"config": [],
"options": {}
},
"enableIPv6": false,
"internal": false,
"labels": {},
"options": {}
}
}
}
}
}
},
"dependent": {
"apps": [],
"devices": []
}
}
Trying to push it back to the RPi 4 without changing anything gives following error:
{"status":"failed","message":"Invalid apps"}
- and I really don’t know why.
From the structure I can see one needs to add the changes to the local, config tree and substitute the starting parameter, so out of
"BALENA_HOST_CONFIG_gpu_mem": "192",
should become
"HOST_CONFIG_gpu_mem": "192",
is that correct?
If you got some new infos and I can iterate on them thanks for your help!
While this thread shall be about resolving the issue above, I got to think of a new usecase for the balena environment and how to make it suitable for extremly enclosed environments, so I am adding
@mpous @dtischler and @ajlennon - maybe the last one can support this idea and the first ones decide that the idea is not to stupid and worthwhile
To be upfront: I know running a device locally without any external “cloud backend” is not really the main goal of balena, however - there is a niche (especially in the aerospace sector and other industrial applications) where either complete airgaps exist, connectivity is limited, data is classified or a ban on usage of cloud environments at all exist. However, there are still dozens of applications were balena would still be useable, if you were able to provision a new device via a special laptop (which is already possible with balena-cli) from a local codebase, which is not send to the cloud (thats balena push ) and put onto the device. Then the device still can be scanned and then put into production.
However, there are still two things to be needed for that
a) support of the device variables for a local deployment. These device variables should be kept within textfiles, so that the really complete fleet/application can be kept within one git repo and be provisioned as needed without too many manual steps. While docker-compose.yml would be a good idea, I think you started using these device variables already in the balena.yml for the balenaHub applications - and so it would make perfect sense to configure a local devices variables (e.g. gpu_mem etc) by using balena push from a balena.yml in the folder [ gpsTime/balena.yml at main · nmaas87/gpsTime · GitHub data / applicationConfigVariables ].
b) there needs to be an option to harden the device, lets just name it protected local mode. within the dev local mode, the device is really open. with e.g. supervisor answering questions and getting new configs, ssh via 22222 / root, etc. It would be a great idea for a usage as stated above if you could provision a such hardend device on the first connection with a certificate and close all connection other than via ssh on 22222 using this certificate. Meaning every other port and the local terminal should be closed and only be reachable via this cert and secured connection. balena-cli could still work its functions, if it were to use the cert and tunnel via ssh, but the device would not be easyily attackable (this is also in regards of these environments, as nessus scans for open ports and such are a thing and then the test which can be done with the device using these open ports).
Cheers
Nico