Use standard directories when running on Linux (#91)

* Use standard Linux directories for application data (https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)

* Use standard system directories

* Cleanup all Polaris files during uninstall

* Expose get_pid_directory to rest of the crate

* Add separate targets for install binary and data files, clean up makefile

* Use environment variables for directory locations during install process

* On Linux, read locations from environment variables at compile time

* Split static_directory in two (web and swagger directories)

* Follow recommendations from the Make manual

* Avoid redundant directories

* Added workflow to validate installer setup

* Added CLI options to locate log file, pid file and cache directory

* Fixed an issue where build command did not support the xdg/system switch

* Renamed log option to log-level

* Fixed an issue where xdg install would do a system build

* Use re-usable action to make linux release

* Avoid nested actions (see https://github.com/actions/runner/issues/646)

* Updated installation instructions

* Replaced deprecated use of set-env
This commit is contained in:
Antoine Gersant 2020-11-26 15:57:08 -08:00 committed by GitHub
parent 0927f3815e
commit 538b41a2b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 421 additions and 188 deletions

View file

@ -0,0 +1,28 @@
name: 'Make a Linux Release'
description: 'Creates archive containing files to install Polaris on on a Linux system'
inputs:
version-number:
description: 'Polaris version number'
required: true
default: '0.0'
output-file:
description: 'File path where the resulting archive should be stored'
required: false
default: 'polaris.tar.gz'
runs:
using: "composite"
steps:
- name: Download Polaris Web
run: |
curl -L -o web.zip https://github.com/agersant/polaris-web/releases/latest/download/web.zip
unzip web.zip
shell: bash
- name: Set Polaris version
run: echo "POLARIS_VERSION=${{ inputs.version-number }}" >> $GITHUB_ENV
shell: bash
- name: Build archive
run: res/unix/release_script.sh
shell: bash
- name: Copy archive to output location
run: cp release/polaris.tar.gz ${{ inputs.output-file }}
shell: bash

View file

@ -0,0 +1,28 @@
name: 'Make a Windows Release'
description: 'Creates archive containing files to install Polaris on on a Windows system'
inputs:
version-number:
description: 'Polaris version number'
required: true
default: '0.0'
output-file:
description: 'File path where the resulting installer should be stored'
required: false
default: 'polaris.msi'
runs:
using: "composite"
steps:
- name: Download Polaris Web
run: |
curl -L -o web.zip https://github.com/agersant/polaris-web/releases/latest/download/web.zip
unzip web.zip
shell: bash
- name: Set Polaris Version
run: echo "POLARIS_VERSION=${{ inputs.version-number }}" >> $GITHUB_ENV
shell: bash
- name: Build Installer
run: res/windows/release_script
shell: pwsh
- name: Copy installer to output location
run: cp release/polaris.msi ${{ inputs.output-file }}
shell: bash

View file

@ -13,7 +13,7 @@ jobs:
steps:
- name: Read Polaris Version
run: echo ::set-env name=POLARIS_VERSION::${GITHUB_REF:10}
run: echo "POLARIS_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Create Github Release
id: create_release
uses: actions/create-release@v1.0.0
@ -40,35 +40,30 @@ jobs:
steps:
- name: Checkout Polaris
uses: actions/checkout@v1
- name: Download Polaris Web
run: |
curl -L -o web.zip https://github.com/agersant/polaris-web/releases/latest/download/web.zip
unzip web.zip
- name: Read Polaris Version
shell: bash
run: echo "POLARIS_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Install Rust Toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
profile: minimal
default: true
- name: Read Polaris Version
shell: bash
run: echo ::set-env name=POLARIS_VERSION::${GITHUB_REF:10}
- name: Build Installer
run: res/windows/release_script
- name: Retrieve Upload URL
uses: actions/download-artifact@v1
- name: Make release
uses: ./.github/actions/make-windows-release
with:
name: release
version-number: ${{ env.POLARIS_VERSION }}
output-file: polaris.msi
- name: Read Upload URL
shell: bash
run: echo ::set-env name=UPLOAD_URL::$(cat release/upload-url)
run: echo "UPLOAD_URL=$(cat release/upload-url)" >> $GITHUB_ENV
- name: Upload Installer To Github Release
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ env.UPLOAD_URL }}
asset_path: ./release/Polaris_${{ env.POLARIS_VERSION }}.msi
asset_path: polaris.msi
asset_name: Polaris_${{ env.POLARIS_VERSION }}.msi
asset_content_type: application/x-msi
@ -80,26 +75,25 @@ jobs:
steps:
- name: Checkout Polaris
uses: actions/checkout@v1
- name: Download Polaris Web
run: |
curl -L -o web.zip https://github.com/agersant/polaris-web/releases/latest/download/web.zip
unzip web.zip
- name: Read Polaris Version
run: echo ::set-env name=POLARIS_VERSION::${GITHUB_REF:10}
- name: Build Archive
run: res/unix/release_script.sh
run: echo "POLARIS_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV
- name: Make release
uses: ./.github/actions/make-linux-release
with:
version-number: ${{ env.POLARIS_VERSION }}
output-file: polaris.tar.gz
- name: Retrieve Upload URL
uses: actions/download-artifact@v1
with:
name: release
- name: Read Upload URL
run: echo ::set-env name=UPLOAD_URL::$(cat release/upload-url)
run: echo "UPLOAD_URL=$(cat release/upload-url)" >> $GITHUB_ENV
- name: Upload To Github Release
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ env.UPLOAD_URL }}
asset_path: ./release/Polaris_${{ env.POLARIS_VERSION }}.tar.gz
asset_path: polaris.tar.gz
asset_name: Polaris_${{ env.POLARIS_VERSION }}.tar.gz
asset_content_type: application/gzip

139
.github/workflows/validate-install.yml vendored Normal file
View file

@ -0,0 +1,139 @@
on:
pull_request:
push:
name: Validate Install
jobs:
package_linux_release:
name: Package Linux Release
runs-on: ubuntu-latest
steps:
- name: Checkout Polaris
uses: actions/checkout@v1
- name: Make release
uses: ./.github/actions/make-linux-release
with:
version-number: '0.0'
output-file: polaris.tar.gz
- name: Upload packaged release
uses: actions/upload-artifact@v2
with:
name: linux-release
path: polaris.tar.gz
validate_linux_system_install:
name: Linux System Install
runs-on: ubuntu-latest
needs: package_linux_release
steps:
- name: Download release
uses: actions/download-artifact@v2
with:
name: linux-release
path: .
- name: Extract release
run: tar -xzvf polaris.tar.gz --strip-components=1
- name: Preview Install
run: make preview
- name: Preview Install w/ Custom Prefix
run: make preview PREFIX=/some/random/prefix
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
profile: minimal
default: true
- name: Install
run: sudo --preserve-env=PATH make install
- name: Run Polaris
run: sudo /usr/local/bin/polaris && sleep 5s
- name: Make a request
run: curl -f http://localhost:5050
- name: Stop Polaris
run: sudo kill -KILL $(cat /usr/local/var/run/polaris/polaris.pid)
- name: Uninstall
run: sudo make uninstall
validate_linux_xdg_install:
name: Linux XDG Install
runs-on: ubuntu-latest
needs: package_linux_release
steps:
- name: Download release
uses: actions/download-artifact@v2
with:
name: linux-release
path: .
- name: Extract release
run: tar -xzvf polaris.tar.gz --strip-components=1
- name: Preview Install
run: make preview-xdg
- name: Preview Install w/ Custom XDG_DATA_HOME
run: make preview-xdg XDG_DATA_HOME=/my/own/xdg/home
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
profile: minimal
default: true
- name: Install
run: make install-xdg
- name: Run Polaris
run: $HOME/.local/bin/polaris && sleep 5s
- name: Make a request
run: curl -f http://localhost:5050
- name: Stop Polaris
run: kill -KILL $(cat /tmp/polaris-1001/polaris.pid)
- name: Uninstall
run: make uninstall-xdg
package_windows_release:
name: Package Windows Release
runs-on: windows-latest
steps:
- name: Checkout Polaris
uses: actions/checkout@v1
- name: Install Rust Toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
profile: minimal
default: true
- name: Make release
uses: ./.github/actions/make-windows-release
with:
version-number: '0.0'
output-file: polaris.msi
- name: Upload packaged release
uses: actions/upload-artifact@v2
with:
name: windows-release
path: polaris.msi
validate_windows_install:
name: Windows Install
runs-on: windows-latest
needs: package_windows_release
steps:
- name: Download release
uses: actions/download-artifact@v2
with:
name: windows-release
path: .
- name: Install
run: msiexec /i polaris.msi /qn
- name: Run Polaris
run: |
start $env:LOCALAPPDATA/Permafrost/Polaris/polaris-cli.exe
sleep 5
- name: Make a request
run: curl -f http://localhost:5050
- name: Stop Polaris
run: taskkill /IM polaris-cli.exe
- name: Uninstall
run: msiexec /x polaris.msi /qn

6
.gitignore vendored
View file

@ -10,6 +10,10 @@ index-flame-graph.html
# Local config for quick iteration
TestConfig.toml
# Release process artefacts (usually runs on CI)
# Runtime artifacts
*.sqlite
thumbnails
# Release process artifacts (usually runs on CI)
release
*.res

39
Cargo.lock generated
View file

@ -100,18 +100,6 @@ dependencies = [
"byteorder",
]
[[package]]
name = "app_dirs"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d"
dependencies = [
"ole32-sys",
"shell32-sys",
"winapi 0.2.8",
"xdg",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -1647,16 +1635,6 @@ dependencies = [
"byteorder",
]
[[package]]
name = "ole32-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "opaque-debug"
version = "0.2.3"
@ -1833,7 +1811,6 @@ version = "0.12.4"
dependencies = [
"anyhow",
"ape",
"app_dirs",
"base64 0.12.3",
"cookie 0.14.3",
"crossbeam-channel 0.4.4",
@ -2518,16 +2495,6 @@ dependencies = [
"opaque-debug 0.3.0",
]
[[package]]
name = "shell32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "simplelog"
version = "0.8.0"
@ -3328,12 +3295,6 @@ dependencies = [
"winapi-build",
]
[[package]]
name = "xdg"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
[[package]]
name = "yansi"
version = "0.5.0"

View file

@ -6,14 +6,13 @@ edition = "2018"
[features]
default = ["service-rocket"]
ui = []
ui = ["uuid", "winapi"]
profile-index = ["flame", "flamer"]
service-rocket = ["rocket", "rocket_contrib"]
[dependencies]
anyhow = "1.0.31"
ape = "0.3.0"
app_dirs = "1.1.1"
base64 = "0.12.1"
crossbeam-channel = "0.4"
diesel = { version = "1.4.4", features = ["sqlite", "r2d2"] }
@ -54,11 +53,8 @@ features = ["json", "serve"]
optional = true
[target.'cfg(windows)'.dependencies]
uuid = "0.8"
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3.3"
features = ["winuser", "libloaderapi", "shellapi", "errhandlingapi"]
uuid = { version="0.8", optional = true }
winapi = { version = "0.3.3", features = ["winuser", "libloaderapi", "shellapi", "errhandlingapi"], optional = true }
[target.'cfg(unix)'.dependencies]
sd-notify = "0.1.0"

View file

@ -4,7 +4,7 @@
Compiling and running Polaris is very easy as it only depends on the Rust toolchain.
1. [Install Rust](https://www.rust-lang.org/en-US/install.html)
1. [Install Rust](https://www.rust-lang.org/en-US/install.html), you need the `nightly` version of the toolchain
2. Clone the polaris depot with this command: `git clone --recursive https://github.com/agersant/polaris.git`
3. You can now run compile and run polaris from the newly created directory with the command: `cargo run`

View file

@ -6,8 +6,6 @@ One of the following:
- Windows 7 or newer
- Linux (any reasonably modern distribution should do)
## Installation
### Windows
1. Download the [latest installer](https://github.com/agersant/polaris/releases/latest) (you want the .msi file)
2. Run the installer
@ -24,14 +22,14 @@ You can now start Polaris from the start menu or from your desktop, Polaris will
#### Polaris installation
1. Download the [latest release]((https://github.com/agersant/polaris/releases/latest)) of Polaris (you want the .tar.gz file)
2. Extract the polaris archive in a directory and open a terminal in that directory
3. Execute `make install` (this may take several minutes)
2. Extract the Polaris archive in a directory and open a terminal in that directory
3. To install Polaris within your home directory, execute `make install-xdg`. This installation follows the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html). You can use `make preview-xdg` to see which directories the install process would use.
4. If you prefer a system-wide install, execute `make install` (without the `-xdg` suffix). If you use `sudo` to perform such a system install, you may need the `-E` option so that your sudo user find the Rust binaries: `sudo -E make install`. This installation follows the [GNU Standard Installation Directories](https://www.gnu.org/prep/standards/html_node/Directory-Variables.html). You can use `make preview` to see which directories the install process would use.
This installation process puts the polaris executable in `~/.local/bin/polaris` and several data files under `~/.local/share/polaris`.
From here, you might want to adjust your system to run Polaris on login using Cron, Systemd or whichever method your distribution endorses.
From here, you might want to adjust your system to run Polaris on login using Systemd, Cron or whichever method your distribution endorses.
If you want to uninstall Polaris, execute `make uninstall` from the extracted archive's directory. This will simply delete the directories created by the install process.
If you want to uninstall Polaris, execute `make uninstall` from the extracted archive's directory. This will delete all the files and directories listed above **including your Polaris database**. If you customized the install process by specifying environment variables like `PREFIX`, make sure they are set to the same values when running `make uninstall`.
### In a docker container
@ -39,6 +37,6 @@ To run polaris from a Docker container, please follow instructions from the [doc
## Test Run
- Start Polaris using the shortcut on your desktop (Windows) or by running the executable in `~/.local/bin/polaris` (Linux)
- Start Polaris using the shortcut on your desktop (Windows) or by running the Polaris executable
- In your Web browser, access http://localhost:5050
- You will see a welcome page that will guide you through the Polaris configuration

View file

@ -1,22 +1,96 @@
POLARIS_BIN_DIR := ~/.local/bin/polaris
POLARIS_DATA_DIR := ~/.local/share/polaris
.PHONY: all build build-system build-xdg cargo-build clean preview preview-system preview-xdg list-paths install install-bin install-data install-system install-xdg uninstall uninstall-bin uninstall-data uninstall-system uninstall-xdg
all: build
UID := $(shell id -u)
build:
PREFIX ?= /usr/local
EXEC_PREFIX ?= $(PREFIX)
BINDIR ?= $(EXEC_PREFIX)/bin
DATAROOTDIR ?= $(PREFIX)/share
DATADIR ?= $(DATAROOTDIR)
LOCALSTATEDIR ?= $(PREFIX)/var
RUNSTATEDIR ?= $(LOCALSTATEDIR)/run
%-system: POLARIS_BIN_PATH := $(BINDIR)/polaris
%-system: export POLARIS_WEB_DIR := $(DATADIR)/polaris/web
%-system: export POLARIS_SWAGGER_DIR := $(DATADIR)/polaris/swagger
%-system: export POLARIS_DB_DIR := $(LOCALSTATEDIR)/lib/polaris
%-system: export POLARIS_LOG_DIR := $(LOCALSTATEDIR)/log/polaris
%-system: export POLARIS_CACHE_DIR := $(LOCALSTATEDIR)/cache/polaris
%-system: export POLARIS_PID_DIR := $(RUNSTATEDIR)/polaris
XDG_CACHE_HOME ?= $(HOME)/.cache
XDG_DATA_HOME ?= $(HOME)/.local/share
XDG_BINDIR ?= $(HOME)/.local/bin
XDG_DATADIR ?= $(XDG_DATA_HOME)/polaris
XDG_CACHEDIR ?= $(XDG_CACHE_HOME)/polaris
ifdef $(XDG_RUNTIME_DIR)
XDG_PIDDIR ?= $(XDG_RUNTIME_DIR)/polaris
else
XDG_PIDDIR ?= /tmp/polaris-$(UID)
endif
%-xdg: POLARIS_BIN_PATH := $(XDG_BINDIR)/polaris
%-xdg: export POLARIS_WEB_DIR := $(XDG_DATADIR)/web
%-xdg: export POLARIS_SWAGGER_DIR := $(XDG_DATADIR)/swagger
%-xdg: export POLARIS_DB_DIR := $(XDG_DATADIR)
%-xdg: export POLARIS_LOG_DIR := $(XDG_CACHEDIR)
%-xdg: export POLARIS_CACHE_DIR := $(XDG_CACHEDIR)
%-xdg: export POLARIS_PID_DIR := $(XDG_PIDDIR)
# Build
build-system: cargo-build
build-xdg: cargo-build
build: build-system
all: build-system
cargo-build:
cargo build --release
install: build
install -d $(POLARIS_BIN_DIR)
install -d $(POLARIS_DATA_DIR)
install ./target/release/polaris $(POLARIS_BIN_DIR)
cp -r ./web $(POLARIS_DATA_DIR)
cp -r ./swagger $(POLARIS_DATA_DIR)
@echo "Polaris installation complete!"
clean:
cargo clean
uninstall:
rm -r $(POLARIS_BIN_DIR)
rm -r $(POLARIS_DATA_DIR)
# Preview
preview-system: list-paths
preview-xdg: list-paths
preview: preview-system
list-paths:
$(info POLARIS_BIN_PATH is $(POLARIS_BIN_PATH))
$(info POLARIS_WEB_DIR is $(POLARIS_WEB_DIR))
$(info POLARIS_SWAGGER_DIR is $(POLARIS_SWAGGER_DIR))
$(info POLARIS_DB_DIR is $(POLARIS_DB_DIR))
$(info POLARIS_LOG_DIR is $(POLARIS_LOG_DIR))
$(info POLARIS_CACHE_DIR is $(POLARIS_CACHE_DIR))
$(info POLARIS_PID_DIR is $(POLARIS_PID_DIR))
# Install
install-system: install-bin install-data
install-xdg: install-bin install-data
install: install-system
install-bin: cargo-build
install -Dm755 ./target/release/polaris $(POLARIS_BIN_PATH)
install-data:
install -d $(POLARIS_WEB_DIR)
install -d $(POLARIS_SWAGGER_DIR)
cp -rT ./web $(POLARIS_WEB_DIR)
cp -rT ./swagger $(POLARIS_SWAGGER_DIR)
# Uninstall
uninstall-system: uninstall-bin uninstall-data
uninstall-xdg: uninstall-bin uninstall-data
uninstall: uninstall-system
uninstall-bin:
rm $(POLARIS_BIN_PATH)
uninstall-data:
rm -rf $(POLARIS_WEB_DIR)
rm -rf $(POLARIS_SWAGGER_DIR)
rm -rf $(POLARIS_DB_DIR)
rm -rf $(POLARIS_LOG_DIR)
rm -rf $(POLARIS_CACHE_DIR)
rm -rf $(POLARIS_PID_DIR)

View file

@ -6,8 +6,7 @@ echo "Copying package files"
cp -r web docs/swagger src migrations test-data Cargo.toml Cargo.lock res/unix/Makefile release/tmp/polaris
echo "Creating tarball"
POLARIS_VERSION=$(grep -m 1 ^version Cargo.toml | awk '{print $3}' | tr -d '"\r\n')
tar -zc -C release/tmp -f release/Polaris_$POLARIS_VERSION.tar.gz polaris
tar -zc -C release/tmp -f release/polaris.tar.gz polaris
echo "Cleaning up"
rm -rf release/tmp

View file

@ -1,7 +1,5 @@
Get-ChildItem "Cargo.toml" | ForEach-Object {
$conf = $_ | Get-Content -raw
$conf -match 'version\s+=\s+"(.*)"' | out-null
$script:POLARIS_VERSION = $matches[1]
if (!(Test-Path env:POLARIS_VERSION)) {
throw "POLARIS_VERSION environment variable is not defined"
}
"Compiling resource file"
@ -10,6 +8,13 @@ $rc_exe = Join-Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64
""
"Compiling executable"
$script:INSTALL_DIR = "$env:LOCALAPPDATA\Permafrost\Polaris"
$env:POLARIS_WEB_DIR = "$INSTALL_DIR\web"
$env:POLARIS_SWAGGER_DIR = "$INSTALL_DIR\swagger"
$env:POLARIS_DB_DIR = "$INSTALL_DIR"
$env:POLARIS_LOG_DIR = "$INSTALL_DIR"
$env:POLARIS_CACHE_DIR = "$INSTALL_DIR"
$env:POLARIS_PID_DIR = "$INSTALL_DIR"
cargo rustc --release --features "ui" -- -C link-args="/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup res\windows\application\application.res"
cargo rustc --release -- -o ".\target\release\polaris-cli.exe" -C link-args="res\windows\application\application.res"
@ -31,7 +36,7 @@ Copy-Item .\docs\swagger .\release\tmp\swagger -recurse
""
"Inserting version number in installer config"
[xml]$wxs = Get-Content .\res\windows\installer\installer.wxs
$wxs.Wix.Product.SetAttribute("Version", $POLARIS_VERSION)
$wxs.Wix.Product.SetAttribute("Version", $env:POLARIS_VERSION)
$wxs.Save('.\res\windows\installer\installer.wxs')
""
@ -46,7 +51,7 @@ $candle_exe = Join-Path $env:WIX bin\candle.exe
& $candle_exe -wx -ext WixUtilExtension -arch x64 -out .\release\tmp\installer.wixobj .\res\windows\installer\installer.wxs
$light_exe = Join-Path $env:WIX bin\light.exe
& $light_exe -dWebUIDir=".\release\tmp\web" -dSwaggerUIDir=".\release\tmp\swagger" -wx -ext WixUtilExtension -ext WixUIExtension -spdb -sw1076 -sice:ICE38 -sice:ICE64 -out .\release\Polaris_$POLARIS_VERSION.msi .\release\tmp\installer.wixobj .\release\tmp\web_ui_fragment.wixobj .\release\tmp\swagger_ui_fragment.wixobj
& $light_exe -dWebUIDir=".\release\tmp\web" -dSwaggerUIDir=".\release\tmp\swagger" -wx -ext WixUtilExtension -ext WixUIExtension -spdb -sw1076 -sice:ICE38 -sice:ICE64 -out .\release\polaris.msi .\release\tmp\installer.wixobj .\release\tmp\web_ui_fragment.wixobj .\release\tmp\swagger_ui_fragment.wixobj
"Cleaning up"
Remove-Item -Recurse .\release\tmp

View file

@ -3,7 +3,6 @@ use diesel::r2d2::{self, ConnectionManager, PooledConnection};
use diesel::sqlite::SqliteConnection;
use diesel::RunQueryDsl;
use diesel_migrations;
use log::info;
use std::path::Path;
mod schema;
@ -42,7 +41,6 @@ impl diesel::r2d2::CustomizeConnection<SqliteConnection, diesel::r2d2::Error>
impl DB {
pub fn new(path: &Path) -> Result<DB> {
info!("Database file path: {}", path.to_string_lossy());
let manager = ConnectionManager::<SqliteConnection>::new(path.to_string_lossy());
let pool = diesel::r2d2::Pool::builder()
.connection_customizer(Box::new(ConnectionCustomizer {}))

View file

@ -14,8 +14,6 @@ use log::error;
#[cfg(unix)]
use sd_notify::{self, NotifyState};
#[cfg(unix)]
use std::fs::File;
#[cfg(unix)]
use std::io::prelude::*;
#[cfg(unix)]
use unix_daemonize::{daemonize_redirect, ChdirMode};
@ -24,7 +22,8 @@ use anyhow::*;
use getopts::Options;
use log::info;
use simplelog::{LevelFilter, SimpleLogger, TermLogger, TerminalMode};
use std::path::Path;
use std::fs;
use std::path::PathBuf;
mod config;
mod db;
@ -52,15 +51,33 @@ fn daemonize(options: &getopts::Matches) -> Result<()> {
if options.opt_present("f") {
return Ok(());
}
let mut log_file = utils::get_data_root()?;
log_file.push("polaris.log");
let pid = match daemonize_redirect(Some(&log_file), Some(&log_file), ChdirMode::NoChdir) {
let log_path = options
.opt_str("log")
.map(PathBuf::from)
.unwrap_or_else(|| {
let mut path = PathBuf::from(option_env!("POLARIS_LOG_DIR").unwrap_or("."));
path.push("polaris.log");
path
});
fs::create_dir_all(&log_path.parent().unwrap())?;
let pid = match daemonize_redirect(Some(&log_path), Some(&log_path), ChdirMode::NoChdir) {
Ok(p) => p,
Err(e) => bail!("Daemonize error: {:#?}", e),
};
let mut pid_path = utils::get_data_root()?;
pid_path.push("polaris.pid");
let mut file = File::create(pid_path)?;
let pid_path = options
.opt_str("pid")
.map(PathBuf::from)
.unwrap_or_else(|| {
let mut path = PathBuf::from(option_env!("POLARIS_PID_DIR").unwrap_or("."));
path.push("polaris.pid");
path
});
fs::create_dir_all(&pid_path.parent().unwrap())?;
let mut file = fs::File::create(pid_path)?;
file.write_all(pid.to_string().as_bytes())?;
Ok(())
}
@ -113,8 +130,16 @@ fn main() -> Result<()> {
options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
options.optopt("s", "swagger", "set the path to swagger files", "DIRECTORY");
options.optopt(
"l",
"log",
"",
"cache",
"set the directory to use as cache",
"DIRECTORY",
);
options.optopt("", "log", "set the path to the log file", "FILE");
options.optopt("", "pid", "set the path to the pid file", "FILE");
options.optopt(
"",
"log-level",
"set the log level to a value between 0 (off) and 3 (debug)",
"LEVEL",
);
@ -137,7 +162,7 @@ fn main() -> Result<()> {
return Ok(());
}
let log_level = match matches.opt_str("l").as_ref().map(String::as_ref) {
let log_level = match matches.opt_str("log-level").as_ref().map(String::as_ref) {
Some("0") => LevelFilter::Off,
Some("1") => LevelFilter::Error,
Some("2") => LevelFilter::Info,
@ -151,60 +176,73 @@ fn main() -> Result<()> {
daemonize(&matches)?;
// Init DB
info!("Starting up database");
let db_path = matches.opt_str("d");
let mut default_db_path = utils::get_data_root()?;
default_db_path.push("db.sqlite");
let db_path = db_path
.map(|n| Path::new(n.as_str()).to_path_buf())
.unwrap_or(default_db_path);
let db_path = matches.opt_str("d").map(PathBuf::from).unwrap_or_else(|| {
let mut path = PathBuf::from(option_env!("POLARIS_DB_DIR").unwrap_or("."));
path.push("db.sqlite");
path
});
fs::create_dir_all(&db_path.parent().unwrap())?;
info!("Database file path is {}", db_path.display());
let db = db::DB::new(&db_path)?;
// Parse config
info!("Parsing configuration");
let config_file_name = matches.opt_str("c");
let config_file_path = config_file_name.map(|p| Path::new(p.as_str()).to_path_buf());
if let Some(path) = config_file_path {
let config = config::parse_toml_file(&path)?;
info!("Applying configuration");
if let Some(config_path) = matches.opt_str("c").map(PathBuf::from) {
let config = config::parse_toml_file(&config_path)?;
info!("Applying configuration from {}", config_path.display());
config::amend(&db, &config)?;
}
let auth_secret = config::get_auth_secret(&db)?;
// Init index
info!("Initializing index");
let index = index::builder(db.clone()).periodic_updates(true).build();
// API mount target
let api_url = "/api".to_owned();
info!("Mounting API on {}", api_url);
// Web client mount target
let web_dir_name = matches.opt_str("w");
let mut default_web_dir = utils::get_data_root()?;
default_web_dir.push("web");
let web_dir_path = web_dir_name
.map(|n| Path::new(n.as_str()).to_path_buf())
.unwrap_or(default_web_dir);
// Locate web client files
let web_dir_path = match matches
.opt_str("w")
.or(option_env!("POLARIS_WEB_DIR").map(String::from))
{
Some(s) => PathBuf::from(s),
None => [".", "web"].iter().collect(),
};
fs::create_dir_all(&web_dir_path)?;
info!("Static files location is {}", web_dir_path.display());
let web_url = "/".to_owned();
info!("Mounting web client files on {}", web_url);
// Swagger files mount target
let swagger_dir_name = matches.opt_str("s");
let mut default_swagger_dir = utils::get_data_root()?;
default_swagger_dir.push("swagger");
let swagger_dir_path = swagger_dir_name
.map(|n| Path::new(n.as_str()).to_path_buf())
.unwrap_or(default_swagger_dir);
// Locate swagger files
let swagger_dir_path = match matches
.opt_str("s")
.or(option_env!("POLARIS_SWAGGER_DIR").map(String::from))
{
Some(s) => PathBuf::from(s),
None => [".", "docs", "swagger"].iter().collect(),
};
fs::create_dir_all(&swagger_dir_path)?;
info!("Swagger files location is {}", swagger_dir_path.display());
// Initialize thumbnails manager
let mut thumbnails_path = PathBuf::from(
matches
.opt_str("cache")
.or(option_env!("POLARIS_CACHE_DIR").map(String::from))
.unwrap_or(".".to_owned()),
);
thumbnails_path.push("thumbnails");
fs::create_dir_all(&thumbnails_path)?;
info!("Thumbnails location is {}", thumbnails_path.display());
let thumbnails_manager = thumbnails::ThumbnailsManager::new(&thumbnails_path);
// Endpoints
let api_url = "/api".to_owned();
let swagger_url = "/swagger".to_owned();
let web_url = "/".to_owned();
info!("Mounting API on {}", api_url);
info!("Mounting web client files on {}", web_url);
info!("Mounting swagger files on {}", swagger_url);
// Thumbnails manager
let mut thumbnails_path = utils::get_data_root()?;
thumbnails_path.push("thumbnails");
let thumbnails_manager = thumbnails::ThumbnailsManager::new(thumbnails_path.as_path());
// Init index
let index = index::builder(db.clone()).periodic_updates(true).build();
// Start DDNS updates
let db_ddns = db.clone();
std::thread::spawn(move || {
ddns::run(&db_ddns);
});
// Start server
info!("Starting up server");
@ -229,12 +267,6 @@ fn main() -> Result<()> {
);
});
// Start DDNS updates
let db_ddns = db.clone();
std::thread::spawn(move || {
ddns::run(&db_ddns);
});
// Send readiness notification
notify_ready();

View file

@ -1,7 +1,4 @@
use anyhow::*;
use app_dirs::{app_root, AppDataType, AppInfo};
use std::fs;
use std::path::{Path, PathBuf};
use std::path::Path;
#[macro_export]
macro_rules! match_ignore_case {
@ -15,26 +12,6 @@ macro_rules! match_ignore_case {
}
pub use crate::match_ignore_case;
#[cfg(target_family = "windows")]
const APP_INFO: AppInfo = AppInfo {
name: "Polaris",
author: "Permafrost",
};
#[cfg(not(target_family = "windows"))]
const APP_INFO: AppInfo = AppInfo {
name: "polaris",
author: "permafrost",
};
pub fn get_data_root() -> Result<PathBuf> {
if let Ok(root) = app_root(AppDataType::UserData, &APP_INFO) {
fs::create_dir_all(&root)?;
return Ok(root);
}
bail!("Could not retrieve data directory root");
}
#[derive(Debug, PartialEq)]
pub enum AudioFormat {
APE,