diff --git a/samba-backup/.devcontainer/devcontainer.json b/samba-backup/.devcontainer/devcontainer.json new file mode 100644 index 0000000..c894622 --- /dev/null +++ b/samba-backup/.devcontainer/devcontainer.json @@ -0,0 +1,26 @@ +{ + "name": "Samba Backup DevContainer", + "image": "ghcr.io/home-assistant/devcontainer:addons", + "appPort": ["7123:8123", "7357:4357"], + "postStartCommand": "bash devcontainer_bootstrap", + "runArgs": ["-e", "GIT_EDITOR=code --wait", "--privileged"], + "containerEnv": { + "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}" + }, + "extensions": ["timonwong.shellcheck", "esbenp.prettier-vscode"], + "mounts": [ "type=volume,target=/var/lib/docker" ], + "settings": { + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/usr/bin/zsh" + } + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "files.trimTrailingWhitespace": true + }, + "remoteUser": "root", + "containerUser": "root" +} diff --git a/samba-backup/.gitignore b/samba-backup/.gitignore new file mode 100644 index 0000000..dfe8a26 --- /dev/null +++ b/samba-backup/.gitignore @@ -0,0 +1,3 @@ +backup +data +start-local.sh diff --git a/samba-backup/.vscode/tasks.json b/samba-backup/.vscode/tasks.json new file mode 100644 index 0000000..1b6de80 --- /dev/null +++ b/samba-backup/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Home Assistant", + "type": "shell", + "command": "supervisor_run", + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + } + ] +} diff --git a/samba-backup/CHANGELOG.md b/samba-backup/CHANGELOG.md new file mode 100644 index 0000000..d3a7e53 --- /dev/null +++ b/samba-backup/CHANGELOG.md @@ -0,0 +1,153 @@ +# Changelog + +## 5.2.0 + +- Add dutch translation +- Fix incorrect sensor values during backup run +- Fix problem with reset-counter function +- Check current number of stored backups at startup + +## 5.1.2 + +- Add german and swedish translation +- Improve log output + +## 5.1.1 + +- Fix bug that add-on does not start without a log level + +## 5.1.0 + +- Implement necessary changes for Supervisor 2022.06 so that add-ons are considered in partial backups +- Add translations +- Update Alpine Linux to 3.16 +- Bump CLI version to 4.18.0 + +## 5.0.0 + +**Important**: You need to run supervisor 2021.08.0 or higher! + +- Replace deprecated supervisor API calls +- Rename snapshot -> backup +- Include date and improve logs +- Add support to reset the Home Assistant sensor +- Improve situation when backup could not be created +- Update Alpine Linux to 3.14 +- Bump CLI version to 4.13.0 + +## 4.5.0 + +- Increase timeout for smbclient +- Update password schema +- Update Alpine Linux to 3.13 +- Bump CLI version to 4.10.1 + +## 4.4.0 + +- Use snapshot names for the filenames on the share +- Remove ICMP requests and config option `no_icmp` +- Add support to skip the pre-checks on add-on startup + +## 4.3.0 + +- Remove mqtt support +- Add config option for the workgroup +- Add support to disable ICMP requests +- Bump CLI version to 4.9.0 + +## 4.2.0 + +- Fix supervisor warnings for partial snapshots +- Add support to exclude the media folder +- Bump CLI version to 4.7.0 + +## 4.1.0 + +- Improve and extend SMB pre-checks +- Update sensor if pre-check fails +- Remove mqtt listener + +## 4.0.0 + +- Include a Home Assistant sensor for status updates and statistics +- The add-on will no longer shut down in case of a failed backup +- MQTT support is now deprecated. Please switch to the new sensor +- Several minor improvements + +**Important**: If you have already a sensor called `Samba Backup` (sensor.samba_backup), please delete or at least rename it! + +## 3.1.0 + +- Add support for legacy SMB protocols + +## 3.0.0 + +- Support multiple triggers at once +- Introduce mqtt trigger +- Make configuration options overwritable for manual triggers + +## 2.6.0 + +- Fix config issues with dollar signs + +## 2.5.0 + +- Add support for external mqtt brokers +- Fix incorrect escaped user input + +## 2.4.0 + +- Fix config issues with spaces and special characters + +## 2.3.0 + +- Add mqtt support +- Publish current status via mqtt + +## 2.2.0 + +- Use dedicated log functions +- Control verbosity of logs +- Perform precheck on Samba share + +## 2.1.0 + +- Fix wrong HA version in name patterns + +## 2.0.0 + +- This is a breaking release! +- Samba Backup now cleans up all snapshots stored on the device +- Samba Backup is now running as a service in the background +- Support custom snapshot names including name patterns +- Support triggers out of the box without separate Home Assistant automations +- Support manual triggers for advanced use-cases + +## 1.5.0 + +- Improve remote cleanup functionality +- Make backup password optional + +## 1.4.0 + +- Add support for partial snapshots +- Minor improvements + +## 1.3.0 + +- Add support to clean up remote snapshots + +## 1.2.0 + +- Add support for password-protected snapshots + +## 1.1.0 + +- Add support to clean up local snapshots +- Minor improvements + +## 1.0.0 + +- Add support for add-on configuration +- Add support to create snapshots +- Add support to copy snapshots to remote Samba share diff --git a/samba-backup/DOCS.md b/samba-backup/DOCS.md new file mode 100644 index 0000000..87d1f05 --- /dev/null +++ b/samba-backup/DOCS.md @@ -0,0 +1,187 @@ +# Home Assistant Add-on: Samba Backup + +Create backups and store them on a Samba share. + +## Configuration Options + +### Option: `host` + +The hostname/URL of the Samba share. + +### Option: `share` + +The name of the Samba share. + +### Option: `target_dir` + +The target directory on the Samba share in which the backups will be stored. The directory must be a folder *inside* your share. Leave this option empty if you do not use sub folders and instead want the backups to be stored in the root directory. + +**Note**: _The directory must exist and write permissions must be granted._ + +### Option: `username` + +The username to access the Samba share. + +### Option: `password` + +The password to access the Samba share. + +### Option: `keep_local` + +The number of local backups to be preserved. Set `all` if you do not want to delete any backups. + +**Note**: _Backups that were not created with this add-on will be deleted as well._ + +### Option: `keep_remote` + +The number of backups to be preserved on the Samba share. Set `all` if you do not want to delete any backups. + +### Option: `trigger_time` + +The time at which a backup will be triggered. The input must be given in format 'HH:MM', e.g. '04:00' which means 4 am. You can additionally use your own Home Assistant automations to trigger a backup - see [Manual Triggers](https://github.com/thomasmauerer/hassio-addons/blob/master/samba-backup/DOCS.md#manual-triggers) for more information. If you want to disable the time-based schedule and only use your own automations, scripts, etc., set the option to `manual`. + +### Option: `trigger_days` + +The days on which a backup will be triggered. If `trigger_time` is set to `manual` this parameter will not have any effect. + +### Option: `exclude_addons` + +The slugs of add-ons to exclude in the backup. This will trigger a partial backup if specified. You can find out the correct slugs by clicking on an installed add-on and looking at the URL e.g. `core_ssh`. + +### Option: `exclude_folders` + +The folders to exclude in the backup. This will trigger a partial backup if specified. Possible values are `homeassistant`, `ssl`, `share`, `addons/local` and `media`. + +### Option: `backup_name` + +The custom name for the backups. You can either use a fixed text or include the following name patterns which will automatically be converted to its real values. + +- `{type}`: Full or Partial +- `{version}`: The current version of Home Assistant +- `{date}`: The current date and timestamp + +_Example_: "{type} Backup {version} {date}" might end up as "Full Backup 0.110.4 2020-06-05 12:00" + +### Option: `backup_password` + +If specified the backups will be password-protected. + +### Option: `workgroup` + +The workgroup to use for authentication. Only set this option if not using the default workgroup `WORKGROUP`. + +### Option: `compatibility_mode` + +Set this option to `true` if you need to connect to shares that only support old legacy SMB protocols. Note that this option is not recommended, since these protocols are known to be out-dated, insecure and slow. + +### Option: `skip_precheck` + +Set this option to `true` if you want to skip the checks about the availability/existance/permissions of the share. These checks are performed when the add-on starts. Only use this if you know what you are doing! Default value is `false`. + +### Option: `log_level` + +Controls the verbosity of log output produced by this add-on. Possible values are `debug`, `info` (default), `warning` and `error`. + + +## Home Assistant Sensor + +This add-on includes a sensor for Home Assistant which reflects the current status and additionally has some useful statistics within its attributes. No configuration is necessary in order to use the sensor. The name of the sensor is `sensor.samba_backup`. + + +The state of the sensor will be one of the following: + +- `IDLE`: Samba Backup is waiting for the trigger +- `RUNNING`: A backup is currently in progress +- `SUCCEEDED`: The backup was successful +- `FAILED`: The backup was not successful + + +The sensor includes the following attributes: + +- `backups local`: The current number of backups available on the device +- `backups remote`: The current number of backups available on the Samba share +- `total backups succeeded`: The total number of successful backups made with this add-on +- `total backups failed`: The total number of failed backups +- `last backup`: The date of the last successful backup + + +There is a known limitation that the sensor will be unavailable if you restart Home Assistant. This is caused by the way Home Assistant handles sensors which are not backed up by an entity, but instead come from an add-on or AppDaemon. You can easily fix that with the following blueprint: + +[![Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https://github.com/thomasmauerer/hassio-addons/blob/master/samba-backup/blueprints/restore_samba_backup_sensor.yaml) + +Or use this automation directly: + +```yaml +automation: +- alias: Restore Samba Backup sensor on startup + trigger: + - event: start + platform: homeassistant + action: + - service: hassio.addon_stdin + data: + addon: 15d21743_samba_backup + input: restore-sensor + mode: single +``` + +_Automation to restore the sensor when Home Assistant restarts_ + + +The `total backups failed` and `total backups succeeded` counters can be reset with the following script: + +```yaml +service: hassio.addon_stdin +data: + addon: 15d21743_samba_backup + input: reset-counter +``` + +_Reset counter variables_ + + + +## Manual Triggers + +Apart from a time-based schedule, this add-on also supports manual triggers from a Home Assistant automation or script. If you only want manual triggers, you can set `trigger_time` to `manual`. + +The easiest way to trigger a manual backup is by using the `hassio.addon_stdin` service call in a script: + +```yaml +service: hassio.addon_stdin +data: + addon: 15d21743_samba_backup + input: trigger +``` + +_Simple trigger_ + +The configuration options that directly affect the backup creation are overwritable for a single run: `exclude_addons`, `exclude_folders`, `backup_name` and `backup_password`. To overwrite any of these options, you have to use an extended syntax - `command` has to be `trigger`. See the following example: + +```yaml +service: hassio.addon_stdin +data: + addon: 15d21743_samba_backup + input: + command: trigger + backup_name: My overwritten backup name {date} + backup_password: some_pwd + exclude_addons: [core_mariadb, core_deconz] + exclude_folders: [ssl] +``` + +_Extended trigger_ + +## FAQ + +### Why is the sensor missing when I restart Home Assistant? + +This is a known limitation, but it can easily be fixed with an automation. See the [Home Assistant sensor](https://github.com/thomasmauerer/hassio-addons/blob/master/samba-backup/DOCS.md#home-assistant-sensor) section for more details. Apart from that, check that Samba Backup is really running after restart. If not the automation will not have any effect. + +### Can I use Samba Backup to upload backups to an online storage via the internet? + +Samba Backup is based on the SMB protocol, so as long as the online storage supports SAMBA/CIFS it is possible. However, keep in mind that some SMB implementations rely on NetBIOS which some routers block by default. Therefore it could be necessary to disable the NetBIOS filter in the router settings. + +### Why do I get this error at startup "Server does not support EXTENDED_SECURITY"? + +If you see this error in the logs, it means that your NAS only supports an outdated authentication mechanism which Samba Backup refuses. The SMB options to overcome this issue are already marked as deprecated and will be removed in the future. Hence, I will not add support for that. Please use a different NAS/share in this case. diff --git a/samba-backup/Dockerfile b/samba-backup/Dockerfile new file mode 100644 index 0000000..aa22c35 --- /dev/null +++ b/samba-backup/Dockerfile @@ -0,0 +1,20 @@ +ARG BUILD_FROM +FROM $BUILD_FROM + +ENV LANG C.UTF-8 + +# Copy script +COPY rootfs / + +# Setup base +ARG BUILD_ARCH +ARG CLI_VERSION +RUN \ + curl -Lso /usr/bin/ha "https://github.com/home-assistant/cli/releases/download/${CLI_VERSION}/ha_${BUILD_ARCH}" \ + && chmod a+x /usr/bin/ha \ + && apk add --no-cache \ + samba-client \ + && chmod a+x /run.sh + +# Run script +CMD [ "/run.sh" ] diff --git a/samba-backup/README.md b/samba-backup/README.md new file mode 100644 index 0000000..dd0f07f --- /dev/null +++ b/samba-backup/README.md @@ -0,0 +1,61 @@ +# Home Assistant Add-on: Samba Backup + +![Supports aarch64 Architecture][aarch64-shield] ![Supports amd64 Architecture][amd64-shield] ![Supports armhf Architecture][armhf-shield] ![Supports armv7 Architecture][armv7-shield] ![Supports i386 Architecture][i386-shield] + +![Current version][version] + +[](https://www.paypal.com/donate/?hosted_button_id=LP732BXWCKM3C) + +Create backups and store them on a Samba share. + +## About + +This add-on lets you automatically create Home Assistant backups and store them on a Samba share. This does work with Samba shares that require authentication by username/password or allow guest access. + +## Installation + +1. Navigate in your Home Assistant frontend to **Settings** -> **Add-ons** -> **Add-on Store** and add this URL as an additional repository: `https://github.com/thomasmauerer/hassio-addons` +2. Refresh your browser. +3. Find the "Samba Backup" add-on and click the "INSTALL" button. +4. Configure the add-on and click on "START". + +## Configuration + +The `host` and the `share` parameters are always required. If you do not specify any username and password, the Samba share has to be configured to allow guest access for this to work. + +_Example configuration_: + +```yaml +host: 192.168.178.100 +share: my-share +target_dir: backups/ha-backups +username: my-user +password: my-password +keep_local: 5 +keep_remote: 10 +trigger_time: 04:00 +trigger_days: + - Mon + - Wed + - Fri +exclude_addons: + - core_mariadb +exclude_folders: + - media +backup_name: {type} Backup {date} +``` + +**Note**: _This is just an example, don't copy and paste it! Create your own!_ + +Please check the **[Documentation](https://github.com/thomasmauerer/hassio-addons/blob/master/samba-backup/DOCS.md)** for a complete reference of all configuration options. + +## Want to contribute? + +Any kind of help or useful input/feedback is appreciated! Please also check the [forum thread](https://community.home-assistant.io/t/samba-backup-create-and-store-snapshots-on-a-samba-share/199471) of this add-on for infos and discussions. + +[aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg +[amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg +[armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg +[armv7-shield]: https://img.shields.io/badge/armv7-yes-green.svg +[i386-shield]: https://img.shields.io/badge/i386-yes-green.svg +[version]: https://img.shields.io/badge/version-v5.2.0-blue.svg diff --git a/samba-backup/blueprints/restore_samba_backup_sensor.yaml b/samba-backup/blueprints/restore_samba_backup_sensor.yaml new file mode 100644 index 0000000..eac59c8 --- /dev/null +++ b/samba-backup/blueprints/restore_samba_backup_sensor.yaml @@ -0,0 +1,22 @@ +blueprint: + name: Restore Samba Backup sensor on startup + description: Restore Samba Backup sensor on startup + domain: automation + input: + addon: + name: Samba Backup Addon + description: Select samba backup addon. + selector: + addon: + +mode: single + +trigger: + - event: start + platform: homeassistant + +action: + - service: hassio.addon_stdin + data: + addon: !input addon + input: restore-sensor diff --git a/samba-backup/build.sh b/samba-backup/build.sh new file mode 100755 index 0000000..fe0c707 --- /dev/null +++ b/samba-backup/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --rm --privileged -v ~/.docker:/root/.docker -v /var/run/docker.sock:/var/run/docker.sock:ro -v $(pwd):/data homeassistant/amd64-builder --all -t /data diff --git a/samba-backup/build.yaml b/samba-backup/build.yaml new file mode 100644 index 0000000..d16f6fe --- /dev/null +++ b/samba-backup/build.yaml @@ -0,0 +1,9 @@ +--- +build_from: + aarch64: ghcr.io/hassio-addons/base/aarch64:12.0.0 + amd64: ghcr.io/hassio-addons/base/amd64:12.0.0 + armhf: ghcr.io/hassio-addons/base/armhf:12.0.0 + armv7: ghcr.io/hassio-addons/base/armv7:12.0.0 + i386: ghcr.io/hassio-addons/base/i386:12.0.0 +args: + CLI_VERSION: 4.18.0 diff --git a/samba-backup/config.yaml b/samba-backup/config.yaml new file mode 100644 index 0000000..403faa0 --- /dev/null +++ b/samba-backup/config.yaml @@ -0,0 +1,62 @@ +--- +name: Samba Backup +version: 5.2.0 +slug: samba_backup +description: Create backups and store them on a Samba share +url: https://github.com/thomasmauerer/hassio-addons/tree/master/samba-backup +arch: + - armhf + - armv7 + - aarch64 + - amd64 + - i386 +startup: application +boot: auto +homeassistant_api: true +hassio_api: true +hassio_role: manager +stdin: true +map: + - backup:rw +image: thomasmauerer/samba-backup-{arch} +init: false +options: + host: null + share: null + target_dir: "" + username: "" + password: "" + keep_local: all + keep_remote: all + trigger_time: 00:00 + trigger_days: + - Mon + - Tue + - Wed + - Thu + - Fri + - Sat + - Sun + exclude_addons: [] + exclude_folders: [] +schema: + host: str + share: str + target_dir: str + username: str + password: password + keep_local: match(^(all|[0-9]+)$) + keep_remote: match(^(all|[0-9]+)$) + trigger_time: match(^(manual|([0-1][0-9]|2[0-3]):[0-5][0-9])$) + trigger_days: + - match(Mon|Tue|Wed|Thu|Fri|Sat|Sun) + exclude_addons: + - str + exclude_folders: + - str + backup_name: str? + backup_password: str? + workgroup: str? + compatibility_mode: bool? + skip_precheck: bool? + log_level: list(debug|info|warning|error)? diff --git a/samba-backup/icon.png b/samba-backup/icon.png new file mode 100644 index 0000000..8bf2f65 Binary files /dev/null and b/samba-backup/icon.png differ diff --git a/samba-backup/images/donate-paypal.svg b/samba-backup/images/donate-paypal.svg new file mode 100644 index 0000000..79c3609 --- /dev/null +++ b/samba-backup/images/donate-paypal.svg @@ -0,0 +1,91 @@ + + + + + + + paypal-seeklogo.com + + + + + + + + Donate with + + diff --git a/samba-backup/rootfs/run.sh b/samba-backup/rootfs/run.sh new file mode 100644 index 0000000..354792c --- /dev/null +++ b/samba-backup/rootfs/run.sh @@ -0,0 +1,88 @@ +#!/command/with-contenv bashio +# shellcheck shell=bash +# shellcheck disable=SC1091 + +source scripts/config.sh +source scripts/main.sh +source scripts/helper.sh +source scripts/precheck.sh +source scripts/sensor.sh + +export __BASHIO_LOG_TIMESTAMP="%y-%m-%d %T" + +function run-backup { + ( + # synchronize the backup routine + flock -n -x 200 || { bashio::log.warning "Backup already running. Trigger ignored."; return 0; } + + bashio::log.info "Backup running ..." + get-sensor + update-sensor "${SAMBA_STATUS[1]}" + + # run entire backup steps + # shellcheck disable=SC2015 + create-backup && copy-backup && cleanup-backups-local && cleanup-backups-remote \ + && update-sensor "${SAMBA_STATUS[2]}" "ALL" \ + || update-sensor "${SAMBA_STATUS[3]}" "ALL" + + sleep 10 + update-sensor "${SAMBA_STATUS[0]}" + bashio::log.info "Backup finished" + ) 200>/tmp/samba_backup.lockfile +} + + +# init config and sensor +get-config +get-sensor + +# run precheck and exit entire addon in case the check fails +if [ "$SKIP_PRECHECK" = true ]; then + update-sensor "${SAMBA_STATUS[0]}" +elif ! smb-precheck; then + update-sensor "${SAMBA_STATUS[3]}" + exit 1 +else + update-sensor "${SAMBA_STATUS[0]}" "ALL" +fi + +bashio::log.info "Samba Backup started successfully" + +# check the time in the background +if [[ "$TRIGGER_TIME" != "manual" ]]; then + { + bashio::log.debug "Starting main loop ..." + while true; do + current_date=$(date +'%a %H:%M') + [[ "$TRIGGER_DAYS" =~ ${current_date:0:3} && "$current_date" =~ $TRIGGER_TIME ]] && run-backup + + sleep 60 + done + } & +fi + +# start the stdin listener in foreground +bashio::log.debug "Starting stdin listener ..." +while true; do + read -r input + bashio::log.debug "Input received: ${input}" + input=$(echo "$input" | jq -r .) + + if [ "$input" = "restore-sensor" ]; then + restore-sensor + + elif [ "$input" = "reset-counter" ]; then + get-sensor && reset-counter + bashio::log.info "Counter variables reset successfully" + + elif [ "$input" = "trigger" ]; then + run-backup + + elif is-extended-trigger "$input"; then + bashio::log.info "Running backup with customized parameters" + overwrite-params "$input" && run-backup && restore-params + + else + bashio::log.warning "Received unknown input: ${input}" + fi +done diff --git a/samba-backup/rootfs/scripts/config.sh b/samba-backup/rootfs/scripts/config.sh new file mode 100644 index 0000000..6f5292a --- /dev/null +++ b/samba-backup/rootfs/scripts/config.sh @@ -0,0 +1,131 @@ +#!/command/with-contenv bashio +# shellcheck shell=bash +# shellcheck disable=SC2034 + +# user input variables +declare TARGET_DIR +declare KEEP_LOCAL +declare KEEP_REMOTE +declare TRIGGER_TIME +declare TRIGGER_DAYS +declare EXCLUDE_ADDONS +declare EXCLUDE_FOLDERS +declare BACKUP_NAME +declare BACKUP_PWD +declare SKIP_PRECHECK + + +# smbclient command strings +declare SMB +declare ALL_SHARES + + +# ------------------------------------------------------------------------------ +# Read and print config. +# ------------------------------------------------------------------------------ +function get-config { + local host + local share + local username + local password + local workgroup + + host=$(bashio::config 'host' | escape-input) + share=$(bashio::config 'share' | escape-input) + username=$(bashio::config 'username' | escape-input) + password=$(bashio::config 'password' | escape-input) + bashio::config.exists 'workgroup' && workgroup=$(bashio::config 'workgroup' | escape-input) || workgroup="" + + TARGET_DIR=$(bashio::config 'target_dir') + KEEP_LOCAL=$(bashio::config 'keep_local') + KEEP_REMOTE=$(bashio::config 'keep_remote') + TRIGGER_TIME=$(bashio::config 'trigger_time') + TRIGGER_DAYS=$(bashio::config 'trigger_days') + EXCLUDE_ADDONS=$(bashio::config 'exclude_addons') + EXCLUDE_FOLDERS=$(bashio::config 'exclude_folders') + + bashio::config.exists 'backup_name' && BACKUP_NAME=$(bashio::config 'backup_name') || BACKUP_NAME="" + bashio::config.exists 'backup_password' && BACKUP_PWD=$(bashio::config 'backup_password') || BACKUP_PWD="" + bashio::config.true 'skip_precheck' && SKIP_PRECHECK=true || SKIP_PRECHECK=false + + if [[ -n "$username" && -n "$password" ]]; then + SMB="smbclient -U \"${username}\"%\"${password}\" \"//${host}/${share}\" 2>&1 -t 180" + ALL_SHARES="smbclient -U \"${username}\"%\"${password}\" -L \"//${host}\" 2>&1" + else + SMB="smbclient -N \"//${host}/${share}\" 2>&1 -t 180" + ALL_SHARES="smbclient -N -L \"//${host}\" 2>&1" + fi + + # non-default workgroup? + [ -n "$workgroup" ] && SMB="${SMB} -W \"${workgroup}\"" + [ -n "$workgroup" ] && ALL_SHARES="${ALL_SHARES} -W \"${workgroup}\"" + + # legacy SMB protocols allowed? + bashio::config.true 'compatibility_mode' && SMB="${SMB} --option=\"client min protocol\"=\"NT1\"" + bashio::config.true 'compatibility_mode' && ALL_SHARES="${ALL_SHARES} --option=\"client min protocol\"=\"NT1\"" + + bashio::log.info "---------------------------------------------------" + bashio::log.info "Host/Share: ${host}/${share}" + bashio::log.info "Target directory: ${TARGET_DIR}" + bashio::log.info "Keep local/remote: ${KEEP_LOCAL}/${KEEP_REMOTE}" + bashio::log.info "Trigger time: ${TRIGGER_TIME}" + [[ "$TRIGGER_TIME" != "manual" ]] && bashio::log.info "Trigger days: $(echo "$TRIGGER_DAYS" | xargs)" + bashio::log.info "---------------------------------------------------" + + return 0 +} + +# ------------------------------------------------------------------------------ +# Escape input given by the user. +# +# Returns the escaped string on stdout +# ------------------------------------------------------------------------------ +function escape-input { + local input + read -r input + + # escape the evil dollar sign + input=${input//$/\\$} + + echo "$input" +} + +# ------------------------------------------------------------------------------ +# Overwrite the backup parameters. +# +# Arguments +# $1 The json input string +# ------------------------------------------------------------------------------ +function overwrite-params { + local input="$1" + local addons + local folders + local name + local password + + addons=$(echo "$input" | jq '.exclude_addons[]' 2>/dev/null) + [[ "$addons" != null ]] && EXCLUDE_ADDONS="$addons" + + folders=$(echo "$input" | jq '.exclude_folders[]' 2>/dev/null) + [[ "$folders" != null ]] && EXCLUDE_FOLDERS="$folders" + + name=$(echo "$input" | jq -r '.backup_name') + [[ "$name" != null ]] && BACKUP_NAME="$name" + + password=$(echo "$input" | jq -r '.backup_password') + [[ "$password" != null ]] && BACKUP_PWD="$password" + + return 0 +} + +# ------------------------------------------------------------------------------ +# Restore the original backup parameters. +# ------------------------------------------------------------------------------ +function restore-params { + EXCLUDE_ADDONS=$(bashio::config 'exclude_addons') + EXCLUDE_FOLDERS=$(bashio::config 'exclude_folders') + bashio::config.exists 'backup_name' && BACKUP_NAME=$(bashio::config 'backup_name') || BACKUP_NAME="" + bashio::config.exists 'backup_password' && BACKUP_PWD=$(bashio::config 'backup_password') || BACKUP_PWD="" + + return 0 +} diff --git a/samba-backup/rootfs/scripts/helper.sh b/samba-backup/rootfs/scripts/helper.sh new file mode 100644 index 0000000..4d6abda --- /dev/null +++ b/samba-backup/rootfs/scripts/helper.sh @@ -0,0 +1,93 @@ +#!/command/with-contenv bashio +# shellcheck shell=bash + +# ------------------------------------------------------------------------------ +# Create the backup name by replacing all name patterns. +# +# Returns the final name on stdout +# ------------------------------------------------------------------------------ +function generate-backup-name { + local name + local theversion + local thetype + local thedate + + if [ -n "$BACKUP_NAME" ]; then + # get all values + theversion=$(ha core info --raw-json | jq -r .data.version) + [[ -n "$EXCLUDE_ADDONS" || -n "$EXCLUDE_FOLDERS" ]] && thetype="Partial" || thetype="Full" + thedate=$(date +'%Y-%m-%d %H:%M') + + # replace the string patterns with the real values + name="$BACKUP_NAME" + name=${name/\{version\}/$theversion} + name=${name/\{type\}/$thetype} + name=${name/\{date\}/$thedate} + else + name="Samba Backup $(date +'%Y-%m-%d %H:%M')" + fi + + echo "$name" +} + +# ------------------------------------------------------------------------------ +# Create a valid filename by replacing all forbidden characters. +# +# Arguments +# $1 The original name +# +# Returns the final name on stdout +# ------------------------------------------------------------------------------ +function generate-filename { + local input="${1}" + local prefix + + declare -a forbidden=('\/' '\\' '\<' '\>' '\:' '\"' '\|' '\?' '\*' '\.' '\..' '\ ' '\-') + for fc in "${forbidden[@]}"; do + input=${input//$fc/_} + done + + prefix=${input:0:13} + [ "$prefix" = "Samba_Backup_" ] && echo "${input}" || echo "Samba_Backup_${input}" +} + +# ------------------------------------------------------------------------------ +# Run a command and log its output (debug or warning). +# +# Arguments +# $1 The command to run +# +# Returns 1 in case the command failed +# ------------------------------------------------------------------------------ +function run-and-log { + local cmd="$1" + local result + + if result=$(eval "$cmd"); then + [ -n "$result" ] && bashio::log.debug "$result" + else + bashio::log.warning "$result" + return 1 + fi + + return 0 +} + +# ------------------------------------------------------------------------------ +# Checks if input is an extended trigger. +# +# Arguments +# $1 The input to check +# +# Returns 0 (true) or 1 (false) +# ------------------------------------------------------------------------------ +function is-extended-trigger { + local input=${1} + local cmd + + if cmd=$(echo "$input" | jq -r '.command' 2>/dev/null); then + [ "$cmd" = "trigger" ] && return 0 + fi + + return 1 +} diff --git a/samba-backup/rootfs/scripts/main.sh b/samba-backup/rootfs/scripts/main.sh new file mode 100644 index 0000000..f4ffe86 --- /dev/null +++ b/samba-backup/rootfs/scripts/main.sh @@ -0,0 +1,110 @@ +#!/command/with-contenv bashio +# shellcheck shell=bash + +declare SLUG +declare SNAP_NAME + + +# ------------------------------------------------------------------------------ +# Create a new backup (full or partial). +# ------------------------------------------------------------------------------ +function create-backup { + local args + local addons + local folders + + SNAP_NAME=$(generate-backup-name) + + args=() + args+=("--name" "$SNAP_NAME") + [ -n "$BACKUP_PWD" ] && args+=("--password" "$BACKUP_PWD") + + # do we need a partial backup? + if [[ -n "$EXCLUDE_ADDONS" || -n "$EXCLUDE_FOLDERS" ]]; then + # include all installed addons that are not listed to be excluded + addons=$(ha addons --raw-json | jq -rc '.data.addons[] | select (.installed != false) | .slug') + for ad in ${addons}; do [[ ! $EXCLUDE_ADDONS =~ $ad ]] && args+=("-a" "$ad"); done + + # include all folders that are not listed to be excluded + folders=(homeassistant ssl share addons/local media) + for fol in "${folders[@]}"; do [[ ! $EXCLUDE_FOLDERS =~ $fol ]] && args+=("-f" "$fol"); done + fi + + # run the command + bashio::log.info "Creating backup \"${SNAP_NAME}\"" + SLUG="$(ha backups new "${args[@]}" --raw-json | jq -r .data.slug)" +} + +# ------------------------------------------------------------------------------ +# Copy the latest backup to the remote share. +# ------------------------------------------------------------------------------ +function copy-backup { + local store_name + local input + local count + + if [ "$SLUG" = "null" ]; then + bashio::log.error "Error occurred! Backup could not be created! Please try again" + return 1 + fi + + store_name=$(generate-filename "$SNAP_NAME") + + # append number to filename if already existing + input="$(eval "${SMB} -c 'cd \"${TARGET_DIR}\"; ls'")" + count=$(echo "$input" | grep "\<$store_name.*\.tar\>" | wc -l) + (( "$count" > 0 )) && store_name="${store_name}${count}.tar" || store_name="${store_name}.tar" + + bashio::log.info "Copying backup ${SLUG} (${store_name}) to share" + cd /backup || return 1 + + if ! run-and-log "${SMB} -c 'cd \"${TARGET_DIR}\"; put ${SLUG}.tar ${store_name}'"; then + bashio::log.warning "Could not copy backup ${SLUG} to share. Trying again ..." + sleep 5 + run-and-log "${SMB} -c 'cd \"${TARGET_DIR}\"; put ${SLUG}.tar ${store_name}'" + fi +} + +# ------------------------------------------------------------------------------ +# Delete old local backups. +# ------------------------------------------------------------------------------ +function cleanup-backups-local { + local snaps + local slug + local name + + [ "$KEEP_LOCAL" == "all" ] && return 0 + + snaps=$(ha backups --raw-json | jq -c '.data.backups[] | {date,slug,name}' | sort -r) + bashio::log.debug "List of local backups:\n$snaps" + + echo "$snaps" | tail -n +$((KEEP_LOCAL + 1)) | while read -r backup; do + slug=$(echo "$backup" | jq -r .slug) + name=$(echo "$backup" | jq -r .name) + bashio::log.info "Deleting ${slug} (${name}) local" + run-and-log "ha backups remove ${slug}" + done +} + +# ------------------------------------------------------------------------------ +# Delete old backups on the share. +# ------------------------------------------------------------------------------ +function cleanup-backups-remote { + local input + local snaps + + [ "$KEEP_REMOTE" == "all" ] && return 0 + + # read all tar files that match the backup name pattern and sort them + input="$(eval "${SMB} -c 'cd \"${TARGET_DIR}\"; ls'")" + snaps="$(echo "$input" | grep -E '\<([0-9a-f]{8}|Samba_Backup_.*)\.tar\>' | while read -r name _ _ _ a b c d; do + theDate=$(echo "$a $b $c $d" | xargs -i date +'%Y-%m-%d %H:%M' -d "{}") + echo "$theDate $name" + done | sort -r)" + bashio::log.debug "List of remote backups:\n$snaps" + + echo "$snaps" | tail -n +$((KEEP_REMOTE + 1)) | while read -r _ _ name; do + bashio::log.info "Deleting ${name} on share" + run-and-log "${SMB} -c 'cd \"${TARGET_DIR}\"; rm ${name}'" + done +} diff --git a/samba-backup/rootfs/scripts/precheck.sh b/samba-backup/rootfs/scripts/precheck.sh new file mode 100644 index 0000000..ff7da02 --- /dev/null +++ b/samba-backup/rootfs/scripts/precheck.sh @@ -0,0 +1,71 @@ +#!/command/with-contenv bashio +# shellcheck shell=bash + +# ------------------------------------------------------------------------------ +# Perform a pre-check if the Samba share is configured correctly. +# +# Returns 1 in case of a failure +# ------------------------------------------------------------------------------ +function smb-precheck { + local result + local shares + + # check if we can access the share at all + if ! result=$(eval "${SMB} -c 'exit'"); then + bashio::log.warning "$result" + + # host not found + if [[ "$result" =~ "NT_STATUS_NOT_FOUND" ]]; then + bashio::log.fatal "The provided host cannot be found. If you've specified a DNS name, please try using an IP address instead." + + # host unreachable + elif [[ "$result" =~ "NT_STATUS_HOST_UNREACHABLE" ]]; then + bashio::log.fatal "The provided host is unreachable. Please check your config and network." + + # SMB1 problem + elif [[ "$result" =~ "NT_STATUS_CONNECTION_DISCONNECTED" ]]; then + bashio::log.fatal "Cannot access share. It seems that your share only supports insecure SMB protocols." + bashio::log.fatal "If you want me to connect, please check the \"compatibility_mode\" option. Use at your own risk." + + # share does not exist + elif [[ "$result" =~ "NT_STATUS_BAD_NETWORK_NAME" ]]; then + bashio::log.fatal "Cannot access share. It seems that your configured share does not exist." + + # try to find out which shares exist + if shares=$(eval "${ALL_SHARES}"); then + bashio::log.fatal "I found the following shares on your host. Did you mean one of those?" + bashio::log.fatal "$shares" + fi + + # access denied + elif [[ "$result" =~ "NT_STATUS_ACCESS_DENIED" ]]; then + bashio::log.fatal "Cannot access share. Access denied. Please check your share permissions." + + # login failed + elif [[ "$result" =~ "NT_STATUS_LOGON_FAILURE" ]]; then + bashio::log.fatal "Cannot access share. Login failed. Please check your credentials." + + # unknown reason + else + bashio::log.fatal "Cannot access share. Unknown reason." + fi + + return 1 + fi + + # check if the target directory exists + if ! run-and-log "${SMB} -c 'cd \"${TARGET_DIR}\"'"; then + bashio::log.fatal "Target directory does not exist. Please check your config." + return 1 + fi + + # check if we have write permissions + touch samba-tmp123 + if ! run-and-log "${SMB} -c 'cd \"${TARGET_DIR}\"; put samba-tmp123; rm samba-tmp123'"; then + bashio::log.fatal "Missing write permissions on target folder. Please check your share settings." + return 1 + fi + rm samba-tmp123 + + return 0 +} diff --git a/samba-backup/rootfs/scripts/sensor.sh b/samba-backup/rootfs/scripts/sensor.sh new file mode 100644 index 0000000..75dd12c --- /dev/null +++ b/samba-backup/rootfs/scripts/sensor.sh @@ -0,0 +1,190 @@ +#!/command/with-contenv bashio +# shellcheck shell=bash + +declare SAMBA_STATUS=(IDLE RUNNING SUCCEEDED FAILED) +declare SENSOR_NAME="sensor.samba_backup" +declare SENSOR_URL="/core/api/states/${SENSOR_NAME}" +declare STORAGE_FILE="/backup/.samba_backup.sensor" + +declare CURRENT_STATUS + +declare BACKUPS_LOCAL="0" +declare BACKUPS_REMOTE="0" +declare TOTAL_SUCCESS="0" +declare TOTAL_FAIL="0" +declare LAST_BACKUP="never" + + +# ------------------------------------------------------------------------------ +# Get the current sensor values and store them in internal variables. +# ------------------------------------------------------------------------------ +function get-sensor { + local storage + local result + + if [ -f "$STORAGE_FILE" ]; then + storage=$(cat "$STORAGE_FILE") + + if result=$(echo "$storage" | jq -r ".attributes.backups_local" 2>/dev/null); then + [[ "$result" != null ]] && BACKUPS_LOCAL="$result" + fi + + if result=$(echo "$storage" | jq -r ".attributes.backups_remote" 2>/dev/null); then + [[ "$result" != null ]] && BACKUPS_REMOTE="$result" + fi + + if result=$(echo "$storage" | jq -r ".attributes.total_backups_succeeded" 2>/dev/null); then + [[ "$result" != null ]] && TOTAL_SUCCESS="$result" + fi + + if result=$(echo "$storage" | jq -r ".attributes.total_backups_failed" 2>/dev/null); then + [[ "$result" != null ]] && TOTAL_FAIL="$result" + fi + + if result=$(echo "$storage" | jq -r ".attributes.last_backup" 2>/dev/null); then + [[ "$result" != null ]] && LAST_BACKUP="$result" + fi + fi + + bashio::log.debug "Backups local/remote: ${BACKUPS_LOCAL}/${BACKUPS_REMOTE}" + bashio::log.debug "Total backups succeeded/failed: ${TOTAL_SUCCESS}/${TOTAL_FAIL}" + bashio::log.debug "Last backup: ${LAST_BACKUP}" + + return 0 +} + +# ------------------------------------------------------------------------------ +# Update the Home Assistant sensor. +# +# Arguments +# $1 The status +# $2 Whether to update all values +# ------------------------------------------------------------------------------ +function update-sensor { + local status=${1} + local all=${2:-} + local data + local response + + CURRENT_STATUS="$status" + + if bashio::var.has_value "${all}"; then + if response=$(ha backups --raw-json | jq ".data.backups[].slug"); then + [ -n "$response" ] && BACKUPS_LOCAL=$(echo "$response" | wc -l) || BACKUPS_LOCAL="0" + fi + + if response=$(eval "${SMB} -c 'cd \"${TARGET_DIR}\"; ls'"); then + # grep returns non-zero exit code if there are no matches + if response=$(echo "$response" | grep -E '\<([0-9a-f]{8}|Samba_Backup_.*)\.tar\>'); then + BACKUPS_REMOTE=$(echo "$response" | wc -l) + else + BACKUPS_REMOTE="0" + fi + fi + + if [ "$CURRENT_STATUS" = "${SAMBA_STATUS[2]}" ]; then + TOTAL_SUCCESS=$((TOTAL_SUCCESS + 1)) + LAST_BACKUP=$(date +'%Y-%m-%d %H:%M') + elif [ "$CURRENT_STATUS" = "${SAMBA_STATUS[3]}" ]; then + TOTAL_FAIL=$((TOTAL_FAIL + 1)) + fi + fi + + data=$(jq -n \ + --arg s "$CURRENT_STATUS" \ + --arg bl "$BACKUPS_LOCAL" \ + --arg br "$BACKUPS_REMOTE" \ + --arg ts "$TOTAL_SUCCESS" \ + --arg tf "$TOTAL_FAIL" \ + --arg lb "$LAST_BACKUP" \ + '{ + "state": $s, + "attributes": { + "friendly_name": "Samba Backup", + "backups_local": $bl, + "backups_remote": $br, + "total_backups_succeeded": $ts, + "total_backups_failed": $tf, + "last_backup": $lb + } + }') + + if ! response=$(ha-post-sensor "$data"); then + bashio::log.error "Unable to update sensor ${SENSOR_NAME} in Home Assistant" + fi + + echo "$data" > "$STORAGE_FILE" + return 0 +} + +# ------------------------------------------------------------------------------ +# Restore the Home Assistant sensor with the last known values. +# ------------------------------------------------------------------------------ +function restore-sensor { + local data + local response + + if [ -f "$STORAGE_FILE" ]; then + data=$(cat "$STORAGE_FILE") + + if ! response=$(ha-post-sensor "$data"); then + bashio::log.error "Unable to restore sensor ${SENSOR_NAME} in Home Assistant" + fi + fi + + return 0 +} + +# ------------------------------------------------------------------------------ +# Reset the counter variables of the Home Assistant sensor. +# ------------------------------------------------------------------------------ +function reset-counter { + TOTAL_SUCCESS="0" + TOTAL_FAIL="0" + + update-sensor "$CURRENT_STATUS" + return 0 +} + + +# ------------------------------------------------------------------------------ +# ----------------------- INTERNAL FUNCTION ------------------------------------ +# ------------------------------------------------------------------------------ +# Post a sensor via the REST API of Home Assistant. +# +# Arguments: +# $1 The JSON data to POST +# ------------------------------------------------------------------------------ +function ha-post-sensor { + local data=${1} + local status + local response + + bashio::log.debug "Posting sensor data to API at ${SENSOR_URL}" + + if ! response=$(curl --silent --show-error \ + --write-out '\n%{http_code}' --request "POST" \ + -H "Authorization: Bearer ${__BASHIO_SUPERVISOR_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "${data}" \ + "${__BASHIO_SUPERVISOR_API}${SENSOR_URL}" + ); then + bashio::log.debug "${response}" + bashio::log.error "Something went wrong contacting the API" + return 1 + fi + + status=${response##*$'\n'} + response=${response%$status} + + bashio::log.debug "API Status: ${status}" + bashio::log.debug "API Response: ${response}" + + if [[ "${status}" -eq 401 ]]; then + bashio::log.error "Unable to authenticate with the API, permission denied" + return 1 + fi + + echo "${response}" + return 0 +} diff --git a/samba-backup/translations/de.yaml b/samba-backup/translations/de.yaml new file mode 100644 index 0000000..9ed05f2 --- /dev/null +++ b/samba-backup/translations/de.yaml @@ -0,0 +1,52 @@ +configuration: + host: + name: Host Adresse + description: DNS Name oder IP Adresse des Hostsystems, NAS, etc. auf dem die Samba Freigabe eingerichtet wurde. + share: + name: Freigabe + description: Name der Samba Freigabe. + target_dir: + name: Zielverzeichnis + description: Verzeichnis innerhalb der Freigabe, in dem Sicherungen abgelegt werden. + username: + name: Benutzername + description: Benutzername für die Samba Freigabe. + password: + name: Passwort + description: Passwort für die Samba Freigabe. + keep_local: + name: Lokal behalten + description: Anzahl der Sicherungen, die lokal in Home Assistant erhalten bleiben. + keep_remote: + name: Remote behalten + description: Anzahl der Sicherungen, die im freigegebenen Verzeichnis erhalten bleiben. + trigger_time: + name: Sicherungszeitpunkt + description: Zeitpunkt (Format HH:MM) für die Erstellung einer Sicherung. + trigger_days: + name: Sicherungstage + description: Tage an denen eine Sicherung erstellt wird. + exclude_addons: + name: Add-ons ausschließen + description: Liste an Add-ons, die nicht gesichert werden. + exclude_folders: + name: Ordner ausschließen + description: Liste an Ordnern, die nicht gesichert werden. + backup_name: + name: Sicherungsname + description: Name der Sicherung. + backup_password: + name: Sicherungspasswort + description: Passwort mit dem die Sicherung geschützt wird. + workgroup: + name: Arbeitsgruppe + description: Arbeitsgruppe für den Zugriff auf die Samba Freigabe. + compatibility_mode: + name: Kompatibilitätsmodus + description: Schaltet Unterstützung für alte Legacy SMB Protokolle ein. NICHT empfohlen! + skip_precheck: + name: Checks überspringen + description: Startet das Add-on ohne Checks ob die Samba Freigabe korrekt eingerichtet wurde. + log_level: + name: Log Level + description: Steuert wie viele Log Einträge das Add-on schreibt. diff --git a/samba-backup/translations/en.yaml b/samba-backup/translations/en.yaml new file mode 100644 index 0000000..cfd9cfe --- /dev/null +++ b/samba-backup/translations/en.yaml @@ -0,0 +1,53 @@ +--- +configuration: + host: + name: Host + description: The DNS or IP address of the Samba share, NAS, etc. + share: + name: Share + description: The name of the share. + target_dir: + name: Target directory + description: The directory inside the share where the backups will be stored. + username: + name: Username + description: The username to access the Samba share. + password: + name: Password + description: The password to access the Samba share. + keep_local: + name: Keep local + description: The number of backups to be preserved on the device. + keep_remote: + name: Keep remote + description: The number of backups to be preserved on the share. + trigger_time: + name: Trigger time + description: The time (format HH:MM) at which a backup will be triggered. + trigger_days: + name: Trigger days + description: The days on which a backup will be triggered. + exclude_addons: + name: Exclude add-ons + description: A list of add-ons to be excluded in the backup. + exclude_folders: + name: Exclude folders + description: A list of folders to be excluded in the backup. + backup_name: + name: Backup name + description: The name of the backup. + backup_password: + name: Backup password + description: If specified, the backups will be password protected. + workgroup: + name: Workgroup + description: The workgroup to access the Samba share. + compatibility_mode: + name: Compatibility mode + description: Enables old legacy SMB protocols. NOT recommended! + skip_precheck: + name: Skip precheck + description: Starts the addon without any checks whether the share is set up correctly. + log_level: + name: Log level + description: Sets the verbosity of log output. diff --git a/samba-backup/translations/nl.yaml b/samba-backup/translations/nl.yaml new file mode 100644 index 0000000..d0d6128 --- /dev/null +++ b/samba-backup/translations/nl.yaml @@ -0,0 +1,53 @@ +--- +configuration: + host: + name: Host + description: Het DNS- of IP-adres van de Samba-share, NAS, enz. + share: + name: Share + description: De naam van de share. + target_dir: + name: Doelmap + description: De map binnen de share waar de back-ups worden opgeslagen. + username: + name: Gebruikersnaam + description: De gebruikersnaam voor toegang tot de Samba-share. + password: + name: Wachtwoord + description: Het wachtwoord voor toegang tot de Samba-share. + keep_local: + name: Keep local + description: Het aantal te bewaren back-ups op het apparaat. + keep_remote: + name: Keep remote + description: Het aantal te bewaren back-ups op de share. + trigger_time: + name: Triggertijd + description: De tijd (formaat HH:MM) waarop een back-up wordt getriggerd. + trigger_days: + name: Trigger days + description: De dagen waarop een back-up zal worden getriggerd. + exclude_addons: + name: Uitsluiten add-ons + description: Een lijst met add-ons die moeten worden uitgesloten in de back-up. + exclude_folders: + name: Mappen uitsluiten + description: Een lijst met mappen die in de back-up moeten worden uitgesloten. + backup_name: + name: Naam van de back-up + description: De naam van de back-up. + backup_password: + name: Back-up wachtwoord + description: Indien opgegeven, worden de back-ups beveiligd met een wachtwoord. + workgroup: + name: Werkgroep + description: De werkgroep voor toegang tot de Samba-share. + compatibility_mode: + name: Compatibiliteitsmodus + description: Schakelt oude legacy SMB protocollen in. NIET aanbevolen! + skip_precheck: + name: Skip precheck + description: Start de addon zonder enige controle of de share correct is ingesteld. + log_level: + name: Logniveau + description: Stelt de verbositeit van de loguitvoer in. diff --git a/samba-backup/translations/sv.yaml b/samba-backup/translations/sv.yaml new file mode 100644 index 0000000..f69e7e8 --- /dev/null +++ b/samba-backup/translations/sv.yaml @@ -0,0 +1,52 @@ +configuration: + host: + name: Värd + description: IP-adressen till Samba share, NAS, etc. + share: + name: Utdelning + description: Namnet på utdelningen share. + target_dir: + name: målmapp + description: Mappen i den utdelade platsen där kopior ska sparas. + username: + name: Användarnamn + description: Användarnamnet för att få tillgång till din Samba share. + password: + name: Lösenord + description: Lösenordet för att få tillgång till din Samba share. + keep_local: + name: Behåll lokalt + description: Antalet kopior som ska behållas lokalt på enheten. + keep_remote: + name: Behåll fjärrstyrt + description: Antalet kopior som ska behållas i den utdelade mappen. + trigger_time: + name: Trigger tid + description: Tidpunkten (format HH:MM) för när en kopia skall göras. + trigger_days: + name: Trigger dag + description: Vilka dagar en kopia skall göras. + exclude_addons: + name: Exkludera tillägg + description: En lista på de tillägg som ska exkluderas i en kopia. + exclude_folders: + name: Exkludera mappar + description: En lista på de mappar som ska exkluderas i en kopia. + backup_name: + name: Namn på kopia + description: Namnet på kopian. + backup_password: + name: Lösenord på kopia + description: Om specificerat så kommer varje kopia tilldelas ett lösenord. + workgroup: + name: Arbetsgrupp + description: Arbetsgruppen för att få tillgång till Samba share. + compatibility_mode: + name: Kompabilitetsläge + description: Aktiverar äldre SMB protokoll. INTE rekommenderat! + skip_precheck: + name: Skippa förkontroll + description: Starta tillägget utan att kontrollera om utdelningen är korret inställd. + log_level: + name: Loggnivå + description: Sätter känsligheten på hur mycket information som ska skickas ut i loggen.