Files, logs and API
This page lists the files of a Mutara install, the log, the command-line flags and the web routes that are documented for other programs.
Files of an install #
| Path | What it holds |
|---|---|
/etc/mutara/mutara.yaml | The configuration. A save keeps the old file as .bak. |
/etc/mutara/modules.d/ | One file for each node after the first. |
/opt/mutara/bin/ | The programs. The old program stays as mutara.prev after an upgrade. |
/var/lib/mutara/ | The state folder of the service. |
/var/lib/mutara-upgrade/result | The result of the last upgrade job. |
The installer links mutara and mutara-switch into /usr/local/bin and /usr/local/sbin.
The state folder #
The state folder holds:
mutara-tls/: the self-signed certificatemutara-certs/: the Let's Encrypt cachechat/: the chat messages and filesrecordings/: the recorded clips. A clip with a transcript also has<clip>.stt.json.bundles/: the bundles. Each bundle has a folderbundles/<id>/withbundle.json, the clips inclips/(hard links or copies), and the joined audioaudio.opusandaudio.m4a. Read Storage and clean-up.voice-cache/: the copies of voice server answers- The recent nodes, the calls that stay up through a restart, and the weather alerts
scan-priority.json: the own scan priority of each userscan-list.json: the own scan list of each user (In my scan)user-prefs.json: the dashboard theme, the DMR ID and the M17 callsign of each usersessions.json: the dashboard sign-ins, as hashes of the tokens. Older versions kept it next to the configuration file; the node moves it here at start.install-id: the ID of the install for the transcoder server. Do not delete or change it.
Mutara finds the state folder with the first rule that applies:
MUTARA_STATE_DIR, if it is set.STATE_DIRECTORY, which systemd sets:/var/lib/mutarafor the service.- The working folder, if it already holds state and the folder of the configuration file does not.
- The working folder, if it is
/var/lib/mutara, as in the Docker image. - The folder of the configuration file.
Each node after the first keeps its recent nodes, clips, bundles, chat and favorites in modules/<node>/. A room keeps its clips, bundles and chat in modules/<id>/. A removed node moves to modules/.removed/<node>-<date>-<time>/. Mutara does not delete those files.
Logs and the journal #
- Follow the log of the service:
journalctl -u mutara -f - Read the log of an upgrade:
journalctl -u mutara -u mutara-upgrade log.levelisdebug,info,warnorerror.log.formatistextorjson.- The diagnostics file from Settings has the recent logs, the version, the status and the settings without passwords.
Useful messages: "allstar registration failed" with the reason, and an ERROR with the stack when a node stops on an internal error.
Command-line flags #
| Flag | What it does |
|---|---|
-config file | The configuration file. The default is ./mutara.yaml, then /etc/mutara/mutara.yaml. |
-version | Print the version. |
-example-config | Print a commented example configuration. |
-check-config | Check the configuration and the module files. |
-hash-password | Read a password and print a bcrypt hash for password_hash. |
-list-radios | List the USB radio interfaces. |
-find-radio-module | Look for radio modules on the USB serial ports. -ports selects the ports. |
-program-radio-module | Write radio.module to the module, only when the radio is quiet. |
-import-asl3 folder | Make the configuration from an ASL3 setup. Read The ASL3 importer. |
-verify-release file | Check the signature and checksum of a release file. |
-healthcheck | Check that the dashboard of the running node answers. |
-cpuprofile file | Write a CPU profile of the running node. -cpuprofile-seconds sets the time, 60 by default. |
The ASL3 importer #
mutara -import-asl3 /etc/asterisk -dry-run
sudo mutara -import-asl3 /etc/asterisk -config /etc/mutara/mutara.yaml
The importer reads rpt.conf, iax.conf and the USB channel files. It copies these items:
- the node number and password, the callsign and the timers
- the courtesy tone, the DTMF functions, the macros and the schedule
- the permanent links of
startup_macroand the[nodes]entries - the simpleusb or usbradio channel and the IAX app logins
It prints what it copied and what it skipped. It does not change the ASL3 files.
-dry-runshows the result and writes nothing.-forcereplaces a configuration and keeps its dashboard accounts.-asl3-nodeselects the node formutara.yamlwhen the setup has several nodes.- The importer writes the node with the USB radio, or the node of
-asl3-node, tomutara.yaml. It writes each other node tomodules.d/<node>.yaml.
sudo mutara-switch asl3 stops Mutara and starts ASL3. sudo mutara-switch mutara does the opposite. The first time, it copies the ASL3 settings. To copy a different node, add its number: sudo mutara-switch mutara 2101. If Mutara does not start, it starts ASL3 again.
Web API #
These routes are documented for other programs. Other routes are for the dashboard and can change.
| Route | What it does |
|---|---|
GET /api/recordings | The list of clips, newest first, with id, start, duration_ms, talker, label, kind, size, type and url. |
GET /api/recordings/{id}/audio | The clip, with HTTP Range support. format=m4a sends Opus in MP4. download=1 asks the browser to save it. |
DELETE /api/recordings/{id} | Delete a clip. Admins only. |
/api/ws | The event stream. It sends a recording message when a clip is added or deleted. Each user, or each address of a visitor who is not signed in, can have at most 32 of these connections, and the node accepts 1024 in total. A connection over a limit closes with code 1013 and a reason. |
GET /api/me | The signed-in user and the rights. modules lists the nodes that the user may view, also when there is one, and can of each node has the twelve actions, bundles included, for example {"talk":true,"download":false}. The fields for the whole install (can_transmit, can_operate, can_chat and the others) are true when the user may do it on any node, for older apps. can_admin is an admin of the install. An older node sends only those fields, and modules only with more than one node, without can. "no_modules": true when the user has no node of the install. "theme" is the saved dashboard theme of the user, "dmr_id" the DMR ID and "callsign" the M17 callsign of the user. |
PUT /api/me/prefs | Save the preferences of the signed-in user, for example {"theme":"dark"}. The theme is system, light or dark. dmr_id (7 digits) and callsign (the M17 callsign) are optional. Signed-in users only. |
GET /api/status | The status of the first node. |
GET /api/modules | The nodes that the user can use, with their status. |
/api/m/{node}/… | Each dashboard route for one node, for example /api/m/2101/status. Another node of a limited user returns 403. A change to a stopped node returns 503. |
POST /api/modules/{node}/restart | Restart one node. Admins only. |
POST /api/modules | Add a module, for example {"type":"allstar","node":"2200"} or {"type":"ysf","id":"ysf-club","reflector":"host:port","local_number":"2350","link_module":"2100"}, or a DMR module with "type":"dmr", id, master, password, dmr_id, essid, timeslot, talkgroup, local_number and link_module. Admins only. |
DELETE /api/modules/{id} | Remove a module. Mutara keeps its state folder in modules/.removed/. You cannot remove the first module. Admins only. |
GET /api/lastheard | The last talkers and the activity of each module, for the module bar. ?module={id} gives the talkers of one module. ?scope=all gives one row for each callsign. |
GET /api/activity | The recent events of all the modules that you may see, newest first, up to 150. Each event has module and module_type. Add ?module= and a module ID for the events of one module. |
GET /api/scan/priority | The scan priority of each module that you may listen to, for example {"2101":{"default":90,"user":null,"effective":90}}. user is null when you use the default. |
PUT /api/scan/priority | {"module":"2101","user":20} sets your own value. "user":null removes it. An admin sends {"module":"2101","default":90} to set the default. The value is from 0 to 99. |
/api/m/{node}/bundles | The bundles of a node: list, make, change and delete them, get the audio and the zip, and make public links. /api/bundles is the same for the first node. A bundle gives can_edit, can_delete, can_links and can_download for the user. The zip needs download. Read Bundles and transcripts. |
POST /api/m/{node}/recordings/{id}/transcribe | Send one clip to speech to text. It needs bundles. The answer is 202. The recording event with op: "transcript" comes when the text is ready. |
GET /api/m/{node}/recordings/{id}/transcript | The transcript of a clip, with its parts and a confidence for each part. It needs clips. 404 means that the clip has no transcript. |
GET /api/share/{token} | A bundle as the holder of a public link sees it, with no account. Account names show as callsigns. /share/{token} is the web page. A link that ended or was revoked gives 404. |
/api/scan/audio | The scan stream, a WebSocket. It plays the active node of all the nodes of the user. Read The scan stream. |
A user with clips on the module can list and play its clips. Saving a clip (download=1 or format=m4a) needs download. The list says can_download and can_delete for the user, so a client shows only the buttons that work. An older node does not send can_download: take it as true. Other requests get 403. A client must play url with the media type in type, and must not make the URL itself.
The scan stream
Open /api/scan/audio?codec=opus or ?codec=ulaw as a WebSocket. You must be signed in with listen permission. hang= (2 to 30 seconds), skip_ids=1 and list=1 are optional start values. list=1 is Scan my list; without it, the scan is Scan all. The scan and the audio of a module count in the same limit: at most 8 audio connections for each user, and 256 in total. A connection over a limit closes with code 1013 and a reason.
- The audio frames, and the
pttandagcmessages, are the same as on the audio stream of one node. - The first message is
hello, with"where":"scan","protocol":1,mode(allorlist) and the list of nodes. - A
scanmessage comes when the scan changes. It givesmodule,state,active,skipped,waiting,priority,port_id,list(the modules of the scan now) andleft_out(the rooms of the list that the scan left out, with the reasonfullorremoved). The state isidle,active,hangortalk. prioritygives the priority of each module for this user.waitinglists the active modules with a higher priority that wait because you talk back, the best first.- A change of priority or of the scan list applies to an open scan at once. The scan does not connect again.
port_idis the port of the scan in the status of that node. It is empty when the scan is idle.- To control the scan, send
scan(withhang_sorskip_ids),skiporunskip.
PTT talks on the node that the scan plays. If the node refuses PTT, a ptt message gives the reason: scan_idle, scan_no_tx, scan_gone, limit or busy, and in a room stopped, interrupt or threshold. On a YSF module that is busy, busy comes with "where":"reflector" and the talker of the reflector. The README of the project has the full list of messages.