@@ -23,4 +23,5 @@
|
||||
# MAIL_TO=""
|
||||
# MAIL_WHEN_SUCCESS="TRUE"
|
||||
# MAIL_WHEN_FAILURE="TRUE"
|
||||
# MAIL_FORCE_THREAD="FALSE"
|
||||
# TIMEZONE="UTC"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/*.hcl linguist-detectable=false
|
||||
+255
@@ -1,5 +1,260 @@
|
||||
# Changelog
|
||||
|
||||
## v1.26.8 (20260502)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.74.0`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.7 (20260421)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.73.5`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.6 (20260409)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.73.4`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.5 (20260325)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.73.3`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.4 (20260317)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix unable to validate encrypted Rclone config (fixed [#229](https://github.com/ttionya/vaultwarden-backup/issues/229))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.3 (20260307)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.73.2`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.2 (20260219)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.73.1`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.1 (20260131)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.73.0`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.26.0 (20251213)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.72.1`
|
||||
- Support PostgreSQL 18 (close [#223](https://github.com/ttionya/vaultwarden-backup/issues/223))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.25.4 (20251122)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.72.0`
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the incorrect generation of the Message-ID (fixed [#220](https://github.com/ttionya/vaultwarden-backup/issues/220))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.25.3 (20251023)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.71.2`
|
||||
- Accurately distinguish between an unconfigured Rclone and the use of illegal Rclone flags (fixed [#205](https://github.com/ttionya/vaultwarden-backup/issues/205))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.25.2 (20250928)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.71.1`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.25.1 (20250823)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.71.0`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.25.0 (20250802)
|
||||
|
||||
### Feature
|
||||
|
||||
- Add environment variable `MAIL_FORCE_THREAD` to control email threading (close [#210](https://github.com/ttionya/vaultwarden-backup/issues/210))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.24.4 (20250712)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.70.3`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.24.3 (20250522)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.69.3`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.24.2 (20250512)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `directory not found` error (fixed [#199](https://github.com/ttionya/vaultwarden-backup/issues/199))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.24.1 (20250503)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.69.2`
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.24.0 (20250316)
|
||||
|
||||
### Feature
|
||||
|
||||
- Add environment variable `DISPLAY_NAME` to customize the display name (close [#189](https://github.com/ttionya/vaultwarden-backup/issues/189))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.23.2 (20250312)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the issue where errors occur due to spaces in `MAIL_SMTP_VARIABLES` in some cases (fixed [#186](https://github.com/ttionya/vaultwarden-backup/issues/186))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.23.1 (20250220)
|
||||
|
||||
### Feature
|
||||
|
||||
- Add environment variables `MYSQL_SSL` and `MYSQL_SSL_VERIFY_SERVER_CERT` to resolve the MySQL TLS connection error
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.23.0 (20250218)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.69.1`
|
||||
- Support MySQL SSL connection (close [#185](https://github.com/ttionya/vaultwarden-backup/pull/185))
|
||||
- Optimize Rclone connection detection logic (close [#183](https://github.com/ttionya/vaultwarden-backup/issues/183))
|
||||
|
||||
### Chore
|
||||
|
||||
- Compatible with docker/bake-action@v6
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.22.0 (20250116)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.69.0`
|
||||
- Support PostgreSQL 17 (close [#178](https://github.com/ttionya/vaultwarden-backup/issues/178))
|
||||
- Allow partial storage system connection failures during backup verification (close [#175](https://github.com/ttionya/vaultwarden-backup/issues/175))
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.21.3 (20241117)
|
||||
|
||||
### Feature
|
||||
|
||||
- Update Dockerfile base image to `rclone/rclone:1.68.2`
|
||||
- Use standardized docker labels
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## v1.21.2 (20240925)
|
||||
|
||||
### Feature
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
FROM rclone/rclone:1.68.1
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
FROM rclone/rclone:1.74.0
|
||||
LABEL "repository"="git.ow7.de/martinan/vaultwarden-backup:latest" \
|
||||
"homepage"="https://git.ow7.de/martinan/vaultwarden-backup" \
|
||||
"maintainer"="Andreas Martin <andreas.martin@gmx.net>"
|
||||
@@ -13,7 +14,7 @@ COPY scripts/*.sh /app/
|
||||
|
||||
RUN chmod +x /app/*.sh \
|
||||
&& mkdir -m 777 /bitwarden \
|
||||
&& apk add --no-cache 7zip bash curl mariadb-client postgresql16-client sqlite supercronic s-nail tzdata \
|
||||
&& apk add --no-cache 7zip bash curl mariadb-client postgresql18-client sqlite supercronic s-nail tzdata \
|
||||
&& apk info --no-cache -Lq mariadb-client | grep -vE '/bin/mariadb$' | grep -vE '/bin/mariadb-dump$' | xargs -I {} rm -f "/{}" \
|
||||
&& ln -sf "${LOCALTIME_FILE}" /etc/localtime \
|
||||
&& addgroup -g "${USER_ID}" "${USER_NAME}" \
|
||||
|
||||
@@ -314,6 +314,14 @@ Here is timezone list at [wikipedia](https://en.wikipedia.org/wiki/List_of_tz_da
|
||||
|
||||
Default: `UTC`
|
||||
|
||||
#### DISPLAY_NAME
|
||||
|
||||
A custom name to identify your vaultwarden instance in notifications and logs.
|
||||
|
||||
This doesn't affect functionality, it only affects the display in the notification title and partial log output.
|
||||
|
||||
Default: `vaultwarden`
|
||||
|
||||
#### DATA_DIR
|
||||
|
||||
This folder stores the data of vaultwarden.
|
||||
@@ -384,56 +392,6 @@ Default: `${DATA_DIR}/sends`
|
||||
|
||||
## Notification
|
||||
|
||||
### Mail
|
||||
|
||||
Starting from v1.19.0, we will be using [`s-nail`](https://www.sdaoden.eu/code-nail.html) instead of [`heirloom-mailx`](https://www.systutorials.com/docs/linux/man/1-heirloom-mailx/) to send emails.
|
||||
|
||||
Please note that `heirloom-mailx` is a stub for `s-nail`, and most of its functionality is compatible. Therefore, you may not need to modify any environment variables for this change.
|
||||
|
||||
| Environment Variable | Default Value | Description |
|
||||
| --- | --- |-------------------------------------------------------|
|
||||
| MAIL_SMTP_ENABLE | `FALSE` | Enable sending mail. |
|
||||
| MAIL_SMTP_VARIABLES | | Mail sending options. |
|
||||
| MAIL_TO | | The recipient of the notification email. |
|
||||
| MAIL_WHEN_SUCCESS | `TRUE` | Send an email when the backup completes successfully. |
|
||||
| MAIL_WHEN_FAILURE | `TRUE` | Send an email if the backup fails. |
|
||||
|
||||
For `MAIL_SMTP_VARIABLES`, you need to configure the mail sending options yourself. **We will set the email subject based on the usage scenario, so you should not use the `-s` flag.**
|
||||
|
||||
```text
|
||||
# My example:
|
||||
|
||||
# For Zoho
|
||||
-S smtp-use-starttls \
|
||||
-S smtp=smtp://smtp.zoho.com:587 \
|
||||
-S smtp-auth=login \
|
||||
-S smtp-auth-user=<my-email-address> \
|
||||
-S smtp-auth-password=<my-email-password> \
|
||||
-S from=<my-email-address>
|
||||
```
|
||||
|
||||
Console showing warnings? Check [issue #177](https://github.com/ttionya/vaultwarden-backup/issues/117#issuecomment-1691443179) for more details.
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
### Mail Test
|
||||
|
||||
You can use the following command to test mail sending. We will add the `-v` flag to display detailed information, so you do not need to set it again in `MAIL_SMTP_VARIABLES`.
|
||||
|
||||
```shell
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' ttionya/vaultwarden-backup:latest mail <mail send to>
|
||||
|
||||
# Or
|
||||
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' -e MAIL_TO='<mail send to>' ttionya/vaultwarden-backup:latest mail
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
### Ping
|
||||
|
||||
We provide functionality to send notifications when the backup is completed, started, successful, or failed.
|
||||
@@ -480,6 +438,65 @@ docker run --rm -it \
|
||||
|
||||
|
||||
|
||||
### Mail
|
||||
|
||||
Starting from v1.19.0, we will be using [`s-nail`](https://www.sdaoden.eu/code-nail.html) instead of [`heirloom-mailx`](https://www.systutorials.com/docs/linux/man/1-heirloom-mailx/) to send emails.
|
||||
|
||||
Please note that `heirloom-mailx` is a stub for `s-nail`, and most of its functionality is compatible. Therefore, you may not need to modify any environment variables for this change.
|
||||
|
||||
| Environment Variable | Default Value | Description |
|
||||
| --- | --- |-----------------------------------------------------------------------------------------------------------------------|
|
||||
| MAIL_SMTP_ENABLE | `FALSE` | Enable sending mail. |
|
||||
| MAIL_SMTP_VARIABLES | | Mail sending options. |
|
||||
| MAIL_TO | | The recipient of the notification email. |
|
||||
| MAIL_WHEN_SUCCESS | `TRUE` | Send an email when the backup completes successfully. |
|
||||
| MAIL_WHEN_FAILURE | `TRUE` | Send an email if the backup fails. |
|
||||
| MAIL_FORCE_THREAD | `FALSE` | Particularly useful when mail clients fail to group related messages in conversation view despite identical subjects. |
|
||||
|
||||
For `MAIL_SMTP_VARIABLES`, you need to configure the mail sending options yourself. **We will set the email subject based on the usage scenario, so you should not use the `-s` flag.**
|
||||
|
||||
```text
|
||||
# My example:
|
||||
|
||||
# For Zoho
|
||||
-S smtp-use-starttls \
|
||||
-S smtp=smtp://smtp.zoho.com:587 \
|
||||
-S smtp-auth=login \
|
||||
-S smtp-auth-user=<my-email-address> \
|
||||
-S smtp-auth-password=<my-email-password> \
|
||||
-S from=<my-email-address>
|
||||
```
|
||||
|
||||
Console showing warnings? Check [issue #177](https://github.com/ttionya/vaultwarden-backup/issues/117#issuecomment-1691443179) for more details.
|
||||
|
||||
For `MAIL_FORCE_THREAD`, particularly useful when receiving systems fail to properly aggregate messages into conversation threads. It supports three modes of operation:
|
||||
|
||||
1. `FALSE`: Default email sending behavior.
|
||||
2. `TRUE`: Auto-generates RFC-compliant Message-ID to force thread creation.
|
||||
3. `Valid Message-ID string`: Uses specified Message-ID to associate with existing thread. Find it in the original email's Message-ID field.
|
||||
|
||||
When enabled, the system automatically adds required headers (`Message-ID`, `References`, `In-Reply-To`) to enforce proper thread association on the receiving end.
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
### Mail Test
|
||||
|
||||
You can use the following command to test mail sending. We will add the `-v` flag to display detailed information, so you do not need to set it again in `MAIL_SMTP_VARIABLES`.
|
||||
|
||||
```shell
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' ttionya/vaultwarden-backup:latest mail <mail send to>
|
||||
|
||||
# Or
|
||||
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' -e MAIL_TO='<mail send to>' ttionya/vaultwarden-backup:latest mail
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## Environment Variables Considerations
|
||||
|
||||
### Using `.env` file
|
||||
@@ -531,10 +548,10 @@ MY_ENV="example1"
|
||||
MY_ENV_FILE="/path/to/example2"
|
||||
|
||||
# For 3 (.env file)
|
||||
MY_ENV_FILE: "/path/to/example3"
|
||||
MY_ENV_FILE="/path/to/example3"
|
||||
|
||||
# For 4 (.env file)
|
||||
MY_ENV: "example4"
|
||||
MY_ENV="example4"
|
||||
```
|
||||
|
||||
<br>
|
||||
@@ -583,7 +600,7 @@ Check out the [CHANGELOG](CHANGELOG.md) file.
|
||||
|
||||
I am grateful for the OSS license provided by [JetBrains](https://www.jetbrains.com/).
|
||||
|
||||
<a href="https://jb.gg/OpenSourceSupport" target="_blank"><img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" alt="JetBrains Logo (Main) logo" width="200"></a>
|
||||
<a href="https://jb.gg/OpenSource" target="_blank"><img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg" alt="JetBrains logo."></a>
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
+70
-53
@@ -312,6 +312,14 @@ Rclone 全局参数,详见 [flags](https://rclone.org/flags/)。
|
||||
|
||||
默认值:`UTC`
|
||||
|
||||
#### DISPLAY_NAME
|
||||
|
||||
用于在通知和日志中标识 vaultwarden 实例的自定义名称。
|
||||
|
||||
这不会影响功能,仅影响通知标题和部分日志输出中的显示。
|
||||
|
||||
默认值:`vaultwarden`
|
||||
|
||||
#### DATA_DIR
|
||||
|
||||
指定存放 vaultwarden 数据的目录。
|
||||
@@ -381,56 +389,6 @@ Default: `%Y%m%d`
|
||||
|
||||
## 通知
|
||||
|
||||
### Mail
|
||||
|
||||
从 v1.19.0 开始,本工具使用 [`s-nail`](https://www.sdaoden.eu/code-nail.html) 代替 [`heirloom-mailx`](https://www.systutorials.com/docs/linux/man/1-heirloom-mailx/) 发送邮件。
|
||||
|
||||
请注意,`heirloom-mailx` 是 `s-nail` 的存根,它们大部分功能是兼容的。因此你可能不需要为这个改变修改任何环境变量。
|
||||
|
||||
| 环境变量 | 默认值 | 描述 |
|
||||
| --- |--------|-----------|
|
||||
| MAIL_SMTP_ENABLE | `FALSE` | 启用邮件发送功能 |
|
||||
| MAIL_SMTP_VARIABLES | | 邮件发送参数 |
|
||||
| MAIL_TO | | 接收邮件的地址 |
|
||||
| MAIL_WHEN_SUCCESS | `TRUE` | 备份成功后发送邮件 |
|
||||
| MAIL_WHEN_FAILURE | `TRUE` | 备份失败后发送邮件 |
|
||||
|
||||
对于 `MAIL_SMTP_VARIABLES`,你需要自行配置邮件发送参数。**我们会根据使用场景设置邮件主题,所以你不应该使用 `-s` 标志。**
|
||||
|
||||
```text
|
||||
# 提供一个能正常使用的例子:
|
||||
|
||||
# For Zoho
|
||||
-S smtp-use-starttls \
|
||||
-S smtp=smtp://smtp.zoho.com:587 \
|
||||
-S smtp-auth=login \
|
||||
-S smtp-auth-user=<my-email-address> \
|
||||
-S smtp-auth-password=<my-email-password> \
|
||||
-S from=<my-email-address>
|
||||
```
|
||||
|
||||
控制台有警告?查看 [issue #177](https://github.com/ttionya/vaultwarden-backup/issues/117#issuecomment-1691443179) 了解更多。
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
### 邮件发送测试
|
||||
|
||||
你可以使用下面的命令测试邮件发送功能。我们会增加 `-v` 标志以显示详细信息,你无需在 `MAIL_SMTP_VARIABLES` 中重复设置。
|
||||
|
||||
```shell
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' ttionya/vaultwarden-backup:latest mail <mail send to>
|
||||
|
||||
# Or
|
||||
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' -e MAIL_TO='<mail send to>' ttionya/vaultwarden-backup:latest mail
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
### Ping
|
||||
|
||||
我们提供了在备份完成、开始、成功、失败时发送通知的功能。
|
||||
@@ -477,6 +435,65 @@ docker run --rm -it \
|
||||
|
||||
|
||||
|
||||
### Mail
|
||||
|
||||
从 v1.19.0 开始,本工具使用 [`s-nail`](https://www.sdaoden.eu/code-nail.html) 代替 [`heirloom-mailx`](https://www.systutorials.com/docs/linux/man/1-heirloom-mailx/) 发送邮件。
|
||||
|
||||
请注意,`heirloom-mailx` 是 `s-nail` 的存根,它们大部分功能是兼容的。因此你可能不需要为这个改变修改任何环境变量。
|
||||
|
||||
| 环境变量 | 默认值 | 描述 |
|
||||
| --- |--------|----------------------------------------|
|
||||
| MAIL_SMTP_ENABLE | `FALSE` | 启用邮件发送功能 |
|
||||
| MAIL_SMTP_VARIABLES | | 邮件发送参数 |
|
||||
| MAIL_TO | | 接收邮件的地址 |
|
||||
| MAIL_WHEN_SUCCESS | `TRUE` | 备份成功后发送邮件 |
|
||||
| MAIL_WHEN_FAILURE | `TRUE` | 备份失败后发送邮件 |
|
||||
| MAIL_FORCE_THREAD | `FALSE` | 尤其适用于邮件客户端在主题相同的情况下仍无法在对话视图中将相关邮件分组的情况 |
|
||||
|
||||
对于 `MAIL_SMTP_VARIABLES`,你需要自行配置邮件发送参数。**我们会根据使用场景设置邮件主题,所以你不应该使用 `-s` 标志。**
|
||||
|
||||
```text
|
||||
# 提供一个能正常使用的例子:
|
||||
|
||||
# For Zoho
|
||||
-S smtp-use-starttls \
|
||||
-S smtp=smtp://smtp.zoho.com:587 \
|
||||
-S smtp-auth=login \
|
||||
-S smtp-auth-user=<my-email-address> \
|
||||
-S smtp-auth-password=<my-email-password> \
|
||||
-S from=<my-email-address>
|
||||
```
|
||||
|
||||
控制台有警告?查看 [issue #177](https://github.com/ttionya/vaultwarden-backup/issues/117#issuecomment-1691443179) 了解更多。
|
||||
|
||||
对于 `MAIL_FORCE_THREAD`,在邮件客户端无法正确将邮件聚合到同一会话中时特别有用。它支持三种操作模式:
|
||||
|
||||
1. `FALSE`:默认电子邮件发送行为
|
||||
2. `TRUE`:自动生成符合 RFC 的 Message-ID 以强制会话关联
|
||||
3. `有效 Message-ID 字符串`:使用指定的 Message-ID 与现有会话关联。你可以在原始邮件内容的 Message-ID 字段中找到它
|
||||
|
||||
启用后,系统会自动添加所需的标头(`Message-ID`、`References`、`In-Reply-To`),以便邮件客户端适当地关联会话。
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
### 邮件发送测试
|
||||
|
||||
你可以使用下面的命令测试邮件发送功能。我们会增加 `-v` 标志以显示详细信息,你无需在 `MAIL_SMTP_VARIABLES` 中重复设置。
|
||||
|
||||
```shell
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' ttionya/vaultwarden-backup:latest mail <mail send to>
|
||||
|
||||
# Or
|
||||
|
||||
docker run --rm -it -e MAIL_SMTP_VARIABLES='<your smtp variables>' -e MAIL_TO='<mail send to>' ttionya/vaultwarden-backup:latest mail
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
## 环境变量注意事项
|
||||
|
||||
### 使用 `.env` 文件
|
||||
@@ -528,10 +545,10 @@ MY_ENV="example1"
|
||||
MY_ENV_FILE="/path/to/example2"
|
||||
|
||||
# 对于 3 (.env 文件)
|
||||
MY_ENV_FILE: "/path/to/example3"
|
||||
MY_ENV_FILE="/path/to/example3"
|
||||
|
||||
# 对于 4 (.env 文件)
|
||||
MY_ENV: "example4"
|
||||
MY_ENV="example4"
|
||||
```
|
||||
|
||||
<br>
|
||||
@@ -580,7 +597,7 @@ MY_ENV: "example4"
|
||||
|
||||
感谢 [JetBrains](https://www.jetbrains.com/) 提供的 OSS 许可证。
|
||||
|
||||
<a href="https://jb.gg/OpenSourceSupport" target="_blank"><img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" alt="JetBrains Logo (Main) logo" width="250"></a>
|
||||
<a href="https://jb.gg/OpenSource" target="_blank"><img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg" alt="JetBrains logo."></a>
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
-
|
||||
name: DockerHub Description
|
||||
uses: peter-evans/dockerhub-description@v4
|
||||
uses: peter-evans/dockerhub-description@v5
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
enable-url-completion: true
|
||||
-
|
||||
name: DockerHub Description
|
||||
uses: peter-evans/dockerhub-description@v4
|
||||
uses: peter-evans/dockerhub-description@v5
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
@@ -21,44 +21,51 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
-
|
||||
name: Prepare
|
||||
run: echo "TAG=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV
|
||||
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Login to ghcr.io
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
context: '.'
|
||||
file: './Dockerfile'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7'
|
||||
labels: |
|
||||
org.opencontainers.image.title=vaultwarden-backup
|
||||
org.opencontainers.image.description=Backup vaultwarden SQLite3/PostgreSQL/MySQL/MariaDB database by rclone
|
||||
org.opencontainers.image.authors=ttionya
|
||||
org.opencontainers.image.version=${{ env.VERSION }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/bake-action@v7
|
||||
env:
|
||||
VERSION: ${{ env.VERSION }}
|
||||
with:
|
||||
source: .
|
||||
files: |
|
||||
./docker-bake.hcl
|
||||
${{ steps.meta.outputs.bake-file-labels }}
|
||||
targets: image-stable
|
||||
push: true
|
||||
tags: |
|
||||
ttionya/vaultwarden-backup:latest
|
||||
ttionya/vaultwarden-backup:${{ env.TAG }}
|
||||
ttionya/bitwardenrs-backup:latest
|
||||
ttionya/bitwardenrs-backup:${{ env.TAG }}
|
||||
ghcr.io/ttionya/vaultwarden-backup:latest
|
||||
ghcr.io/ttionya/vaultwarden-backup:${{ env.TAG }}
|
||||
|
||||
publish-beta:
|
||||
name: Docker Publish Beta
|
||||
@@ -70,32 +77,44 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
-
|
||||
name: Prepare
|
||||
run: echo "TAG=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV
|
||||
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
context: '.'
|
||||
file: './Dockerfile'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7'
|
||||
labels: |
|
||||
org.opencontainers.image.title=vaultwarden-backup
|
||||
org.opencontainers.image.description=Backup vaultwarden SQLite3/PostgreSQL/MySQL/MariaDB database by rclone
|
||||
org.opencontainers.image.authors=ttionya
|
||||
org.opencontainers.image.version=${{ env.VERSION }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/bake-action@v7
|
||||
env:
|
||||
VERSION: ${{ env.VERSION }}
|
||||
with:
|
||||
source: .
|
||||
files: |
|
||||
./docker-bake.hcl
|
||||
${{ steps.meta.outputs.bake-file-labels }}
|
||||
targets: image-beta
|
||||
push: true
|
||||
tags: |
|
||||
ttionya/vaultwarden-backup:${{ env.TAG }}
|
||||
|
||||
publish-schedule:
|
||||
name: Docker Publish Schedule
|
||||
@@ -114,45 +133,52 @@ jobs:
|
||||
excludes: prerelease, draft
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: refs/tags/${{ steps.tag.outputs.release }}
|
||||
-
|
||||
name: Prepare
|
||||
run: |
|
||||
TAG=${{ steps.tag.outputs.release }}
|
||||
echo "TAG=${TAG#v}" >> $GITHUB_ENV
|
||||
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Login to ghcr.io
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
context: '.'
|
||||
file: './Dockerfile'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7'
|
||||
labels: |
|
||||
org.opencontainers.image.title=vaultwarden-backup
|
||||
org.opencontainers.image.description=Backup vaultwarden SQLite3/PostgreSQL/MySQL/MariaDB database by rclone
|
||||
org.opencontainers.image.authors=ttionya
|
||||
org.opencontainers.image.version=${{ env.VERSION }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/bake-action@v7
|
||||
env:
|
||||
VERSION: ${{ env.VERSION }}
|
||||
with:
|
||||
source: .
|
||||
files: |
|
||||
./docker-bake.hcl
|
||||
${{ steps.meta.outputs.bake-file-labels }}
|
||||
targets: image-schedule
|
||||
push: true
|
||||
tags: |
|
||||
ttionya/vaultwarden-backup:latest
|
||||
ttionya/vaultwarden-backup:${{ env.TAG }}
|
||||
ttionya/bitwardenrs-backup:latest
|
||||
ttionya/bitwardenrs-backup:${{ env.TAG }}
|
||||
ghcr.io/ttionya/vaultwarden-backup:latest
|
||||
ghcr.io/ttionya/vaultwarden-backup:${{ env.TAG }}
|
||||
|
||||
@@ -24,35 +24,33 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
with:
|
||||
# network=host driver-opt needed to push to local registry
|
||||
# https://docs.docker.com/build/ci/github-actions/named-contexts/#using-with-a-container-builder
|
||||
driver-opts: network=host
|
||||
-
|
||||
name: Build base image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/bake-action@v7
|
||||
with:
|
||||
context: '.'
|
||||
file: './Dockerfile'
|
||||
platforms: 'linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7'
|
||||
source: .
|
||||
files: ./docker-bake.hcl
|
||||
targets: image-test-base
|
||||
push: true
|
||||
tags: localhost:5000/base:dev
|
||||
-
|
||||
name: Build test image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/bake-action@v7
|
||||
with:
|
||||
context: '.'
|
||||
file: './tests/Dockerfile'
|
||||
build-contexts: base=docker-image://localhost:5000/base:dev
|
||||
source: .
|
||||
files: ./docker-bake.hcl
|
||||
targets: image-test
|
||||
load: true
|
||||
tags: ttionya/vaultwarden-backup:test
|
||||
-
|
||||
name: Test
|
||||
run: |
|
||||
|
||||
@@ -18,10 +18,10 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
-
|
||||
name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@v3
|
||||
with:
|
||||
body: |
|
||||
[CHANGELOG](https://github.com/ttionya/vaultwarden-backup/blob/master/CHANGELOG.md)
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
variable "VERSION" {
|
||||
default = "latest"
|
||||
}
|
||||
|
||||
variable "TEST_BASE_TAG" {
|
||||
default = "localhost:5000/base:dev"
|
||||
}
|
||||
|
||||
target "docker-metadata-action" {}
|
||||
|
||||
target "_common" {
|
||||
inherits = ["docker-metadata-action"]
|
||||
context = "."
|
||||
dockerfile = "Dockerfile"
|
||||
}
|
||||
|
||||
target "_common_multi_platforms" {
|
||||
platforms = [
|
||||
"linux/amd64",
|
||||
"linux/arm64",
|
||||
"linux/arm/v6",
|
||||
"linux/arm/v7"
|
||||
]
|
||||
}
|
||||
|
||||
target "_common_tags" {
|
||||
tags = [
|
||||
"ttionya/vaultwarden-backup:latest",
|
||||
"ttionya/vaultwarden-backup:${VERSION}",
|
||||
"ttionya/bitwardenrs-backup:latest",
|
||||
"ttionya/bitwardenrs-backup:${VERSION}",
|
||||
"ghcr.io/ttionya/vaultwarden-backup:latest",
|
||||
"ghcr.io/ttionya/vaultwarden-backup:${VERSION}"
|
||||
]
|
||||
}
|
||||
|
||||
target "image-stable" {
|
||||
inherits = ["_common", "_common_multi_platforms", "_common_tags"]
|
||||
}
|
||||
|
||||
target "image-schedule" {
|
||||
inherits = ["image-stable"]
|
||||
}
|
||||
|
||||
target "image-beta" {
|
||||
inherits = ["_common", "_common_multi_platforms"]
|
||||
tags = [
|
||||
"ttionya/vaultwarden-backup:${VERSION}"
|
||||
]
|
||||
}
|
||||
|
||||
target "image-test-base" {
|
||||
inherits = ["_common", "_common_multi_platforms"]
|
||||
tags = [
|
||||
"${TEST_BASE_TAG}"
|
||||
]
|
||||
}
|
||||
|
||||
target "image-test" {
|
||||
inherits = ["_common"]
|
||||
dockerfile = "./tests/Dockerfile"
|
||||
contexts = {
|
||||
base = "docker-image://${TEST_BASE_TAG}"
|
||||
}
|
||||
tags = [
|
||||
"ttionya/vaultwarden-backup:test"
|
||||
]
|
||||
}
|
||||
@@ -39,6 +39,7 @@ services:
|
||||
# MAIL_TO: ''
|
||||
# MAIL_WHEN_SUCCESS: 'TRUE'
|
||||
# MAIL_WHEN_FAILURE: 'TRUE'
|
||||
# MAIL_FORCE_THREAD: 'FALSE'
|
||||
# TIMEZONE: 'UTC'
|
||||
volumes:
|
||||
- vaultwarden-data:/bitwarden/data/
|
||||
|
||||
@@ -4,6 +4,8 @@ Sometimes, it's necessary to manually trigger backup actions.
|
||||
|
||||
This can be useful when other programs are used to consistently schedule tasks or to verify that environment variables are properly configured.
|
||||
|
||||
If your container is already running (with the container name `vaultwarden_backup`) and you want to execute an adhoc backup you can do so with the command `docker exec vaultwarden_backup bash /app/backup.sh`.
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
@@ -40,6 +40,32 @@ Default: `vaultwarden`
|
||||
|
||||
MySQL(MariaDB) password, **required**.
|
||||
|
||||
#### MYSQL_SSL
|
||||
|
||||
Enable SSL for connection.
|
||||
|
||||
No default value is set; it uses the default provided by `mariadb-dump`, and starting from version `10.11`, the default is `TRUE`.
|
||||
|
||||
#### MYSQL_SSL_VERIFY_SERVER_CERT
|
||||
|
||||
Verify server's certificate.
|
||||
|
||||
No default value is set; it uses the default provided by `mariadb-dump`, and starting from version `11.4`, the default is `TRUE`.
|
||||
|
||||
If you encounter any TLS-related connection errors, you can try disabling it by setting values such as `0` or `FALSE`.
|
||||
|
||||
#### MYSQL_SSL_CA
|
||||
|
||||
The path to the CA certificate for TLS connection (optional).
|
||||
|
||||
#### MYSQL_SSL_CERT
|
||||
|
||||
The path to the client certificate for TLS connection (optional).
|
||||
|
||||
#### MYSQL_SSL_KEY
|
||||
|
||||
The path to the client key for TLS connection (optional).
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
Now supports PostgreSQL backend.
|
||||
|
||||
~~Because upstream Rclone image is based on `alpine 3.16`(and `linux/arm/v6` platform is based on `alpine 3.15`), it **only supports PostgreSQL 14 and previous versions**, see [Alpine 3.16 Packages](https://pkgs.alpinelinux.org/packages?name=postgresql*-client&branch=v3.16) and [Alpine 3.15 Packages](https://pkgs.alpinelinux.org/packages?name=postgresql*-client&branch=v3.15).~~
|
||||
|
||||
We support PostgreSQL 16 and previous versions.
|
||||
We support PostgreSQL 18 and previous versions.
|
||||
|
||||
If the `postgresql*-client` is not updated promptly, please create an issue to inform us.
|
||||
|
||||
|
||||
+19
-2
@@ -52,7 +52,24 @@ function backup_db_postgresql() {
|
||||
function backup_db_mysql() {
|
||||
color blue "backup vaultwarden mysql database"
|
||||
|
||||
mariadb-dump -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USERNAME}" -p"${MYSQL_PASSWORD}" "${MYSQL_DATABASE}" > "${BACKUP_FILE_DB_MYSQL}"
|
||||
local EXTRA_OPTIONS=()
|
||||
if [[ -n "${MYSQL_SSL}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl=\"${MYSQL_SSL}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_VERIFY_SERVER_CERT}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-verify-server-cert=\"${MYSQL_SSL_VERIFY_SERVER_CERT}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_CA}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-ca=\"${MYSQL_SSL_CA}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_CERT}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-cert=\"${MYSQL_SSL_CERT}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_KEY}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-key=\"${MYSQL_SSL_KEY}\"")
|
||||
fi
|
||||
|
||||
eval "mariadb-dump -h \"${MYSQL_HOST}\" -P \"${MYSQL_PORT}\" -u \"${MYSQL_USERNAME}\" -p\"${MYSQL_PASSWORD}\" ${EXTRA_OPTIONS[@]} \"${MYSQL_DATABASE}\" > \"${BACKUP_FILE_DB_MYSQL}\""
|
||||
if [[ $? != 0 ]]; then
|
||||
color red "backup vaultwarden mysql database failed"
|
||||
|
||||
@@ -217,7 +234,7 @@ init_env
|
||||
|
||||
send_notification "start" "Start backup at $(date +"%Y-%m-%d %H:%M:%S %Z")"
|
||||
|
||||
check_rclone_connection
|
||||
check_rclone_connection any
|
||||
|
||||
clear_dir
|
||||
backup_init
|
||||
|
||||
@@ -12,6 +12,7 @@ fi
|
||||
# mail test
|
||||
if [[ "$1" == "mail" ]]; then
|
||||
export_env_file
|
||||
init_env_display
|
||||
init_env_mail
|
||||
|
||||
MAIL_SMTP_ENABLE="TRUE"
|
||||
@@ -21,7 +22,7 @@ if [[ "$1" == "mail" ]]; then
|
||||
MAIL_TO="$2"
|
||||
fi
|
||||
|
||||
send_mail "vaultwarden Backup Test" "Your SMTP configuration looks correct."
|
||||
send_mail "${DISPLAY_NAME} Backup Test" "Your SMTP configuration looks correct."
|
||||
|
||||
exit 0
|
||||
fi
|
||||
@@ -29,11 +30,12 @@ fi
|
||||
# ping test
|
||||
if [[ "$1" == "ping" ]]; then
|
||||
export_env_file
|
||||
init_env_display
|
||||
init_env_ping
|
||||
|
||||
PING_DEBUG="TRUE"
|
||||
|
||||
send_ping "$2" "vaultwarden Backup Test" "Your PING configuration looks correct."
|
||||
send_ping "$2" "${DISPLAY_NAME} Backup Test" "Your PING configuration looks correct."
|
||||
|
||||
exit 0
|
||||
fi
|
||||
@@ -60,7 +62,7 @@ function configure_cron() {
|
||||
}
|
||||
|
||||
init_env
|
||||
check_rclone_connection
|
||||
check_rclone_connection all
|
||||
configure_postgresql
|
||||
configure_timezone
|
||||
configure_cron
|
||||
@@ -75,4 +77,4 @@ if [[ "$1" == "backup" ]]; then
|
||||
fi
|
||||
|
||||
# foreground run crond
|
||||
exec supercronic -passthrough-logs -quiet "${CRON_CONFIG_FILE}"
|
||||
exec /usr/bin/supercronic -passthrough-logs -quiet "${CRON_CONFIG_FILE}"
|
||||
|
||||
+117
-16
@@ -2,6 +2,8 @@
|
||||
|
||||
ENV_FILE="/.env"
|
||||
CRON_CONFIG_FILE="${HOME}/crontabs"
|
||||
MAIL_CONFIG_DIR="/config/mail"
|
||||
MAIL_PARENT_MESSAGE_ID_FILE="${MAIL_CONFIG_DIR}/parent_message_id"
|
||||
BACKUP_DIR="/bitwarden/backup"
|
||||
RESTORE_DIR="/bitwarden/restore"
|
||||
RESTORE_EXTRACT_DIR="/bitwarden/extract"
|
||||
@@ -28,11 +30,19 @@ function color() {
|
||||
########################################
|
||||
# Check storage system connection success.
|
||||
# Arguments:
|
||||
# None
|
||||
# success strategy (all / any)
|
||||
########################################
|
||||
function check_rclone_connection() {
|
||||
# check configuration exist
|
||||
rclone ${RCLONE_GLOBAL_FLAG} config show "${RCLONE_REMOTE_NAME}" > /dev/null 2>&1
|
||||
# check flags validity
|
||||
rclone ${RCLONE_GLOBAL_FLAG} version > /dev/null 2>&1
|
||||
if [[ $? != 0 ]]; then
|
||||
color red "illegal rclone global flags"
|
||||
color blue "Please check https://rclone.org/flags/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if the configuration exists
|
||||
rclone ${RCLONE_GLOBAL_FLAG} config show 2>&1 | grep -F "[${RCLONE_REMOTE_NAME}]" > /dev/null
|
||||
if [[ $? != 0 ]]; then
|
||||
color red "rclone configuration information not found"
|
||||
color blue "Please configure rclone first, check https://github.com/ttionya/vaultwarden-backup/blob/master/README.md#backup"
|
||||
@@ -40,25 +50,40 @@ function check_rclone_connection() {
|
||||
fi
|
||||
|
||||
# check connection
|
||||
local HAS_ERROR="FALSE"
|
||||
local ERROR_COUNT=0
|
||||
|
||||
for RCLONE_REMOTE_X in "${RCLONE_REMOTE_LIST[@]}"
|
||||
do
|
||||
rclone ${RCLONE_GLOBAL_FLAG} mkdir "${RCLONE_REMOTE_X}"
|
||||
rclone ${RCLONE_GLOBAL_FLAG} lsd "${RCLONE_REMOTE_X}" > /dev/null
|
||||
if [[ $? != 0 ]]; then
|
||||
color red "storage system connection failure $(color yellow "[${RCLONE_REMOTE_X}]")"
|
||||
color red "storage system connection may not be initialized, try initializing $(color yellow "[${RCLONE_REMOTE_X}]")"
|
||||
|
||||
HAS_ERROR="TRUE"
|
||||
rclone ${RCLONE_GLOBAL_FLAG} mkdir "${RCLONE_REMOTE_X}"
|
||||
if [[ $? != 0 ]]; then
|
||||
color red "storage system connection failure $(color yellow "[${RCLONE_REMOTE_X}]")"
|
||||
|
||||
((ERROR_COUNT++))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${HAS_ERROR}" == "TRUE" ]]; then
|
||||
exit 1
|
||||
if [[ "${ERROR_COUNT}" -gt 0 ]]; then
|
||||
if [[ "$1" == "all" ]]; then
|
||||
color red "storage system connection failure exists"
|
||||
exit 1
|
||||
elif [[ "$1" == "any" ]]; then
|
||||
if [[ "${ERROR_COUNT}" -eq "${#RCLONE_REMOTE_LIST[@]}" ]]; then
|
||||
color red "all storage system connections failed"
|
||||
exit 1
|
||||
else
|
||||
color yellow "some storage system connections failed, but the backup will continue"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
########################################
|
||||
# Check file is exist.
|
||||
# Check if the file exists.
|
||||
# Arguments:
|
||||
# file
|
||||
########################################
|
||||
@@ -70,7 +95,7 @@ function check_file_exist() {
|
||||
}
|
||||
|
||||
########################################
|
||||
# Check directory is exist.
|
||||
# Check if the directory exists.
|
||||
# Arguments:
|
||||
# directory
|
||||
########################################
|
||||
@@ -90,15 +115,40 @@ function check_dir_exist() {
|
||||
# send mail result
|
||||
########################################
|
||||
function send_mail() {
|
||||
local MAIL_VERBOSE_FLAG=""
|
||||
local MAIL_TEMPLATE_FLAG=""
|
||||
local MAIL_TEMPLATE=""
|
||||
local MAIL_USED_MESSAGE_ID=""
|
||||
|
||||
# verbose
|
||||
if [[ "${MAIL_DEBUG}" == "TRUE" ]]; then
|
||||
local MAIL_VERBOSE="-v"
|
||||
MAIL_VERBOSE_FLAG="-v"
|
||||
fi
|
||||
|
||||
echo "$2" | mail ${MAIL_VERBOSE} -s "$1" ${MAIL_SMTP_VARIABLES} "${MAIL_TO}"
|
||||
# template
|
||||
if [[ "${MAIL_USE_THREAD}" == "TRUE" ]]; then
|
||||
if [[ -n "${MAIL_PARENT_MESSAGE_ID}" ]]; then
|
||||
MAIL_USED_MESSAGE_ID="${MAIL_PARENT_MESSAGE_ID}"
|
||||
MAIL_TEMPLATE="References: ${MAIL_USED_MESSAGE_ID}\nIn-Reply-To: ${MAIL_USED_MESSAGE_ID}\n\n"
|
||||
else
|
||||
MAIL_USED_MESSAGE_ID="<$(date +%s%N).$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16).$(hostname)@vaultwarden.backup>"
|
||||
MAIL_TEMPLATE="Message-ID: ${MAIL_USED_MESSAGE_ID}\n\n"
|
||||
fi
|
||||
fi
|
||||
if [[ -n "${MAIL_TEMPLATE}" ]]; then
|
||||
MAIL_TEMPLATE_FLAG="-t"
|
||||
fi
|
||||
|
||||
echo -e "${MAIL_TEMPLATE}$2" | eval "mail ${MAIL_VERBOSE_FLAG} ${MAIL_TEMPLATE_FLAG} -s \"$1\" ${MAIL_SMTP_VARIABLES} \"${MAIL_TO}\""
|
||||
if [[ $? != 0 ]]; then
|
||||
color red "mail sending has failed"
|
||||
else
|
||||
color blue "mail has been sent successfully"
|
||||
|
||||
if [[ "${MAIL_USE_THREAD}" == "TRUE" && -z "${MAIL_PARENT_MESSAGE_ID}" ]]; then
|
||||
mkdir -p "$(dirname "${MAIL_PARENT_MESSAGE_ID_FILE}")"
|
||||
echo -n "${MAIL_USED_MESSAGE_ID}" > "${MAIL_PARENT_MESSAGE_ID_FILE}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -153,9 +203,9 @@ function send_ping() {
|
||||
# notification content
|
||||
########################################
|
||||
function send_notification() {
|
||||
local SUBJECT_START="vaultwarden Backup Start"
|
||||
local SUBJECT_SUCCESS="vaultwarden Backup Success"
|
||||
local SUBJECT_FAILURE="vaultwarden Backup Failed"
|
||||
local SUBJECT_START="${DISPLAY_NAME} Backup Start"
|
||||
local SUBJECT_SUCCESS="${DISPLAY_NAME} Backup Success"
|
||||
local SUBJECT_FAILURE="${DISPLAY_NAME} Backup Failed"
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
@@ -291,6 +341,7 @@ function init_env() {
|
||||
|
||||
init_env_dir
|
||||
init_env_db
|
||||
init_env_display
|
||||
init_env_ping
|
||||
init_env_mail
|
||||
|
||||
@@ -401,8 +452,16 @@ function init_env() {
|
||||
color yellow "MAIL_TO: ${MAIL_TO}"
|
||||
color yellow "MAIL_WHEN_SUCCESS: ${MAIL_WHEN_SUCCESS}"
|
||||
color yellow "MAIL_WHEN_FAILURE: ${MAIL_WHEN_FAILURE}"
|
||||
if [[ "${MAIL_USE_THREAD}" == "TRUE" ]]; then
|
||||
if [[ -n "${MAIL_PARENT_MESSAGE_ID}" ]]; then
|
||||
color yellow "MAIL_PARENT_MESSAGE_ID: ${MAIL_PARENT_MESSAGE_ID}"
|
||||
else
|
||||
color yellow "MAIL_MESSAGE_ID: auto generate"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
color yellow "TIMEZONE: ${TIMEZONE}"
|
||||
color yellow "DISPLAY_NAME: ${DISPLAY_NAME}"
|
||||
color yellow "========================================"
|
||||
}
|
||||
|
||||
@@ -482,11 +541,32 @@ function init_env_db() {
|
||||
|
||||
# MYSQL_PASSWORD
|
||||
get_env MYSQL_PASSWORD
|
||||
|
||||
# MYSQL_SSL
|
||||
get_env MYSQL_SSL
|
||||
|
||||
# MYSQL_SSL_VERIFY_SERVER_CERT
|
||||
get_env MYSQL_SSL_VERIFY_SERVER_CERT
|
||||
|
||||
# MYSQL_SSL_CA
|
||||
get_env MYSQL_SSL_CA
|
||||
|
||||
# MYSQL_SSL_CERT
|
||||
get_env MYSQL_SSL_CERT
|
||||
|
||||
# MYSQL_SSL_KEY
|
||||
get_env MYSQL_SSL_KEY
|
||||
else # sqlite
|
||||
DB_TYPE="SQLITE"
|
||||
fi
|
||||
}
|
||||
|
||||
function init_env_display() {
|
||||
# DISPLAY_NAME
|
||||
get_env DISPLAY_NAME
|
||||
DISPLAY_NAME="${DISPLAY_NAME:-"vaultwarden"}"
|
||||
}
|
||||
|
||||
function init_env_ping() {
|
||||
# PING_URL
|
||||
get_env PING_URL
|
||||
@@ -551,4 +631,25 @@ function init_env_mail() {
|
||||
else
|
||||
MAIL_WHEN_FAILURE="TRUE"
|
||||
fi
|
||||
|
||||
# MAIL_FORCE_THREAD
|
||||
get_env MAIL_FORCE_THREAD
|
||||
# 1. As long as MAIL_PARENT_MESSAGE_ID is valid (either specified or read from a file), MAIL_FORCE_THREAD must be set to TRUE.
|
||||
# 2. As long as MAIL_FORCE_THREAD is set to TRUE, even if an invalid Message-ID is read from the file, it will be regenerated subsequently.
|
||||
# 3. When MAIL_FORCE_THREAD is not set to TRUE, promptly clear the persistent files.
|
||||
if [[ "${MAIL_FORCE_THREAD^^}" == "TRUE" ]]; then
|
||||
MAIL_USE_THREAD="TRUE"
|
||||
if [[ -f "${MAIL_PARENT_MESSAGE_ID_FILE}" && -s "${MAIL_PARENT_MESSAGE_ID_FILE}" ]]; then
|
||||
MAIL_PARENT_MESSAGE_ID="$(cat "${MAIL_PARENT_MESSAGE_ID_FILE}")"
|
||||
fi
|
||||
else
|
||||
MAIL_PARENT_MESSAGE_ID="${MAIL_FORCE_THREAD}"
|
||||
MAIL_USE_THREAD="FALSE"
|
||||
rm -rf "${MAIL_CONFIG_DIR}"
|
||||
fi
|
||||
if [[ "${MAIL_PARENT_MESSAGE_ID}" =~ ^\<.*\@.+\>$ ]]; then
|
||||
MAIL_USE_THREAD="TRUE"
|
||||
else
|
||||
MAIL_PARENT_MESSAGE_ID=""
|
||||
fi
|
||||
}
|
||||
|
||||
+18
-1
@@ -90,7 +90,24 @@ function restore_db_postgresql() {
|
||||
function restore_db_mysql() {
|
||||
color blue "restore vaultwarden mysql database"
|
||||
|
||||
mariadb -h "${MYSQL_HOST}" -P "${MYSQL_PORT}" -u "${MYSQL_USERNAME}" -p"${MYSQL_PASSWORD}" "${MYSQL_DATABASE}" < "${RESTORE_FILE_DB}"
|
||||
local EXTRA_OPTIONS=()
|
||||
if [[ -n "${MYSQL_SSL}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl=\"${MYSQL_SSL}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_VERIFY_SERVER_CERT}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-verify-server-cert=\"${MYSQL_SSL_VERIFY_SERVER_CERT}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_CA}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-ca=\"${MYSQL_SSL_CA}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_CERT}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-cert=\"${MYSQL_SSL_CERT}\"")
|
||||
fi
|
||||
if [[ -n "${MYSQL_SSL_KEY}" ]]; then
|
||||
EXTRA_OPTIONS+=("--ssl-key=\"${MYSQL_SSL_KEY}\"")
|
||||
fi
|
||||
|
||||
eval "mariadb -h \"${MYSQL_HOST}\" -P \"${MYSQL_PORT}\" -u \"${MYSQL_USERNAME}\" -p\"${MYSQL_PASSWORD}\" --show-warnings ${EXTRA_OPTIONS[@]} \"${MYSQL_DATABASE}\" < \"${RESTORE_FILE_DB}\""
|
||||
|
||||
if [[ $? == 0 ]]; then
|
||||
color green "restore vaultwarden mysql database successful"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Encrypted rclone configuration File (ttionya)
|
||||
|
||||
RCLONE_ENCRYPT_V0:
|
||||
l3mwqE8IiDshJArOYQLMlsen3b/oGL2mT87k29sB0nnLch1gH8aV6oJYh5IrUvKtY8FeCKaNq0cENcYR5V0W7IcHqKFYl1lyo7nG
|
||||
@@ -5,8 +5,10 @@ DOCKER_IMAGE="ttionya/vaultwarden-backup:test"
|
||||
ERROR_NUM=0
|
||||
|
||||
DATA_DIR="$(pwd)/tests/fixtures/source/bitwarden/data"
|
||||
CONFIG_DIR="config"
|
||||
OUTPUT_DIR="output"
|
||||
EXTRACT_DIR="extract"
|
||||
TEMP_DIR="tmp"
|
||||
REMOTE_DIR="/${OUTPUT_DIR}"
|
||||
|
||||
########################################
|
||||
@@ -76,19 +78,29 @@ function check_files_same_in_folders() {
|
||||
# test result
|
||||
########################################
|
||||
function test_result() {
|
||||
local SEP="================================================================================"
|
||||
|
||||
if [[ "$2" == "0" ]]; then
|
||||
color green "Test case \"$1\" passed"
|
||||
color none "${SEP}${SEP}"
|
||||
return
|
||||
fi
|
||||
|
||||
((ERROR_NUM++))
|
||||
|
||||
color red "Test case \"$1\" failed"
|
||||
color none "${SEP}${SEP}"
|
||||
}
|
||||
|
||||
. tests/units/env-priority/test.sh
|
||||
. tests/units/check-rclone-config-exists/test.sh
|
||||
. tests/units/check-rclone-flags-valid/test.sh
|
||||
. tests/units/check-rclone-connection-initializing/test.sh
|
||||
. tests/units/check-encrypted-rclone-config/test.sh
|
||||
. tests/units/backup-zip-file/test.sh
|
||||
. tests/units/backup-7z-file/test.sh
|
||||
. tests/units/backup-unpackage/test.sh
|
||||
. tests/units/backup-cron/test.sh
|
||||
|
||||
if [[ "${ERROR_NUM}" == "0" ]]; then
|
||||
color green "All tests passed"
|
||||
|
||||
@@ -48,8 +48,18 @@ function test() {
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset TEST_EXTRACT_DIR
|
||||
unset PASSWORD
|
||||
unset BACKUP_FILE
|
||||
}
|
||||
|
||||
prepare
|
||||
start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
|
||||
TEST_NAME="backup-cron"
|
||||
TEST_CONTAINER_NAME="${TEST_NAME}"
|
||||
TEST_OUTPUT_DIR="$(pwd)/${OUTPUT_DIR}/${TEST_NAME}"
|
||||
|
||||
PASSWORD="faedea12-7f9e-4d84-983f-d049d9b82a36"
|
||||
BACKUP_FILE="${TEST_OUTPUT_DIR}/backup.test.zip"
|
||||
|
||||
FAILED_NUM=0
|
||||
|
||||
color yellow "Starting test case \"${TEST_NAME}\""
|
||||
|
||||
function prepare() {
|
||||
mkdir -p "${TEST_OUTPUT_DIR}"
|
||||
}
|
||||
|
||||
function start() {
|
||||
docker run --rm -d \
|
||||
--name "${TEST_CONTAINER_NAME}" \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "ZIP_PASSWORD=${PASSWORD}" \
|
||||
-e "BACKUP_FILE_SUFFIX=test" \
|
||||
-e "CRON=* * * * *" \
|
||||
"${DOCKER_IMAGE}"
|
||||
}
|
||||
|
||||
function test() {
|
||||
color blue "Testing..."
|
||||
|
||||
local TIMER=0
|
||||
local SUCCESS=FALSE
|
||||
|
||||
# wait 120s
|
||||
while [[ "${TIMER}" -lt 120 ]]; do
|
||||
if [[ -f "${BACKUP_FILE}" && -s "${BACKUP_FILE}" ]]; then
|
||||
SUCCESS=TRUE
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
((TIMER++))
|
||||
done
|
||||
|
||||
ls -l "${BACKUP_FILE}"
|
||||
|
||||
if [[ "${SUCCESS}" == "FALSE" ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
# stop the container
|
||||
docker stop "${TEST_CONTAINER_NAME}"
|
||||
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}"
|
||||
|
||||
unset TEST_CONTAINER_NAME
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset PASSWORD
|
||||
unset BACKUP_FILE
|
||||
}
|
||||
|
||||
prepare
|
||||
start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
@@ -45,8 +45,16 @@ function test() {
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset TEST_EXTRACT_DIR
|
||||
}
|
||||
|
||||
prepare
|
||||
start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
|
||||
@@ -47,8 +47,18 @@ function test() {
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset TEST_EXTRACT_DIR
|
||||
unset PASSWORD
|
||||
unset BACKUP_FILE
|
||||
}
|
||||
|
||||
prepare
|
||||
start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
TEST_NAME="check-encrypted-rclone-config"
|
||||
TEST_OUTPUT_DIR="$(pwd)/${OUTPUT_DIR}/${TEST_NAME}"
|
||||
TEST_EXTRACT_DIR="$(pwd)/${EXTRACT_DIR}/${TEST_NAME}"
|
||||
|
||||
PASSWORD="32d22daa-4e38-4c4c-8eeb-caf954d2259c"
|
||||
BACKUP_FILE="${TEST_OUTPUT_DIR}/backup.test.zip"
|
||||
|
||||
FAILED_NUM=0
|
||||
|
||||
color yellow "Starting test case \"${TEST_NAME}\""
|
||||
|
||||
function prepare() {
|
||||
mkdir -p "${TEST_OUTPUT_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
}
|
||||
|
||||
function start() {
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "RCLONE_GLOBAL_FLAG=--config /config/rclone/rclone.enc.conf" \
|
||||
-e "RCLONE_CONFIG_PASS=ttionya" \
|
||||
-e "ZIP_PASSWORD=${PASSWORD}" \
|
||||
-e "BACKUP_FILE_SUFFIX=test" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup
|
||||
}
|
||||
|
||||
function test() {
|
||||
color blue "Testing..."
|
||||
|
||||
ls -l "${BACKUP_FILE}"
|
||||
|
||||
7z l -p"${PASSWORD}" "${BACKUP_FILE}"
|
||||
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_EXTRACT_DIR},target=/bitwarden/data/" \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=/bitwarden/restore/" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
restore \
|
||||
-f \
|
||||
-p "${PASSWORD}" \
|
||||
--zip-file "$(basename "${BACKUP_FILE}")"
|
||||
|
||||
check_files_same_in_folders "${DATA_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
if [[ $? != 0 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset TEST_EXTRACT_DIR
|
||||
unset PASSWORD
|
||||
unset BACKUP_FILE
|
||||
}
|
||||
|
||||
prepare
|
||||
start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
# During Rclone connection verification, the configuration is considered complete
|
||||
# by checking for the presence of `RCLONE_REMOTE_NAME` in the configuration file.
|
||||
#
|
||||
# This test case ensures the verification method works by triggering the expected error message.
|
||||
|
||||
TEST_NAME="check-rclone-config-exits"
|
||||
TEST_OUTPUT_DIR="$(pwd)/${OUTPUT_DIR}/${TEST_NAME}"
|
||||
TEST_CONFIG_DIR="$(pwd)/${CONFIG_DIR}/${TEST_NAME}"
|
||||
|
||||
PASSWORD="231454f1-594c-45e2-8810-3ac917ebcf70"
|
||||
|
||||
FAILED_NUM=0
|
||||
|
||||
color yellow "Starting test case \"${TEST_NAME}\""
|
||||
|
||||
function prepare() {
|
||||
mkdir -p "${TEST_OUTPUT_DIR}" "${TEST_CONFIG_DIR}"
|
||||
}
|
||||
|
||||
# function start() {
|
||||
# }
|
||||
|
||||
function test() {
|
||||
color blue "Testing..."
|
||||
|
||||
FOUND_MESSAGE_COUNT=$(docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
--mount "type=bind,source=${TEST_CONFIG_DIR},target=/config" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "ZIP_PASSWORD=${PASSWORD}" \
|
||||
-e "BACKUP_FILE_SUFFIX=test" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup | grep -c "rclone configuration information not found")
|
||||
|
||||
if [[ "${FOUND_MESSAGE_COUNT}" -ne 1 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}" "${TEST_CONFIG_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset TEST_CONFIG_DIR
|
||||
unset PASSWORD
|
||||
unset FOUND_MESSAGE_COUNT
|
||||
}
|
||||
|
||||
prepare
|
||||
# start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
# When verifying the Rclone connection, the previous method ensured
|
||||
# the remote directory existed by creating it (mkdir), which requires special permissions on S3.
|
||||
# It has been changed to attempt listing the remote directory (lsd) to avoid this issue.
|
||||
# If listing the directory fails, the directory is considered non-existent and will be created.
|
||||
# See issue https://github.com/ttionya/vaultwarden-backup/issues/199 for details.
|
||||
#
|
||||
# This test case verifies that the remote directory can be created correctly without affecting the backup operation.
|
||||
|
||||
TEST_NAME="check-rclone-connection-initializing"
|
||||
TEST_OUTPUT_DIR="$(pwd)/${OUTPUT_DIR}/${TEST_NAME}"
|
||||
TEST_EXTRACT_DIR="$(pwd)/${EXTRACT_DIR}/${TEST_NAME}"
|
||||
TEST_DIR="/folder1/folder2/folder3"
|
||||
TEST_REMOTE_DIR="${REMOTE_DIR}${TEST_DIR}"
|
||||
|
||||
PASSWORD="9eeef525-24e9-496b-9e32-990211dce6eb"
|
||||
BACKUP_FILE="${TEST_OUTPUT_DIR}${TEST_DIR}/backup.test.zip"
|
||||
|
||||
FAILED_NUM=0
|
||||
|
||||
color yellow "Starting test case \"${TEST_NAME}\""
|
||||
|
||||
function prepare() {
|
||||
mkdir -p "${TEST_OUTPUT_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
}
|
||||
|
||||
function start() {
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
-e "RCLONE_REMOTE_DIR=${TEST_REMOTE_DIR}" \
|
||||
-e "ZIP_PASSWORD=${PASSWORD}" \
|
||||
-e "BACKUP_FILE_SUFFIX=test" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup
|
||||
}
|
||||
|
||||
function test() {
|
||||
color blue "Testing..."
|
||||
|
||||
ls -l "${BACKUP_FILE}"
|
||||
|
||||
7z l -p"${PASSWORD}" "${BACKUP_FILE}"
|
||||
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_EXTRACT_DIR},target=/bitwarden/data/" \
|
||||
--mount "type=bind,source=$(dirname "${BACKUP_FILE}"),target=/bitwarden/restore/" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
restore \
|
||||
-f \
|
||||
-p "${PASSWORD}" \
|
||||
--zip-file "$(basename "${BACKUP_FILE}")"
|
||||
|
||||
check_files_same_in_folders "${DATA_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
if [[ $? != 0 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}" "${TEST_EXTRACT_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset TEST_EXTRACT_DIR
|
||||
unset TEST_DIR
|
||||
unset TEST_REMOTE_DIR
|
||||
unset PASSWORD
|
||||
unset BACKUP_FILE
|
||||
}
|
||||
|
||||
prepare
|
||||
start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Using non-existent flags with Rclone will throw an exception and exit.
|
||||
#
|
||||
# This test case ensures the verification method works correctly by triggering the error message.
|
||||
|
||||
TEST_NAME="check-rclone-flags-valid"
|
||||
TEST_OUTPUT_DIR="$(pwd)/${OUTPUT_DIR}/${TEST_NAME}"
|
||||
|
||||
PASSWORD="43ef5fec-292d-4f9a-ab97-34f622deb462"
|
||||
|
||||
FAILED_NUM=0
|
||||
|
||||
color yellow "Starting test case \"${TEST_NAME}\""
|
||||
|
||||
function prepare() {
|
||||
mkdir -p "${TEST_OUTPUT_DIR}"
|
||||
}
|
||||
|
||||
# function start() {
|
||||
# }
|
||||
|
||||
function test() {
|
||||
color blue "Testing..."
|
||||
|
||||
FOUND_MESSAGE_COUNT=$(docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "RCLONE_GLOBAL_FLAG=-v --non-existent" \
|
||||
-e "ZIP_PASSWORD=${PASSWORD}" \
|
||||
-e "BACKUP_FILE_SUFFIX=test" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup | grep -c "illegal rclone global flags")
|
||||
|
||||
if [[ "${FOUND_MESSAGE_COUNT}" -ne 1 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset PASSWORD
|
||||
unset FOUND_MESSAGE_COUNT
|
||||
}
|
||||
|
||||
prepare
|
||||
# start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
@@ -0,0 +1,137 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The tool can set environment variables in four ways.
|
||||
# This test case tests the priority by setting different passwords for the environment variable `ZIP_PASSWORD`.
|
||||
|
||||
TEST_NAME="env-priority"
|
||||
TEST_OUTPUT_DIR="$(pwd)/${OUTPUT_DIR}/${TEST_NAME}"
|
||||
TEST_TEMP_DIR="$(pwd)/${TEMP_DIR}/${TEST_NAME}"
|
||||
|
||||
PASSWORD1="32aeec18-3bce-43af-b41d-7be04b0f7810" # For 1
|
||||
PASSWORD2="ce3cbc42-186b-4d1b-a1a9-3f10f0ec59c7" # For 2
|
||||
PASSWORD3="0e0fdbc1-5b2f-44db-ac7d-f0a8764992a7" # For 3
|
||||
PASSWORD4="0ddd9b27-ca9b-4912-b6fb-76569ec5cac1" # For 4
|
||||
PASSWORD2_FILE="${TEST_TEMP_DIR}/password2"
|
||||
PASSWORD3_FILE="${TEST_TEMP_DIR}/password3"
|
||||
BACKUP_FILE1="${TEST_OUTPUT_DIR}/backup.test1.zip"
|
||||
BACKUP_FILE2="${TEST_OUTPUT_DIR}/backup.test2.zip"
|
||||
BACKUP_FILE3="${TEST_OUTPUT_DIR}/backup.test3.zip"
|
||||
BACKUP_FILE4="${TEST_OUTPUT_DIR}/backup.test4.zip"
|
||||
ENV_FILE1="${TEST_TEMP_DIR}/.env1"
|
||||
ENV_FILE4="${TEST_TEMP_DIR}/.env4"
|
||||
|
||||
FAILED_NUM=0
|
||||
|
||||
color yellow "Starting test case \"${TEST_NAME}\""
|
||||
|
||||
function prepare() {
|
||||
mkdir -p "${TEST_OUTPUT_DIR}" "${TEST_TEMP_DIR}"
|
||||
|
||||
echo "${PASSWORD2}" > "${PASSWORD2_FILE}"
|
||||
echo "${PASSWORD3}" > "${PASSWORD3_FILE}"
|
||||
|
||||
cat > "${ENV_FILE1}" << EOF
|
||||
ZIP_PASSWORD_FILE="/password3"
|
||||
ZIP_PASSWORD="${PASSWORD4}"
|
||||
EOF
|
||||
cat > "${ENV_FILE4}" << EOF
|
||||
ZIP_PASSWORD="${PASSWORD4}"
|
||||
EOF
|
||||
}
|
||||
|
||||
function start() {
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
--mount "type=bind,source=${PASSWORD2_FILE},target=/password2" \
|
||||
--mount "type=bind,source=${PASSWORD3_FILE},target=/password3" \
|
||||
--mount "type=bind,source=${ENV_FILE1},target=/.env" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "ZIP_PASSWORD=${PASSWORD1}" \
|
||||
-e "ZIP_PASSWORD_FILE=/password2" \
|
||||
-e "BACKUP_FILE_SUFFIX=test1" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup
|
||||
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
--mount "type=bind,source=${PASSWORD2_FILE},target=/password2" \
|
||||
--mount "type=bind,source=${PASSWORD3_FILE},target=/password3" \
|
||||
--mount "type=bind,source=${ENV_FILE1},target=/.env" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "ZIP_PASSWORD_FILE=/password2" \
|
||||
-e "BACKUP_FILE_SUFFIX=test2" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup
|
||||
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
--mount "type=bind,source=${PASSWORD2_FILE},target=/password2" \
|
||||
--mount "type=bind,source=${PASSWORD3_FILE},target=/password3" \
|
||||
--mount "type=bind,source=${ENV_FILE1},target=/.env" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "BACKUP_FILE_SUFFIX=test3" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup
|
||||
|
||||
docker run --rm \
|
||||
--mount "type=bind,source=${TEST_OUTPUT_DIR},target=${REMOTE_DIR}" \
|
||||
--mount "type=bind,source=${PASSWORD2_FILE},target=/password2" \
|
||||
--mount "type=bind,source=${PASSWORD3_FILE},target=/password3" \
|
||||
--mount "type=bind,source=${ENV_FILE4},target=/.env" \
|
||||
-e "RCLONE_REMOTE_DIR=${REMOTE_DIR}" \
|
||||
-e "BACKUP_FILE_SUFFIX=test4" \
|
||||
"${DOCKER_IMAGE}" \
|
||||
backup
|
||||
}
|
||||
|
||||
function test() {
|
||||
color blue "Testing..."
|
||||
|
||||
ls -l "${TEST_OUTPUT_DIR}"
|
||||
|
||||
7z t -p"${PASSWORD1}" "${BACKUP_FILE1}"
|
||||
if [[ $? != 0 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
|
||||
7z t -p"${PASSWORD2}" "${BACKUP_FILE2}"
|
||||
if [[ $? != 0 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
|
||||
7z t -p"${PASSWORD3}" "${BACKUP_FILE3}"
|
||||
if [[ $? != 0 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
|
||||
7z t -p"${PASSWORD4}" "${BACKUP_FILE4}"
|
||||
if [[ $? != 0 ]]; then
|
||||
((FAILED_NUM++))
|
||||
fi
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
sudo rm -rf "${TEST_OUTPUT_DIR}" "${TEST_TEMP_DIR}"
|
||||
|
||||
unset TEST_OUTPUT_DIR
|
||||
unset TEST_TEMP_DIR
|
||||
unset PASSWORD1
|
||||
unset PASSWORD2
|
||||
unset PASSWORD3
|
||||
unset PASSWORD4
|
||||
unset PASSWORD2_FILE
|
||||
unset PASSWORD3_FILE
|
||||
unset BACKUP_FILE1
|
||||
unset BACKUP_FILE2
|
||||
unset BACKUP_FILE3
|
||||
unset BACKUP_FILE4
|
||||
unset ENV_FILE1
|
||||
unset ENV_FILE4
|
||||
}
|
||||
|
||||
prepare
|
||||
start
|
||||
test
|
||||
cleanup
|
||||
|
||||
test_result "${TEST_NAME}" "${FAILED_NUM}"
|
||||
Reference in New Issue
Block a user