Browse Source

Sort out running as a user

master
Adrian Heine 8 years ago
parent
commit
38cf1d6e98
  1. 3
      Cargo.toml
  2. 16
      src/command_runner.rs
  3. 2
      src/lib.rs
  4. 6
      src/symbols/nginx/server.rs
  5. 20
      src/symbols/systemd/node_js_user_service.rs

3
Cargo.toml

@ -3,5 +3,8 @@ name = "schematics"
version = "0.1.0" version = "0.1.0"
authors = ["Adrian Heine <mail@adrianheine.de>"] authors = ["Adrian Heine <mail@adrianheine.de>"]
[dependencies]
users = "0.5.0"
[dev-dependencies] [dev-dependencies]
tempdir = "0.3" tempdir = "0.3"

16
src/command_runner.rs

@ -34,11 +34,21 @@ impl<'a, C> UserCommandRunner<'a, C> where C: 'a + CommandRunner {
} }
} }
use std::os::unix::process::CommandExt;
use std::env;
use users::get_user_by_name;
impl<'a, C> CommandRunner for UserCommandRunner<'a, C> where C: 'a + CommandRunner { impl<'a, C> CommandRunner for UserCommandRunner<'a, C> where C: 'a + CommandRunner {
fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult<Output> { fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult<Output> {
let mut new_args = vec![self.user_name, "-s", "/usr/bin/env", "--", program];
new_args.extend_from_slice(args);
self.command_runner.run_with_args("su", &new_args)
let uid = get_user_by_name(self.user_name).unwrap().uid();
let old_home = env::var("HOME");
env::set_var("HOME", format!("/home/{}", self.user_name));
let old_dbus = env::var("DBUS_SESSION_BUS_ADDRESS");
env::set_var("DBUS_SESSION_BUS_ADDRESS", format!("unix:path=/run/user/{}/bus", uid));
let res = Command::new(program).uid(uid).gid(uid).args(args).output();
if let Ok(dbus) = old_dbus { env::set_var("DBUS_SESSION_BUS_ADDRESS", dbus); }
if let Ok(home) = old_home { env::set_var("HOME", home); }
res
} }
} }

2
src/lib.rs

@ -20,6 +20,8 @@ missing_debug_implementations
#![allow(box_pointers)] #![allow(box_pointers)]
extern crate users;
pub mod command_runner; pub mod command_runner;
pub mod loggers; pub mod loggers;
pub mod symbols; pub mod symbols;

6
src/symbols/nginx/server.rs

@ -49,7 +49,7 @@ pub struct NginxServer<'a, C> where C: Deref<Target=str> {
use std::borrow::Cow; use std::borrow::Cow;
impl<'a> NginxServer<'a, String> { impl<'a> NginxServer<'a, String> {
pub fn new(home: &'a str, domain: &'a str, static_path: &'a str, redir_domains: &[&'a str], command_runner: &'a CommandRunner) -> Self {
pub fn new(socket_path: &'a str, domain: &'a str, static_path: &'a str, redir_domains: &[&'a str], command_runner: &'a CommandRunner) -> Self {
let file_path: Cow<str> = Cow::from(String::from("/etc/nginx/sites-enabled/") + domain); let file_path: Cow<str> = Cow::from(String::from("/etc/nginx/sites-enabled/") + domain);
let redir_content = redir_domains.iter().map(|redir_domain| format!("server {{ let redir_content = redir_domains.iter().map(|redir_domain| format!("server {{
@ -75,10 +75,10 @@ impl<'a> NginxServer<'a, String> {
location @proxy {{ location @proxy {{
include fastcgi_params; include fastcgi_params;
proxy_pass http://unix:{}/var/service.socket:;
proxy_pass http://unix:{}:;
proxy_redirect off; proxy_redirect off;
}} }}
}}", domain, static_path, home);
}}", domain, static_path, socket_path);
NginxServer { NginxServer {
command_runner: command_runner, command_runner: command_runner,
file: FileSymbol::new(file_path, content) file: FileSymbol::new(file_path, content)

20
src/symbols/systemd/node_js_user_service.rs

@ -56,6 +56,7 @@ impl<E: Error> fmt::Display for NodeJsSystemdUserServiceError<E> {
pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display, C: Deref<Target=str> { pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display, C: Deref<Target=str> {
name: &'a str, name: &'a str,
home: &'a str, home: &'a str,
uid: u32,
path: P, path: P,
command_runner: &'a CommandRunner, command_runner: &'a CommandRunner,
file: FileSymbol<C, Cow<'a, str>> file: FileSymbol<C, Cow<'a, str>>
@ -64,20 +65,24 @@ pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display
use std::borrow::Cow; use std::borrow::Cow;
impl<'a> NodeJsSystemdUserService<'a, Cow<'a, str>, String> { impl<'a> NodeJsSystemdUserService<'a, Cow<'a, str>, String> {
pub fn new(home: &'a str, name: &'a str, path: &'a str, command_runner: &'a CommandRunner) -> Self {
pub fn new(home: &'a str, uid: u32, name: &'a str, path: &'a str, command_runner: &'a CommandRunner) -> Self {
let file_path: Cow<str> = Cow::from(String::from(home.trim_right()) + "/.config/systemd/user/" + name + ".service"); let file_path: Cow<str> = Cow::from(String::from(home.trim_right()) + "/.config/systemd/user/" + name + ".service");
let content = format!("[Service] let content = format!("[Service]
ExecStart=/usr/bin/nodejs {}
ExecStartPre=rm /var/tmp/{1}-{2}.socket
ExecStart=/usr/bin/nodejs {0}
Restart=always Restart=always
Environment=NODE_ENV=production Environment=NODE_ENV=production
Environment=PORT={}/var/service.socket
Environment=PORT=/var/tmp/{1}-{2}.socket
#RuntimeDirectory=service
#RuntimeDirectoryMode=766
[Install] [Install]
WantedBy=default.target WantedBy=default.target
", path, home);
", path, uid, name);
NodeJsSystemdUserService { NodeJsSystemdUserService {
name: name, name: name,
uid: uid,
home: home, home: home,
path: file_path.clone(), path: file_path.clone(),
command_runner: command_runner, command_runner: command_runner,
@ -121,9 +126,6 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str>
} }
fn execute(&self) -> Result<(), Box<Error>> { fn execute(&self) -> Result<(), Box<Error>> {
try!(self.command_runner.run_with_args("mkdir", &["-p", &format!("{}/var", self.home)]));
try!(self.command_runner.run_with_args("rm", &[&format!("{}/var/service.socket", self.home)]));
try!(self.command_runner.run_with_args("mkdir", &["-p", Path::new(self.path.as_ref()).parent().unwrap().to_str().unwrap()])); try!(self.command_runner.run_with_args("mkdir", &["-p", Path::new(self.path.as_ref()).parent().unwrap().to_str().unwrap()]));
// FIXME: Permissions // FIXME: Permissions
// try!(create_dir_all(Path::new(&path).parent().unwrap())); // try!(create_dir_all(Path::new(&path).parent().unwrap()));
@ -136,7 +138,7 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str>
if !(try!(self.check_if_service())) { return Err(Box::new(NodeJsSystemdUserServiceError::GenericError as NodeJsSystemdUserServiceError<io::Error>)); } if !(try!(self.check_if_service())) { return Err(Box::new(NodeJsSystemdUserServiceError::GenericError as NodeJsSystemdUserServiceError<io::Error>)); }
let file_name = format!("{}/var/service.socket", self.home);
let file_name = format!("/var/tmp/{}-{}.socket", self.uid, self.name);
// try!(self.command_runner.run_with_args("chmod", &["666", &file_name])); // try!(self.command_runner.run_with_args("chmod", &["666", &file_name]));
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
@ -148,9 +150,11 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str>
Ok(()) Ok(())
} }
/* // FIXME
fn get_prerequisites(&self) -> Vec<Box<Resource>> { fn get_prerequisites(&self) -> Vec<Box<Resource>> {
self.file.get_prerequisites() self.file.get_prerequisites()
} }
*/
} }
impl<'a, P, C> fmt::Display for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display, C: Deref<Target=str> { impl<'a, P, C> fmt::Display for NodeJsSystemdUserService<'a, P, C> where P: AsRef<str> + fmt::Display, C: Deref<Target=str> {

Loading…
Cancel
Save