wip
This commit is contained in:
260
README.md
260
README.md
@@ -1,58 +1,270 @@
|
||||
# CloudSave
|
||||
|
||||
The software is still in alpha.
|
||||
CloudSave is a small client/server tool to keep save folders in sync across multiple computers.
|
||||
It is aimed at games that do not provide their own cloud sync, such as emulators, old games, or any title that stores progress in a local directory.
|
||||
|
||||
A client/server that allows unsynchronized games (such as emulators, old games, etc.) to be kept up to date on multiple computers.
|
||||
The project is still in alpha.
|
||||
|
||||
## What Is In The Repository
|
||||
|
||||
This repository currently contains three Go binaries:
|
||||
|
||||
- `cmd/cli`: the end-user CLI (`cloudsave`)
|
||||
- `cmd/server`: the HTTP API server
|
||||
- `cmd/web`: a small read-only web UI that talks to the API server
|
||||
|
||||
## Build
|
||||
|
||||
You need go1.24
|
||||
The module targets Go `1.24` in [go.mod](/home/aurelie/src/cloudsave/go.mod), while the container image builds with Go `1.26.3` from [dockerfile](/home/aurelie/src/cloudsave/dockerfile). In practice, using a recent Go toolchain is recommended.
|
||||
|
||||
After downloading the go toolchain, just run the script `./build.sh`
|
||||
To build all binaries for the platforms configured in the project:
|
||||
|
||||
## Usage
|
||||
|
||||
### Server
|
||||
|
||||
The server needs an empty directory. After creating this directory, you need to make a file that contains your credential. The format is "username:password". The server only understand bcrypt password hash for now.
|
||||
|
||||
e.g.:
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
Artifacts are written to `./build`.
|
||||
|
||||
If you only want one binary, you can also build it directly:
|
||||
|
||||
```bash
|
||||
go build -o cloudsave ./cmd/cli
|
||||
go build -o cloudsave_server ./cmd/server
|
||||
go build -o cloudsave_web ./cmd/web
|
||||
```
|
||||
|
||||
## Server
|
||||
|
||||
The server exposes an authenticated HTTP API on port `8080` by default.
|
||||
|
||||
### Data Directory
|
||||
|
||||
By default, the server uses:
|
||||
|
||||
```text
|
||||
/var/lib/cloudsave
|
||||
```
|
||||
|
||||
You can override it with:
|
||||
|
||||
```bash
|
||||
cloudsave_server -document-root /path/to/cloudsave-data
|
||||
```
|
||||
|
||||
Inside this directory, the server expects:
|
||||
|
||||
- `.htpasswd`: credentials file
|
||||
- `data/`: stored save archives and metadata
|
||||
|
||||
### Authentication
|
||||
|
||||
The API uses HTTP Basic Auth. Credentials are read from `.htpasswd`.
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
test:$2y$10$uULsuyROe3LVdTzFoBH7HO0zhvyKp6CX2FDNl7quXMFYqzitU0kc.
|
||||
```
|
||||
|
||||
To generate bcrypt password, I recommand [hash_utils](https://git.thelilfrog.com/thelilfrog/hash_utils), which is offline and secure
|
||||
The code currently expects bcrypt hashes when validating passwords.
|
||||
|
||||
The default path to this directory is `/var/lib/cloudsave`, this can be changed with the `-document-root` argument
|
||||
### Start The Server
|
||||
|
||||
### Client
|
||||
```bash
|
||||
cloudsave_server
|
||||
```
|
||||
|
||||
#### Register a game
|
||||
Useful flags from [cmd/server/runner.go](/home/aurelie/src/cloudsave/cmd/server/runner.go):
|
||||
|
||||
- `-document-root`: change the storage directory
|
||||
- `-port`: change the listening port
|
||||
- `-no-cache`: use the lazy repository instead of the eager cache
|
||||
- `-verbose`: enable more logs
|
||||
|
||||
On non-Windows systems, sending `SIGHUP` reloads the eager cache and the `.htpasswd` file.
|
||||
|
||||
## Docker
|
||||
|
||||
The repository contains a server-only container setup:
|
||||
|
||||
- [dockerfile](/home/aurelie/src/cloudsave/dockerfile)
|
||||
- [docker-compose.yml](/home/aurelie/src/cloudsave/docker-compose.yml)
|
||||
|
||||
Run it with:
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
This maps:
|
||||
|
||||
- port `8080`
|
||||
- local `./data` to `/var/lib/cloudsave`
|
||||
|
||||
Before starting the container, you still need to create `./data/.htpasswd`.
|
||||
|
||||
## Client
|
||||
|
||||
The CLI stores its local database in the user config directory under `cloudsave/data`.
|
||||
|
||||
It keeps:
|
||||
|
||||
- per-game metadata
|
||||
- current local archive
|
||||
- backup archives
|
||||
- `remote.json` per game when a remote is configured
|
||||
|
||||
Saved credentials are stored separately in `credential.json`.
|
||||
|
||||
Important: the `login` command stores credentials in plain text. This is also stated in the code.
|
||||
|
||||
## Typical Workflow
|
||||
|
||||
### 1. Register a game
|
||||
|
||||
You can register a game with the verb `add`
|
||||
```bash
|
||||
cloudsave add /home/user/gamedata
|
||||
```
|
||||
|
||||
You can also change the name of the registration and add a remote
|
||||
You can override the displayed name:
|
||||
|
||||
```bash
|
||||
cloudsave add -name "My Game" -remote "http://localhost:8080" /home/user/gamedata
|
||||
cloudsave add -name "My Game" /home/user/gamedata
|
||||
```
|
||||
|
||||
#### Make an archive of the current state
|
||||
Note: the `-remote` flag exists on `add`, but the current implementation does not persist it. Use `cloudsave remote -set` after `add`.
|
||||
|
||||
This is a command line tool, it cannot auto detect changes.
|
||||
Run this command to start the scan, if needed, the tool will create a new archive
|
||||
### 2. List registered games
|
||||
|
||||
```bash
|
||||
cloudsave list
|
||||
```
|
||||
|
||||
To include local backup IDs:
|
||||
|
||||
```bash
|
||||
cloudsave list -include-backup
|
||||
```
|
||||
|
||||
### 3. Create or refresh the local archive
|
||||
|
||||
```bash
|
||||
cloudsave scan
|
||||
```
|
||||
#### Send everything on the server
|
||||
|
||||
This will pull and push data to the server.
|
||||
This scans all registered folders. If a folder changed since the last scan, the current archive is moved to the backup history and a new `data.tar.gz` archive is created.
|
||||
|
||||
Note: If multiple computers are pushing to this server, a conflict may be generated. If so, the tool will ask for the version to keep
|
||||
### 4. Configure the remote server for a game
|
||||
|
||||
```bash
|
||||
cloudsave remote -set GAME_ID http://localhost:8080
|
||||
```
|
||||
|
||||
To list configured remotes:
|
||||
|
||||
```bash
|
||||
cloudsave remote -list
|
||||
```
|
||||
|
||||
### 5. Save credentials locally
|
||||
|
||||
```bash
|
||||
cloudsave login http://localhost:8080
|
||||
```
|
||||
|
||||
This verifies the credentials against the server and then stores them locally in plain text.
|
||||
|
||||
### 6. Synchronize with the server
|
||||
|
||||
```bash
|
||||
cloudsave sync
|
||||
```
|
||||
|
||||
The sync command:
|
||||
|
||||
- groups games by remote URL
|
||||
- authenticates once per remote
|
||||
- compares local and remote metadata
|
||||
- pushes or pulls as needed
|
||||
- asks for a resolution if versions conflict
|
||||
|
||||
### 7. Restore a save locally
|
||||
|
||||
Apply the latest local archive for a game:
|
||||
|
||||
```bash
|
||||
cloudsave apply GAME_ID
|
||||
```
|
||||
|
||||
Apply a specific backup:
|
||||
|
||||
```bash
|
||||
cloudsave apply GAME_ID BACKUP_ID
|
||||
```
|
||||
|
||||
## Other CLI Commands
|
||||
|
||||
Show metadata for one game:
|
||||
|
||||
```bash
|
||||
cloudsave show GAME_ID
|
||||
```
|
||||
|
||||
Pull one game and its backups from a remote into a local path:
|
||||
|
||||
```bash
|
||||
cloudsave pull http://localhost:8080 GAME_ID /path/to/restore
|
||||
```
|
||||
|
||||
Show local version information:
|
||||
|
||||
```bash
|
||||
cloudsave version
|
||||
```
|
||||
|
||||
Show remote version information:
|
||||
|
||||
```bash
|
||||
cloudsave version -a http://localhost:8080
|
||||
```
|
||||
|
||||
Remove a registered game and its local backups:
|
||||
|
||||
```bash
|
||||
cloudsave remove GAME_ID
|
||||
```
|
||||
|
||||
## Web UI
|
||||
|
||||
The repository also contains a small web frontend in `cmd/web`.
|
||||
|
||||
It uses a JSON config file, for example:
|
||||
|
||||
```json
|
||||
{
|
||||
"server": {
|
||||
"port": 8081
|
||||
},
|
||||
"remote": {
|
||||
"url": "http://localhost:8080"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then start it with:
|
||||
|
||||
```bash
|
||||
cloudsave_web -config /path/to/config.json
|
||||
```
|
||||
|
||||
The web UI itself does not manage users. It forwards HTTP Basic Auth credentials to the configured API server.
|
||||
|
||||
## Current Caveats
|
||||
|
||||
These points are worth knowing in the current state of the project:
|
||||
|
||||
- the software is still alpha
|
||||
- credentials saved by `cloudsave login` are stored in plain text
|
||||
- the Docker setup only runs the API server, not the web UI
|
||||
- `add -remote` is exposed by the CLI but is not currently persisted by the service layer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user