Write rights on USB stick

Hi all,

I have a bit of a noob question; couldn't find the answer yet:
I'm running Node-Red on a Linux NUC pc, and I want to be able to write some logging info to a USB stick. So I began with nodes to determine whether a USB stick is present, and find out its address:

[
    {
        "id": "e9ee1b34.cfb5f8",
        "type": "exec",
        "z": "ca11a0459a7c29b7",
        "command": "",
        "addpay": true,
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "oldrc": false,
        "name": "",
        "x": 330,
        "y": 700,
        "wires": [
            [
                "9ab2c2f4af80e0fe",
                "2ca80c4b9170e354"
            ],
            [
                "bbdbf46cec725a29"
            ],
            [
                "3c6554e354978de1"
            ]
        ]
    },
    {
        "id": "bbdbf46cec725a29",
        "type": "debug",
        "z": "ca11a0459a7c29b7",
        "name": "debug 9",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 540,
        "y": 780,
        "wires": []
    },
    {
        "id": "3c6554e354978de1",
        "type": "debug",
        "z": "ca11a0459a7c29b7",
        "name": "debug 10",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 540,
        "y": 840,
        "wires": []
    },
    {
        "id": "9ab2c2f4af80e0fe",
        "type": "function",
        "z": "ca11a0459a7c29b7",
        "name": "Address of USB stick",
        "func": "var response = [null, null, null];\nvar usbStickFound = Boolean(msg.payload != \"\");\n\nvar newMsg = { payload: usbStickFound };\n\nflow.set(\"usbStickFound\", usbStickFound);\n\nresponse[0] = newMsg;\nif (usbStickFound)\n{\n    var usbStickName = msg.payload.trim();\n    flow.set(\"usb_stick\", usbStickName);\n    newMsg = { payload: \"/media/jw/\" + msg.payload };\n    response[2] = newMsg;\n}\nelse\n{\n    newMsg = { payload: \"Geen USB stick gedetecteerd.\" };\n    response[1] = newMsg;\n}\nreturn response;\n\n\n",
        "outputs": 3,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 580,
        "y": 720,
        "wires": [
            [
                "689f2a274e302539"
            ],
            [
                "b014d243d5220a1b"
            ],
            []
        ]
    },
    {
        "id": "b014d243d5220a1b",
        "type": "ui_toast",
        "z": "ca11a0459a7c29b7",
        "position": "dialog",
        "displayTime": "0",
        "highlight": "",
        "sendall": true,
        "outputs": 1,
        "ok": "OK",
        "cancel": "",
        "raw": false,
        "className": "",
        "topic": "Let op!",
        "name": "Foutmelding",
        "x": 1010,
        "y": 720,
        "wires": [
            []
        ]
    },
    {
        "id": "ba9bcba6d5c99313",
        "type": "function",
        "z": "ca11a0459a7c29b7",
        "name": "Try to find usb stick",
        "func": "msg.payload = \"ls /media/jw\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 190,
        "y": 800,
        "wires": [
            [
                "e9ee1b34.cfb5f8"
            ]
        ]
    },
    {
        "id": "2ca80c4b9170e354",
        "type": "debug",
        "z": "ca11a0459a7c29b7",
        "name": "debug 16",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 540,
        "y": 660,
        "wires": []
    },
    {
        "id": "124fc669055f8694",
        "type": "inject",
        "z": "ca11a0459a7c29b7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 120,
        "y": 720,
        "wires": [
            [
                "ba9bcba6d5c99313"
            ]
        ]
    },
    {
        "id": "689f2a274e302539",
        "type": "debug",
        "z": "ca11a0459a7c29b7",
        "name": "debug 17",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 760,
        "y": 660,
        "wires": []
    }
]

.. which works nicely, but only as long as I'm logged in on the pc. I would like to be able to always write to a USB stick from the NR dashboard. Is that possible?

The problem is that you are relying on the automatic mounting of the stick under /media/<username>/, which doesn't happen if you are not logged in.

You will need to automatically mount it. If you always use the same stick you can do that with an entry in /etc/fstab. If it is not always the same stick then I am not sure how to do it.
If it is the same stick each time then you can find the UUID of the stick using
sudo blkid
and can then put, in /etc/fstab, something like
UUID=129d9cb2-ecdf /media/usbstick ext4 defaults,nofail 0 0
That assumes that you have formatted it with ext4. It mounts at /media/usbstick obviously. I think you need to create that folder manually first.
Keep a copy of the original fstab because if you make a mess of fstab it may not boot, and you will have to put the card in a PC and replace the original fstab.

Thanks for the answer. Unfortunately it's not the answer I was hoping for.
I want to give the user the possibility to harvest logging data from a standalone system on his own usb device, without giving him access to Linux.
I always thought Node-Red uses the permissions of the user that started the process, but it seems to be a little bit more complicated ...

Copying log files to a usb stick when it is inserted doesn’t really need Node-RED. But you may also want to do some checks on the stick first before allowing the export of data to an unknown device. You can use things like udev rules to mount the stick and call a script to do the export.

1 Like

It isn't a permission issue, it is that the software that mounts the stick only runs when the user is logged in. Although node-red runs as that user, the user is not logged in.

Google found this, which might do what you want. I can't vouch for it, bit it does not look unreasonable. Automount USB devices on Linux using UDEV and Systemd | Andrea Fortuna

Thanks @Colin and @dceejay , that explains a lot. I'll have to look into this udev and systemd article, because I'm not a Linux expert.

I had to tweak it a little bit, but it works nicely. Thanks again!