CLOUDMORROW

Resources / User handbook

Files and shares

Your own drive, shares made and shared with people and circles, and mounting them.

Fileshares

A share is a folder on the server with a name. The name is the last segment of its URL — …/dav/media/ — and the thing you mount. It is the server's name, not the account's: there is one share called media, since it is one folder and one address. folders, candidates and check are kept for the API, and my-files is everybody's own drive.

Anybody makes one. It is the folder of its name in the Shares folder on the server, and it is theirs: they see it, write in it, decide who else does, and remove it. Being an administrator opens nobody's share — an admin has the shares they made and the ones shared with them, like everybody else.

Shared with people, circles, or everybody. A share's owner shares it with people by name and with circles, each to change what is in it (write) or only to read it. A circle is followed as it changes: the next person put in Kids has the share the day they are. An administrator may also share with everybody on the server, today's accounts and every one made later. Your access to a share is the most any of those gives you — by name, through a circle, or as everybody — the same rule as circles have for data (CIRCLES.md). There is no deny. Nobody is asked to accept; a person shared with by name may leave, and a circle is left by leaving the circle.

Read means read. Somebody who may only read a share lists it, opens its files and mounts it; everything that would change it — a file put there, a folder made, a rename, a move, a delete, over WebDAV or the API — is refused with 403, and so is copying or moving something out of a share you may write into one you may only read. Somebody whose circles give only read on files gets the same in every share, their own drive included.

An administrator's share elsewhere. An administrator may point a share at another directory on the server — a media library in /srv/media, say — by giving its path when the share is made, or by changing it later (share move; the files are not moved, and an empty path puts the share back in its own folder in Shares). The path is checked as it is given, and the checks are of two kinds:

  • Refused, so nothing is made: a path that is not absolute, not there, or not a directory; and anything that holds, or is inside, what the server keeps for itself — its data directory and database, the encryption key, its settings, and everybody's own files (each drive is its owner's alone). A path inside the Shares folder is fine. Symlinks are followed to where they lead, and judged there.
  • Said, and shared all the same, so it can be fixed in place: a folder the server cannot open, one it can read but not write (the share then works as read-only), a filesystem the service sees as read-only (under systemd that is ProtectSystem=strict: add the folder to ReadWritePaths with systemctl edit cloudmorrow), a world-writable folder, files at the top of it the server cannot read or change, and a folder another share already covers. These come back as warnings when the share is made, and again every time its owner looks, until they are fixed. The web app checks as the path is typed (GET /api/shares/check), before anything is made.

Somebody who is not an administrator is never asked for a path: their share is the folder of its name, and that is the whole of where it can be.

Making one, and sharing it:

In the web app

Files → New share: a name, who has it (a menu per person, circle and — for an administrator — Everybody, each change or read), and, for an administrator, the path, filled in as the name is typed and checked as it is changed. Under each share is whose it is and who has it, which opens the share's own page: the same menus, changed as they are chosen, the path, and Remove — or, for a share somebody else made, whose it is, who has it, and Leave.

In the terminal app

Files (f5): ctrl+n makes one, s changes who has the one under the cursor, as one line to edit — ann, circle:kids (read), everyone — and d removes it; the files stay.

On the command line

cloudmorrow share add family --with ann --with circle:kids   # yours, shared with Ann and Kids
cloudmorrow share add library --with everyone --read          # administrators: everybody may read it
cloudmorrow share add media --path /srv/media                  # administrators: a directory elsewhere
cloudmorrow share with family sam --read                       # Sam may read it
cloudmorrow share unshare family circle:kids
cloudmorrow share leave recipes                                # somebody shared it with you
cloudmorrow share move media /srv/films                        # administrators; --back for Shares
cloudmorrow share remove family                                # for everybody; the files stay
cloudmorrow share remove family --files                        # …and deletes its folder in Shares

Mounting one on the machine you are at, as a folder:

In the web app

A browser cannot mount anything. In the desktop app every share in Files has Mount on this computer, then Mounted at ~/Fileshares/media with Open folder and Unmount. In a browser, the share's page says its address under Mount at, for any WebDAV client — a phone's file manager, a Windows drive letter — with your username and password.

Local backups. A folder on one of your computers, copied into My Files by that computer's agent and kept up to date: Files, “…”, Local backups. The page lists your machines and the folders backed up from each — where each lands (Backups/<machine>/<folder> unless you say otherwise), how often (every hour unless you say), and how the last pass went — with Run now and Remove on each (what was copied stays). Add a folder needs a machine that can do the copying: in the desktop app on a computer whose agent is running, the folder is picked in the system's own dialog; from anywhere, a machine of yours whose agent is online can be named and the folder typed. With neither — a phone, a browser on a computer with nothing installed — the page says what is needed and the button is off: the command line (cm) installed on a computer, where cloudmorrow login enrols and starts its agent, or the desktop app. Each pass sends what is new or changed under the folder (by size and the moment it changed), takes what is gone to the Trash here, passes over hidden files and links, and refuses a folder outside the machine's backup_roots like a backup job would. The files are then the drive's like any other: cm files list my-files Backups/laptop.

In the terminal app

Files (f5): m mounts the selected share on this machine, u unmounts it, c copies its WebDAV address. The table says which shares are mounted here, and where.

On the command line

cloudmorrow share mount family                                 # ~/Fileshares/family, or /Volumes/family
cloudmorrow share unmount family
cloudmorrow share list                                         # with where each is mounted here

When an account or a circle goes. What an account was given goes with it; the shares it made pass to the administrator who removed it, with their files and who has them as they were, so no share is left with nobody to decide about it. A circle that is deleted takes its line off every share, and a new circle of the same name does not inherit it.

My Files. Beside the shares, every account has a drive of its own on the server, served as my-files: …/dav/my-files/, first in share list, mounted with share mount my-files, and at the top of the Files tab in both apps. Nobody makes it and nobody removes it — it is there because the account is — and only its owner ever sees it; it is not shared. Its files are in that account's own tree, <notes_dir>/<username>/files/, and their notes are the Notes folder in it.

The Files Quill. What is in them is on screen through the Files Quill, a foundation Quill in the catalog: ticked on a new server with Calendar, Notes and Tasks, and installed at boot on a server that had Files built in (the switch keeps its name, files, and its setting). The files do not move for it — the core serves the drive and the shares as share and file records through the record API (the shares backend), with each file's bytes at /api/records/file/<id>/content, a small copy of a picture at …/thumb, and a new file put with POST /api/records/file/upload. The Quill is only the screen, drawn by the kit's grid, so the same thing is on every surface, and to an assistant through the generic record tools.

What is in them:

In the web app

Files lists My Files, then your shares and the ones shared with you. One opens as its folders and files, the way a file manager shows them — sorted by name, date, size or type, folders first — as a list, or as tiles with a picture of each photo (the switch beside the sort; the choice is kept). A file opens when tapped: a picture shown, its facts, a button that opens the phone's share sheet (or saves it), and Rename, Duplicate, Copy to another folder, Move to another folder and Delete, with Edit with Docs or Edit with Cells above them for a file one of those edits. The plus beside the title puts something in the folder you are in: a file chosen from the phone, one its camera takes there and then, or a new folder; on a computer a file dragged onto the folder or pasted goes in too. The “…” beside a folder's name renames, duplicates, copies, moves or deletes it.

Every row and tile has a menu — a right-click on a computer, a finger held on it on a phone — with Open, Edit with…, Rename, Duplicate, Copy to…, Move to…, and Delete; Copy to and Move to ask for the folder in a picker of the shares and their folders (a move stays in its share). A right-click on the room around the rows makes a new folder, a new empty text file by any name (notes.md, todo.txt; no suffix is .md), or picks a file to put in. Select beside the title — or Shift or Ctrl with a click, the way every file manager has it — picks several: the bar under the sort says how many, with Copy to, Move to and Delete (Restore and Delete for good in the Trash) for all of them at once, and All. A row or tile dragged onto a folder moves there, with everything picked when the one dragged is among it. The magnifier beside the title searches the folder and everything under it — names, and the lines of text files — and each hit says where it is; Escape closes it. A share you may only read opens with none of what writes: no plus, nothing dropped or pasted in, no rename, move or delete, and Copy to and Edit with alone in the menus — the Files Quill's group_writes reads the share's writable field. At the top of Files, the “…” beside the title has New share… and Local backups….

The Trash. Deleting loses nothing yet: the file or folder moves to a Trash folder at the top of the share (My Files has one of its own). On the web it is not among the folders but the bin beside the plus; open it and what is in it is listed, with Empty beside the title to delete all of it for good, after a question. A deleted file's page says when it was deleted and where it was, and has Restore in place of Rename and Move — back to where it was, the folders made again if they are gone, the name numbered if it is taken since — and Delete for good. The “…” on a folder in the Trash offers the same two. Thirty days after something went to the Trash the server removes it for good; deleting the Trash folder itself — in the terminal, or on the command line — empties it. Something put in the Trash another way — over a mount — counts from when the server first sees it there, and is restored to the top of the share. A note deleted in Notes goes to My Files' Trash the same way.

In the terminal app

The Files card: the shares, then enter on one for its folders and files. The same sort (s is the next one, S turns it around), v for thumbnails, and the picture the cursor is on drawn beside the listing — the real picture in Kitty or a Sixel terminal, coloured half-cells anywhere else. In a folder, p puts a file from this machine there, g gets the one the cursor is on, ctrl+n makes a folder, e renames, M moves and del deletes — to the Trash; in the Trash, u restores and del is for good. A share you may only read hides the same keys.

On the command line

cm files is the same grid; cm share is for the shares themselves.

cm files list                                  # My Files and your shares
cm files list my-files Photos                  # a folder
cm files get my-files Photos/cat.jpg ~/Desktop
cm files put my-files Photos ./dog.jpg
cm files add my-files Photos/2026              # a new folder
cm files copy my-files Photos/cat.jpg          # a duplicate beside it: cat 2.jpg
cm files copy my-files Photos/cat.jpg Albums   # a copy in another folder
cm files copy my-files Photos/cat.jpg media:Pets   # …or in another share you may change
cm files delete my-files Photos/old.jpg        # to the Trash
cm files restore my-files Trash/old.jpg        # back to Photos
cm files delete my-files Trash/old.jpg         # for good

Thumbnails. The server makes them, once, with the long edge at one of a few sizes, and keeps them under <data_dir>/thumbs/. The key includes when the file changed, so a picture put back under the same name gets a fresh one; the stale one is just never asked for again, and the folder is safe to empty at any time. A JPEG, PNG, GIF, WebP, BMP or TIFF gets one; a HEIC or an SVG shows as its icon, since Pillow reads neither without help.

Where a share's files are. In the Shares folder on the server, unless an administrator pointed it elsewhere: <notes_dir>/Shares/ in the Cloudmorrow directory, or shares_dir if the server config sets one (a folder outside the notes, data and code directories is one the service may not write to until the installer has put it in the unit: run install-server.sh --update, or give --shares-dir when installing). One folder for everyone's shares, whoever made them. A share is the folder of its name in there: share add media makes Shares/media if it is not there — and if an administrator has already put a folder there (rsync'd a library in as Pictures, say), naming it shares that folder as it is, whatever its case. The new-share dialog lists, for an administrator, the folders that are not shares yet. --files on remove deletes the folder; without it the share is only forgotten and the folder stays. A directory an administrator pointed a share at is never deleted from here.

Who has a share, in the database. shares holds the share — its name, unique on the server, its owner and its directory — and share_members one line per person, circle or everybody it is shared with, each write or read. Plain, like circles: who may open what is what the server reads on every request.

How it is served. WebDAV, by WsgiDAV, mounted inside the API at /dav. Every machine already has a client for that, which is the whole reason it is WebDAV rather than a FUSE driver of our own: a driver would be more code on the end that is hardest to debug, for a mount that behaves worse than the one the OS ships. The endpoint speaks HTTP Basic and takes your password — or the access token cloudmorrow login stored, in the password's place. That is what share mount sends, so a mount is signed in exactly as long as the client that made it, and no second password is written anywhere. /dav/ lists the caller's drive and every share they have; a share that is not theirs and not shared with them does not exist as far as /dav is concerned. Point any WebDAV client at the URL — a phone's file manager, a Windows drive letter — with the same username and password.

Mounting. What differs per platform is who does the mounting:

  • macOS — Finder, through one AppleScript line (mount volume), so nothing is installed. Finder picks the place, always /Volumes/<name> (or /Volumes/<name>-1 when the name is taken), and share mount reads the real path back and reports it. Basic auth over plain http:// is refused by macOS; the server is behind TLS, so this only matters against a dev server, and there rclone on a Mac works too.
  • Linux — rclone mount, which puts a FUSE filesystem in front of the share at the path you chose. rclone is one binary in every distribution's repository (pacman -S rclone, apt install rclone); the message when it is missing says so. Writes go through rclone's cache (--vfs-cache-mode writes), which is what lets programs that seek and rewrite — editors, most of them — work on a share. rclone's log for a mount is mount-<name>.log beside the client config.

What was mounted, and where, is written to mounts.json beside the client config — per machine, since the same share is at a different path on each — which is how the Files tab says "mounted at …" and share unmount knows what to undo. A mount does not survive a reboot; run share mount again. In the desktop app the same mount is a button on each share in the Files tab.

From docs/MANUAL.md in the Cloudmorrow repository. Something wrong? A pull request there fixes it here.