mirror of
https://github.com/house-of-vanity/mus-fuse.git
synced 2025-07-06 21:24:09 +00:00
Major usability improvements. Add config, DEB make, systemd unit, arg and flags parser.
This commit is contained in:
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
@ -13,10 +13,12 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Pre-build
|
- name: Pre-build
|
||||||
run: sudo apt install -y libfuse-dev pkg-config
|
run: sudo apt install -y libfuse-dev pkg-config && cargo install cargo-deb
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Build
|
- name: Build binary
|
||||||
run: cargo build --verbose --release
|
run: cargo build --verbose --release
|
||||||
|
- name: Build deb
|
||||||
|
run: cargo deb
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
@ -27,13 +29,23 @@ jobs:
|
|||||||
release_name: Release ${{ github.ref }}
|
release_name: Release ${{ github.ref }}
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
- name: Upload Release Asset
|
- name: Upload Release Bin
|
||||||
id: upload-release-asset
|
id: upload-release-asset-bin
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
||||||
asset_path: ./target/release/mus-fuse
|
asset_path: ./target/release/mus-fuse
|
||||||
asset_name: mus-fuse
|
asset_name: mus-fuse-${{ github.ref }}
|
||||||
|
asset_content_type: application/x-pie-executable
|
||||||
|
- name: Upload Release Deb
|
||||||
|
id: upload-release-asset-deb
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
||||||
|
asset_path: ./target/debian/mus-fuse_${{ github.ref }}_amd64.deb
|
||||||
|
asset_name: mus-fuse_${{ github.ref }}_amd64.deb
|
||||||
asset_content_type: application/x-pie-executable
|
asset_content_type: application/x-pie-executable
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
/target
|
/target
|
||||||
|
mus-fuse.yml
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
/mnt
|
/mnt
|
||||||
.vscode/
|
.vscode/
|
||||||
|
43
Cargo.toml
43
Cargo.toml
@ -1,8 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mus-fuse"
|
name = "mus-fuse"
|
||||||
version = "0.6.0"
|
version = "0.7.1"
|
||||||
authors = ["AB <ultradesu@hexor.ru>"]
|
authors = ["AB <ultradesu@hexor.ru>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
license = "WTFPL"
|
||||||
|
readme = "README.md"
|
||||||
|
description = """\
|
||||||
|
Written safely in Rust, FUSE FS with your own private music library \
|
||||||
|
hosted on your server securely."""
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -11,13 +16,31 @@ tokio = { version = "0.2", features = ["full"] }
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
clap = {version = "2.33", features = ["yaml"]}
|
clap = {version = "2.33", features = ["yaml"]}
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
percent-encoding = "2.1.0"
|
percent-encoding = "2.1"
|
||||||
fuse = "0.3.1"
|
fuse = "0.3"
|
||||||
time = "0.1.42"
|
time = "0.1"
|
||||||
libc = "0.2.69"
|
libc = "0.2"
|
||||||
chrono = "0.4.11"
|
chrono = "0.4"
|
||||||
env_logger = "0.7.1"
|
env_logger = "0.7"
|
||||||
log = { version = "^0.4.5", features = ["std"] }
|
log = { version = "^0.4.5", features = ["std"] }
|
||||||
size_format = "1.0.2"
|
size_format = "1.0"
|
||||||
base64 = "0.12.0"
|
base64 = "0.12"
|
||||||
ctrlc = "3.1.4"
|
ctrlc = "3.1"
|
||||||
|
config = "0.9"
|
||||||
|
|
||||||
|
[package.metadata.deb]
|
||||||
|
maintainer = "AB <ultradesu@hexor.ru>"
|
||||||
|
license-file = ["LICENSE", "0"]
|
||||||
|
depends = "$auto, systemd, openssl, fuse"
|
||||||
|
extended-description = """\
|
||||||
|
Written safely in Rust, FUSE FS with your own private music library \
|
||||||
|
hosted on your server securely."""
|
||||||
|
section = "utilities"
|
||||||
|
priority = "optional"
|
||||||
|
maintainer-scripts = "assets/"
|
||||||
|
conf-files = ["etc/mus-fuse.yml"]
|
||||||
|
assets = [
|
||||||
|
["assets/mus-fuse.service", "/usr/lib/systemd/system/mus-fuse.service", "644"],
|
||||||
|
["target/release/mus-fuse", "usr/bin/", "755"],
|
||||||
|
["assets/conf.yml", "etc/mus-fuse.yml", "644"],
|
||||||
|
]
|
||||||
|
12
assets/conf.yml
Normal file
12
assets/conf.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
server: https://mus.test.com
|
||||||
|
mountpoint: /srv/mus-fuse
|
||||||
|
http_user: username
|
||||||
|
http_pass: passwd1337
|
||||||
|
|
||||||
|
# How many KiB of file beginnings download and store in RAM.
|
||||||
|
# It's speeding up any metadata operations and media library scanning.
|
||||||
|
cache_head: 768
|
||||||
|
|
||||||
|
# How many count of `cache_head` store.
|
||||||
|
cache_max_count: 10
|
@ -3,11 +3,10 @@ Description=Mount mus-fuse
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
|
User=mus-fuse
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
Restart=always
|
Restart=always
|
||||||
Environment=HTTP_USER=<USER>
|
ExecStart=/usr/bin/mus-fuse --config /etc/mus-fuse.yml
|
||||||
Environment=HTTP_PASS=<PASS>
|
|
||||||
ExecStart=/usr/local/bin/mus-fuse --mountpoint <PATH> --server <ADDRESS>
|
|
||||||
KillSignal=SIGINT
|
KillSignal=SIGINT
|
||||||
|
|
||||||
[Install]
|
[Install]
|
3
assets/postinst
Executable file
3
assets/postinst
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
10
assets/preinst
Executable file
10
assets/preinst
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if systemctl | grep -Fq 'mus-fuse'; then
|
||||||
|
sudo systemctl stop mus-fuse.service
|
||||||
|
fi
|
||||||
|
|
||||||
|
adduser --quiet --system --group --no-create-home --home /run/mus-fuse mus-fuse
|
||||||
|
mkdir -p /srv/mus-fuse
|
||||||
|
chown mus-fuse:mus-fuse /srv/mus-fuse
|
||||||
|
|
196
src/main.rs
196
src/main.rs
@ -6,6 +6,7 @@ extern crate time;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
|
extern crate config;
|
||||||
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
@ -29,9 +30,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use time::Timespec;
|
use time::Timespec;
|
||||||
|
|
||||||
const CACHE_HEAD: i64 = 768 * 1024; // bytes from beginning of each file cached
|
static mut HTTP_AUTH: String = String::new(); // Basic Auth string.
|
||||||
const MAX_CACHE_SIZE: i64 = 10; // Count of files cached
|
|
||||||
static mut HTTP_AUTH: String = String::new();
|
|
||||||
|
|
||||||
struct Metrics {
|
struct Metrics {
|
||||||
http_requests: u64,
|
http_requests: u64,
|
||||||
@ -126,11 +125,18 @@ struct JsonFilesystem {
|
|||||||
buffer_head_data: HashMap<u64, Vec<u8>>,
|
buffer_head_data: HashMap<u64, Vec<u8>>,
|
||||||
buffer_length: BTreeMap<String, i64>,
|
buffer_length: BTreeMap<String, i64>,
|
||||||
metrics_inode: u64,
|
metrics_inode: u64,
|
||||||
|
cache_head: u64,
|
||||||
|
cache_max_count: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_family = "unix")]
|
#[cfg(target_family = "unix")]
|
||||||
impl JsonFilesystem {
|
impl JsonFilesystem {
|
||||||
fn new(tree: &Vec<Track>, server: String) -> JsonFilesystem {
|
fn new(
|
||||||
|
tree: &Vec<Track>,
|
||||||
|
server: String,
|
||||||
|
cache_max_count: u64,
|
||||||
|
cache_head: u64,
|
||||||
|
) -> JsonFilesystem {
|
||||||
let mut attrs = BTreeMap::new();
|
let mut attrs = BTreeMap::new();
|
||||||
let mut inodes = BTreeMap::new();
|
let mut inodes = BTreeMap::new();
|
||||||
let ts = time::now().to_timespec();
|
let ts = time::now().to_timespec();
|
||||||
@ -215,6 +221,8 @@ impl JsonFilesystem {
|
|||||||
buffer_head_index: HashSet::new(),
|
buffer_head_index: HashSet::new(),
|
||||||
buffer_length: BTreeMap::new(),
|
buffer_length: BTreeMap::new(),
|
||||||
metrics_inode: metrics_inode,
|
metrics_inode: metrics_inode,
|
||||||
|
cache_head: cache_head,
|
||||||
|
cache_max_count: cache_max_count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +278,7 @@ impl Filesystem for JsonFilesystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cleaning cache
|
// cleaning cache
|
||||||
if self.buffer_head_index.len() > MAX_CACHE_SIZE as usize {
|
if self.buffer_head_index.len() > self.cache_max_count as usize {
|
||||||
let mut iter = self.buffer_head_index.iter().filter(|&x| *x != ino);
|
let mut iter = self.buffer_head_index.iter().filter(|&x| *x != ino);
|
||||||
let old_entry = iter.next().unwrap();
|
let old_entry = iter.next().unwrap();
|
||||||
self.buffer_head_data.remove(old_entry);
|
self.buffer_head_data.remove(old_entry);
|
||||||
@ -351,7 +359,7 @@ impl Filesystem for JsonFilesystem {
|
|||||||
let range = format!("bytes={}-{}", offset, end_of_chunk - 1);
|
let range = format!("bytes={}-{}", offset, end_of_chunk - 1);
|
||||||
|
|
||||||
// if it's beginning of file...
|
// if it's beginning of file...
|
||||||
if end_of_chunk < CACHE_HEAD {
|
if end_of_chunk < self.cache_head as i64 {
|
||||||
// looking for CACHE_HEAD bytes file beginning in cache
|
// looking for CACHE_HEAD bytes file beginning in cache
|
||||||
if self.buffer_head_data.contains_key(&ino) {
|
if self.buffer_head_data.contains_key(&ino) {
|
||||||
// Cache found
|
// Cache found
|
||||||
@ -378,10 +386,10 @@ impl Filesystem for JsonFilesystem {
|
|||||||
"Range",
|
"Range",
|
||||||
format!(
|
format!(
|
||||||
"bytes=0-{}",
|
"bytes=0-{}",
|
||||||
if CACHE_HEAD > content_length {
|
if self.cache_head as i64 > content_length {
|
||||||
content_length - 1
|
content_length - 1
|
||||||
} else {
|
} else {
|
||||||
CACHE_HEAD - 1
|
self.cache_head as i64 - 1
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -485,7 +493,7 @@ impl Filesystem for JsonFilesystem {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::from_env(Env::default().default_filter_or("info")).init();
|
env_logger::from_env(Env::default().default_filter_or("info")).init();
|
||||||
info!("Logger initialized. Set RUST_LOG=[debug,error,info,warn,trace] Default: info");
|
// Parse opts and args
|
||||||
let cli_args = App::new("mus-fuse")
|
let cli_args = App::new("mus-fuse")
|
||||||
.version(env!("CARGO_PKG_VERSION"))
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
.author(env!("CARGO_PKG_AUTHORS"))
|
.author(env!("CARGO_PKG_AUTHORS"))
|
||||||
@ -494,58 +502,131 @@ fn main() {
|
|||||||
Arg::with_name("server")
|
Arg::with_name("server")
|
||||||
.short("s")
|
.short("s")
|
||||||
.long("server")
|
.long("server")
|
||||||
.value_name("SERVER")
|
.value_name("ADDRESS")
|
||||||
.help("Sets a server hosting your library")
|
.help("Sets a server hosting your library with schema. (https or http)")
|
||||||
.required(true)
|
.required(false)
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("mountpoint")
|
Arg::with_name("mountpoint")
|
||||||
.short("m")
|
.short("m")
|
||||||
.long("mountpoint")
|
.long("mountpoint")
|
||||||
.value_name("MOUNT POINT")
|
.value_name("PATH")
|
||||||
.help("Mount point for library.")
|
.help("Mount point for library")
|
||||||
.required(true)
|
.required(false)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("conf")
|
||||||
|
.short("c")
|
||||||
|
.long("config")
|
||||||
|
.value_name("PATH")
|
||||||
|
.help("Config file to use")
|
||||||
|
.default_value("/etc/mus-fuse.yaml")
|
||||||
|
.required(false)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("cache_max_count")
|
||||||
|
.long("cache-max")
|
||||||
|
.value_name("COUNT")
|
||||||
|
.help("How many files store in cache. [default: 10]")
|
||||||
|
.required(false)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("cache_head")
|
||||||
|
.long("cache-head")
|
||||||
|
.value_name("KiB")
|
||||||
|
.help("How many KiB cache in file beginning for speeding up metadata requests. [default: 768]")
|
||||||
|
.required(false)
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let server = cli_args.value_of("server").unwrap().to_string();
|
info!("Logger initialized. Set RUST_LOG=[debug,error,info,warn,trace] Default: info");
|
||||||
let mountpoint = cli_args.value_of("mountpoint").unwrap().to_string();
|
info!("Mus-Fuse {}", env!("CARGO_PKG_VERSION"));
|
||||||
|
|
||||||
|
// Read config file and env vars
|
||||||
|
let conf = cli_args.value_of("conf").unwrap();
|
||||||
|
let mut settings = config::Config::default();
|
||||||
|
settings = match settings.merge(config::File::with_name(conf)) {
|
||||||
|
Ok(conf_content) => {
|
||||||
|
info!("Using config file {}", conf);
|
||||||
|
conf_content.to_owned()
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Can't read config file {}", e);
|
||||||
|
config::Config::default()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
settings = match settings.merge(config::Environment::with_prefix("MUS")) {
|
||||||
|
Ok(conf) => conf.to_owned(),
|
||||||
|
Err(_) => config::Config::default(),
|
||||||
|
};
|
||||||
|
let http_user = match settings.get_str("http_user") {
|
||||||
|
Ok(u) => u,
|
||||||
|
Err(_) => {
|
||||||
|
info!("User for basic auth is not defined.");
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let http_pass = match settings.get_str("http_pass") {
|
||||||
|
Ok(u) => u,
|
||||||
|
Err(_) => {
|
||||||
|
info!("User for basic auth is not defined.");
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let server = match settings.get_str("server") {
|
||||||
|
Ok(server_cfg) => match cli_args.value_of("server") {
|
||||||
|
Some(server_opt) => server_opt.to_string(),
|
||||||
|
None => server_cfg,
|
||||||
|
},
|
||||||
|
Err(_) => match cli_args.value_of("server") {
|
||||||
|
Some(server_opt) => server_opt.to_string(),
|
||||||
|
None => {
|
||||||
|
error!("Server is not set in config nor via run options.");
|
||||||
|
process::exit(0x0001)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let mountpoint = match settings.get_str("mountpoint") {
|
||||||
|
Ok(mountpoint_cfg) => match cli_args.value_of("mountpoint") {
|
||||||
|
Some(mountpoint_opt) => mountpoint_opt.to_string(),
|
||||||
|
None => mountpoint_cfg,
|
||||||
|
},
|
||||||
|
Err(_) => match cli_args.value_of("mountpoint") {
|
||||||
|
Some(mountpoint_opt) => mountpoint_opt.to_string(),
|
||||||
|
None => {
|
||||||
|
error!("Mount point is not set in config nor via run options.");
|
||||||
|
process::exit(0x0001)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let cache_head = match settings.get_str("cache_head") {
|
||||||
|
Ok(cache_head_cfg) => match cli_args.value_of("cache_head") {
|
||||||
|
Some(cache_head_opt) => 1024 * cache_head_opt.parse::<u64>().unwrap(),
|
||||||
|
None => 1024 * cache_head_cfg.parse::<u64>().unwrap(),
|
||||||
|
},
|
||||||
|
Err(_) => match cli_args.value_of("cache_head") {
|
||||||
|
Some(cache_head_opt) => 1024 * cache_head_opt.parse::<u64>().unwrap(),
|
||||||
|
None => 768 * 1024,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let cache_max_count = match settings.get_str("cache_max_count") {
|
||||||
|
Ok(cache_max_count_cfg) => match cli_args.value_of("cache_max_count") {
|
||||||
|
Some(cache_max_count_opt) => cache_max_count_opt.parse::<u64>().unwrap(),
|
||||||
|
None => cache_max_count_cfg.parse::<u64>().unwrap(),
|
||||||
|
},
|
||||||
|
Err(_) => match cli_args.value_of("cache_max_count") {
|
||||||
|
Some(cache_max_count_opt) => cache_max_count_opt.parse::<u64>().unwrap(),
|
||||||
|
None => 10,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
METRICS.server_addr = server.clone();
|
METRICS.server_addr = server.clone();
|
||||||
}
|
|
||||||
let http_user_var = "HTTP_USER";
|
|
||||||
let http_pass_var = "HTTP_PASS";
|
|
||||||
|
|
||||||
let http_user = match env::var_os(http_user_var) {
|
|
||||||
Some(val) => {
|
|
||||||
info!(
|
|
||||||
"Variable {} is set. Will be used for http auth as user.",
|
|
||||||
http_user_var
|
|
||||||
);
|
|
||||||
val.to_str().unwrap().to_string()
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
info!("{} is not defined in the environment.", http_user_var);
|
|
||||||
"".to_string()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let http_pass = match env::var_os(http_pass_var) {
|
|
||||||
Some(val) => {
|
|
||||||
info!(
|
|
||||||
"Variable {} is set. Will be used for http auth as password.",
|
|
||||||
http_pass_var
|
|
||||||
);
|
|
||||||
val.to_str().unwrap().to_string()
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
info!("{} is not defined in the environment.", http_pass_var);
|
|
||||||
"".to_string()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
unsafe {
|
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
buf.push_str(&http_user);
|
buf.push_str(&http_user);
|
||||||
buf.push_str(":");
|
buf.push_str(":");
|
||||||
@ -555,16 +636,15 @@ fn main() {
|
|||||||
let lib = match get_tracks(&server) {
|
let lib = match get_tracks(&server) {
|
||||||
Ok(library) => library,
|
Ok(library) => library,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Can't fetch library from remote server. Probably server not running or auth failed.");
|
error!("Can't fetch library from remote server. Probably server is not running or auth failed. {}", err);
|
||||||
error!(
|
error!(
|
||||||
"Provide Basic Auth credentials by setting envs {} and {}",
|
"Provide Basic Auth credentials by setting envs MUS_HTTP_USER and MUS_HTTP_PASS or providing config.",
|
||||||
http_user_var, http_pass_var
|
|
||||||
);
|
);
|
||||||
panic!("Error: {}", err);
|
process::exit(0x0001)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
info!("Remote library host: {}", &server);
|
info!("Remote library host: {}", &server);
|
||||||
let fs = JsonFilesystem::new(&lib, server);
|
let fs = JsonFilesystem::new(&lib, server, cache_max_count, cache_head);
|
||||||
let options = [
|
let options = [
|
||||||
"-o",
|
"-o",
|
||||||
"ro",
|
"ro",
|
||||||
@ -574,17 +654,19 @@ fn main() {
|
|||||||
"sync_read",
|
"sync_read",
|
||||||
"-o",
|
"-o",
|
||||||
"auto_unmount",
|
"auto_unmount",
|
||||||
|
"-o",
|
||||||
|
"allow_other",
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|o| o.as_ref())
|
.map(|o| o.as_ref())
|
||||||
.collect::<Vec<&OsStr>>();
|
.collect::<Vec<&OsStr>>();
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Caching {}B bytes in head of files.",
|
"Caching {}B in head of files.",
|
||||||
SizeFormatterBinary::new(CACHE_HEAD as u64)
|
SizeFormatterBinary::new(cache_head as u64)
|
||||||
);
|
);
|
||||||
info!("Max cache is {} files.", MAX_CACHE_SIZE);
|
info!("Max cache is {} files.", cache_max_count);
|
||||||
info!("Mount options: {:?}", options);
|
info!("Fuse mount options: {:?}", options);
|
||||||
let _mount: fuse::BackgroundSession;
|
let _mount: fuse::BackgroundSession;
|
||||||
unsafe {
|
unsafe {
|
||||||
_mount = fuse::spawn_mount(fs, &mountpoint, &options).expect("Couldn't mount filesystem");
|
_mount = fuse::spawn_mount(fs, &mountpoint, &options).expect("Couldn't mount filesystem");
|
||||||
|
Reference in New Issue
Block a user