Skip to content

Commit f60a070

Browse files
committed
feat: Fix the problem caused by the daemon process discarding permissions
1 parent bc6f445 commit f60a070

File tree

10 files changed

+85
-72
lines changed

10 files changed

+85
-72
lines changed

src/asset/libc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct Asset;
99
struct Asset;
1010

1111
#[cfg(target_os = "linux")]
12-
pub(crate) fn ld_env(envs: &mut std::collections::HashMap<String, String>) -> anyhow::Result<()> {
12+
pub(crate) fn ld_env(envs: &mut std::collections::HashMap<String, String>) -> Result<()> {
1313
use crate::{constant, util};
1414
use anyhow::Context;
1515
use std::ops::Not;

src/asset/thunder.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use anyhow::Context;
2+
use anyhow::Result;
13
use core::str;
24
use std::{
35
borrow::Cow,
@@ -6,8 +8,6 @@ use std::{
68
ops::Not,
79
path::{Path, PathBuf},
810
};
9-
10-
use anyhow::Context;
1111
use tar::Archive;
1212

1313
pub struct Asset {
@@ -31,7 +31,7 @@ impl Asset {
3131
})
3232
}
3333

34-
pub fn init(&self) -> anyhow::Result<()> {
34+
pub fn init(&self) -> Result<()> {
3535
match self.package {
3636
Some(ref filepath) => {
3737
// check filepath is exists
@@ -90,7 +90,7 @@ impl Asset {
9090
}
9191
}
9292

93-
fn decompressor<T: AsRef<Path>>(dir: T, archive_path: T) -> anyhow::Result<()> {
93+
fn decompressor<T: AsRef<Path>>(dir: T, archive_path: T) -> Result<()> {
9494
const PACKAGE_XZ: &str = "package.tgz";
9595
const PACKAGE_TAR: &str = "package.tar";
9696

@@ -158,7 +158,7 @@ impl Asset {
158158
Ok(())
159159
}
160160

161-
fn copy_write(mut src: impl Read, dest: &mut File) -> anyhow::Result<()> {
161+
fn copy_write(mut src: impl Read, dest: &mut File) -> Result<()> {
162162
let mut buffer = [0; 1024];
163163

164164
loop {

src/daemon.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use anyhow::Result;
12
use daemonize::Daemonize;
23
use std::{
34
fs::{File, Permissions},
@@ -22,7 +23,7 @@ pub fn check_root() {
2223
}
2324

2425
/// Get the pid of the daemon
25-
pub(crate) fn get_pid() -> Option<String> {
26+
pub fn get_pid() -> Option<String> {
2627
if let Ok(data) = std::fs::read(PID_PATH) {
2728
let binding = String::from_utf8(data).expect("pid file is not utf8");
2829
return Some(binding.trim().to_string());
@@ -31,7 +32,7 @@ pub(crate) fn get_pid() -> Option<String> {
3132
}
3233

3334
/// Start the daemon
34-
pub(super) fn start() -> anyhow::Result<()> {
35+
pub fn start() -> Result<()> {
3536
if let Some(pid) = get_pid() {
3637
println!("Thunder is already running with pid: {}", pid);
3738
return Ok(());
@@ -73,7 +74,7 @@ pub(super) fn start() -> anyhow::Result<()> {
7374
}
7475

7576
/// Stop the daemon
76-
pub(super) fn stop() -> anyhow::Result<()> {
77+
pub fn stop() -> Result<()> {
7778
use nix::sys::signal;
7879
use nix::unistd::Pid;
7980

@@ -94,7 +95,7 @@ pub(super) fn stop() -> anyhow::Result<()> {
9495
}
9596

9697
/// Show the status of the daemon
97-
pub(super) fn status() -> anyhow::Result<()> {
98+
pub fn status() -> Result<()> {
9899
match get_pid() {
99100
Some(pid) => println!("Thunder is running with pid: {}", pid),
100101
None => println!("Thunder is not running"),
@@ -103,8 +104,8 @@ pub(super) fn status() -> anyhow::Result<()> {
103104
}
104105

105106
/// Show the log of the daemon
106-
pub(super) fn log() -> anyhow::Result<()> {
107-
fn read_and_print_file(file_path: &Path, placeholder: &str) -> anyhow::Result<()> {
107+
pub fn log() -> Result<()> {
108+
fn read_and_print_file(file_path: &Path, placeholder: &str) -> Result<()> {
108109
if !file_path.exists() {
109110
return Ok(());
110111
}

src/install.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@ use std::ops::Not;
22
use std::path::Path;
33
use std::path::PathBuf;
44

5-
use anyhow::Context;
6-
use rand::Rng;
7-
85
use crate::asset::thunder::Asset;
96
use crate::constant;
107
use crate::util;
118
use crate::InstallConfig;
129
use crate::Running;
10+
use anyhow::Context;
11+
use anyhow::Result;
12+
use rand::Rng;
1313

1414
/// Install xunlei
1515
pub struct XunleiInstall(pub InstallConfig);
1616

1717
impl Running for XunleiInstall {
18-
fn run(self) -> anyhow::Result<()> {
18+
fn run(self) -> Result<()> {
1919
// If the package is already installed, skip the installation
2020
if Path::new(constant::SYNOPKG_VAR).exists() {
2121
println!("Thunder already installed");
@@ -66,13 +66,21 @@ impl Running for XunleiInstall {
6666
let target_dir = PathBuf::from(constant::SYNOPKG_PKGDEST);
6767
// /var/packages/pan-xunlei-com/target/host
6868
let host_dir = PathBuf::from(constant::SYNOPKG_HOST);
69+
// If Synology NAS is not installed, the backend service will not be started
70+
let var_path = Path::new(constant::SYNOPKG_VAR);
6971

7072
// uid and gid
7173
let uid = self.0.uid;
7274
let gid = self.0.gid;
7375

7476
util::create_dir_all(&target_dir, 0o755)?;
7577

78+
// path: /var/packages/pan-xunlei-com/target/var
79+
if !var_path.exists() {
80+
util::create_dir_all(var_path, 0o777)?;
81+
util::chown(var_path, uid, gid)?;
82+
}
83+
7684
// download xunlei binary
7785
let xunlei = Asset::new(self.0.package)?;
7886
xunlei.init()?;
@@ -175,7 +183,7 @@ impl Running for XunleiInstall {
175183
pub struct XunleiUninstall(pub Option<InstallConfig>);
176184

177185
impl Running for XunleiUninstall {
178-
fn run(self) -> anyhow::Result<()> {
186+
fn run(self) -> Result<()> {
179187
// path: /var/packages/pan-xunlei-com
180188
let path = Path::new(constant::SYNOPKG_PKGBASE);
181189
if path.exists() {

src/main.rs

+39-8
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ mod install;
99
mod serve;
1010
pub mod util;
1111

12+
use anyhow::Result;
1213
use clap::{Args, Parser, Subcommand};
1314
use std::io::{BufRead, Write};
1415
use std::net::SocketAddr;
1516
use std::path::{Path, PathBuf};
1617

1718
pub trait Running {
18-
fn run(self) -> anyhow::Result<()>;
19+
fn run(self) -> Result<()>;
1920
}
2021

2122
#[derive(Parser)]
@@ -69,7 +70,7 @@ impl InstallConfig {
6970
const PATH: &'static str = "/etc/.thunder";
7071

7172
/// Remove config file
72-
pub fn remove_file(self) -> anyhow::Result<()> {
73+
pub fn remove_file(self) -> Result<()> {
7374
let path = Path::new(Self::PATH);
7475
if path.exists() {
7576
std::fs::remove_file(&Self::PATH)?;
@@ -78,7 +79,7 @@ impl InstallConfig {
7879
}
7980

8081
/// Write to file
81-
fn write_to_file(&self) -> anyhow::Result<()> {
82+
fn write_to_file(&self) -> Result<()> {
8283
let path = Path::new(Self::PATH);
8384
if !path.exists() {
8485
let mut file = std::fs::File::create(path)?;
@@ -175,7 +176,7 @@ pub struct ServeConfig {
175176
tls_key: Option<PathBuf>,
176177
}
177178

178-
fn main() -> anyhow::Result<()> {
179+
fn main() -> Result<()> {
179180
let opt = Opt::parse();
180181

181182
match opt.commands {
@@ -187,12 +188,16 @@ fn main() -> anyhow::Result<()> {
187188
let install_config = InstallConfig::read_from_file().map_or(None, |v| Some(v));
188189
install::XunleiUninstall(install_config).run()?;
189190
}
190-
Commands::Run(config) => {
191-
serve::Serve::new(config, InstallConfig::read_from_file()?).run()?;
191+
Commands::Run(server_config) => {
192+
let install_config = InstallConfig::read_from_file()?;
193+
before_action(&install_config)?;
194+
serve::Serve::new(server_config, install_config).run()?;
192195
}
193-
Commands::Start(config) => {
196+
Commands::Start(server_config) => {
197+
let install_config = InstallConfig::read_from_file()?;
198+
before_action(&install_config)?;
194199
daemon::start()?;
195-
serve::Serve::new(config, InstallConfig::read_from_file()?).run()?;
200+
serve::Serve::new(server_config, install_config).run()?;
196201
}
197202
Commands::Stop => {
198203
daemon::stop()?;
@@ -206,3 +211,29 @@ fn main() -> anyhow::Result<()> {
206211
}
207212
Ok(())
208213
}
214+
215+
/// Running before the daemon starts, execute the following code
216+
fn before_action(install_config: &InstallConfig) -> Result<()> {
217+
#[cfg(target_os = "linux")]
218+
use nix::mount::MsFlags;
219+
220+
#[cfg(target_os = "linux")]
221+
let _ = nix::mount::umount(&install_config.mount_bind_download_path);
222+
#[cfg(target_os = "linux")]
223+
if nix::mount::mount(
224+
Some(&install_config.download_path),
225+
&install_config.mount_bind_download_path,
226+
<Option<&'static [u8]>>::None,
227+
MsFlags::MS_BIND,
228+
<Option<&'static [u8]>>::None,
229+
)
230+
.is_err()
231+
{
232+
anyhow::bail!(
233+
"Mount {} to {} failed",
234+
install_config.download_path.display(),
235+
install_config.mount_bind_download_path.display()
236+
);
237+
}
238+
Ok(())
239+
}

src/serve/auth/token.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use super::{CHECK_AUTH, EXP, TOKEN_SECRET};
2+
use anyhow::Result;
13
use jsonwebtokens::{encode, Algorithm, AlgorithmID, Verifier};
24
use std::{collections::HashMap, time::Duration};
35

4-
use super::{CHECK_AUTH, EXP, TOKEN_SECRET};
5-
66
fn get_or_init_secret() -> &'static String {
77
TOKEN_SECRET.get_or_init(|| {
88
let secret = if let Some(Some(auth_password)) = CHECK_AUTH.get() {
@@ -27,7 +27,7 @@ pub fn generate_token() -> anyhow::Result<String> {
2727
Ok(encode(&header, &claims, &alg)?)
2828
}
2929

30-
pub fn verifier(token_str: &str) -> anyhow::Result<()> {
30+
pub fn verifier(token_str: &str) -> Result<()> {
3131
let s = get_or_init_secret();
3232
let alg = Algorithm::new_hmac(AlgorithmID::HS256, s.to_owned())?;
3333
let verifier = Verifier::create().build()?;

src/serve/backend.rs

+6-34
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
#[cfg(target_os = "linux")]
2-
use nix::mount::MsFlags;
1+
use crate::serve::ConfigExt;
2+
use crate::ServeConfig;
3+
use crate::{constant, InstallConfig, Running};
4+
use anyhow::Result;
35
use nix::sys::signal;
46
use nix::unistd::Pid;
57
use signal_hook::iterator::Signals;
68
use std::os::unix::process::CommandExt;
7-
8-
use crate::serve::ConfigExt;
9-
use crate::{constant, InstallConfig, Running};
10-
use crate::{util, ServeConfig};
11-
use std::{ops::Not, path::Path, process::Stdio};
9+
use std::process::Stdio;
1210

1311
pub(super) struct BackendServer(ServeConfig, InstallConfig, tokio::sync::mpsc::Sender<()>);
1412

@@ -23,33 +21,7 @@ impl BackendServer {
2321
}
2422

2523
impl Running for BackendServer {
26-
fn run(self) -> anyhow::Result<()> {
27-
// If Synology NAS is not installed, the backend service will not be started
28-
let var_path = Path::new(constant::SYNOPKG_VAR);
29-
if var_path.exists().not() {
30-
util::create_dir_all(var_path, 0o777)?;
31-
util::chown(var_path, self.1.uid, self.1.gid)?;
32-
}
33-
34-
#[cfg(target_os = "linux")]
35-
let _ = nix::mount::umount(&self.1.mount_bind_download_path);
36-
#[cfg(target_os = "linux")]
37-
if nix::mount::mount(
38-
Some(&self.1.download_path),
39-
&self.1.mount_bind_download_path,
40-
<Option<&'static [u8]>>::None,
41-
MsFlags::MS_BIND,
42-
<Option<&'static [u8]>>::None,
43-
)
44-
.is_err()
45-
{
46-
anyhow::bail!(
47-
"Mount {} to {} failed",
48-
self.1.download_path.display(),
49-
self.1.mount_bind_download_path.display()
50-
);
51-
}
52-
24+
fn run(self) -> Result<()> {
5325
// environment variables
5426
let envs = (&self.0, &self.1).envs()?;
5527

src/serve/frontend.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::{
66
};
77
use crate::{constant, InstallConfig, Running, ServeConfig};
88
use anyhow::Context;
9+
use anyhow::Result;
910
use axum::{
1011
body::{Body, StreamBody},
1112
extract::State,
@@ -41,7 +42,7 @@ struct User {
4142
pub(super) struct FrontendServer(ServeConfig, InstallConfig, tokio::sync::mpsc::Receiver<()>);
4243

4344
impl Running for FrontendServer {
44-
fn run(self) -> anyhow::Result<()> {
45+
fn run(self) -> Result<()> {
4546
self.start_server()
4647
}
4748
}
@@ -56,7 +57,7 @@ impl FrontendServer {
5657
}
5758

5859
#[tokio::main]
59-
async fn start_server(self) -> anyhow::Result<()> {
60+
async fn start_server(self) -> Result<()> {
6061
log::info!("Starting frontend server: {}", self.0.bind);
6162

6263
// Set check auth

src/serve/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
serve::{backend::BackendServer, frontend::FrontendServer},
1111
InstallConfig, Running, ServeConfig,
1212
};
13+
use anyhow::Result;
1314
use std::collections::HashMap;
1415

1516
pub(crate) trait ConfigExt {
@@ -25,7 +26,7 @@ impl Serve {
2526
}
2627

2728
impl Running for Serve {
28-
fn run(self) -> anyhow::Result<()> {
29+
fn run(self) -> Result<()> {
2930
use std::thread::{Builder, JoinHandle};
3031

3132
let serve_config = self.0.clone();

0 commit comments

Comments
 (0)