@@ -29,7 +29,8 @@ pub struct Systemd {
2929 service_name : String ,
3030 /// `cres.<name>.socket`
3131 socket_name : String ,
32- system_wide : bool ,
32+ /// Use the user's service directory instead of the system's, requires root if false.
33+ user_service : bool ,
3334}
3435
3536impl Systemd {
@@ -40,14 +41,17 @@ impl Systemd {
4041 name : name. to_string ( ) ,
4142 service_name : format ! ( "cres.{name}.service" ) ,
4243 socket_name : format ! ( "cres.{name}.socket" ) ,
43- system_wide : Crescent :: parse ( ) . system_wide ,
44+ user_service : Crescent :: parse ( ) . user_service ,
4445 }
4546 }
4647
47- /// Run a `systemctl` command as the user.
48- fn run_command ( & self , args : Vec < & str > ) -> Result < Output > {
48+ /// Run a `systemctl` command.
49+ fn run_command ( & self , mut args : Vec < & str > ) -> Result < Output > {
50+ if self . user_service {
51+ args. push ( "--user" ) ;
52+ }
53+
4954 Ok ( Command :: new ( "systemctl" )
50- . arg ( "--user" )
5155 . arg ( "--no-pager" )
5256 . args ( args)
5357 . output ( ) ?)
@@ -57,6 +61,10 @@ impl Systemd {
5761 let requires = format ! ( "Requires={}" , self . socket_name) ;
5862 let after = format ! ( "After=network.target {}" , self . socket_name) ;
5963 let exec_start = format ! ( "ExecStart={cmd}" ) ;
64+ let wanted_by = match self . user_service {
65+ true => "WantedBy=default.target" ,
66+ false => "WantedBy=multi-user.target" ,
67+ } ;
6068
6169 let service = [
6270 "[Unit]" ,
@@ -71,13 +79,10 @@ impl Systemd {
7179 "StandardError=journal" ,
7280 "" ,
7381 "[Install]" ,
74- "WantedBy=default.target" ,
82+ wanted_by ,
7583 "" ,
7684 ] ;
7785
78- if let Some ( parent) = path. parent ( ) {
79- fs:: create_dir_all ( parent) ?;
80- }
8186 fs:: write ( path, service. join ( "\n " ) ) ?;
8287 Ok ( ( ) )
8388 }
@@ -94,9 +99,6 @@ impl Systemd {
9499 "" ,
95100 ] ;
96101
97- if let Some ( parent) = path. parent ( ) {
98- fs:: create_dir_all ( parent) ?;
99- }
100102 fs:: write ( path, socket. join ( "\n " ) ) ?;
101103 Ok ( ( ) )
102104 }
@@ -110,15 +112,15 @@ impl InitSystem for Systemd {
110112 }
111113
112114 fn get_scripts_paths ( & self ) -> Vec < String > {
113- if self . system_wide {
115+ if self . user_service {
114116 vec ! [
115- SYSTEM_DIR . to_string( ) + & self . service_name,
116- SYSTEM_DIR . to_string( ) + & self . socket_name,
117+ USER_DIR . to_string( ) + & self . service_name,
118+ USER_DIR . to_string( ) + & self . socket_name,
117119 ]
118120 } else {
119121 vec ! [
120- USER_DIR . to_string( ) + & self . service_name,
121- USER_DIR . to_string( ) + & self . socket_name,
122+ SYSTEM_DIR . to_string( ) + & self . service_name,
123+ SYSTEM_DIR . to_string( ) + & self . socket_name,
122124 ]
123125 }
124126 }
@@ -143,8 +145,11 @@ impl InitSystem for Systemd {
143145 }
144146
145147 fn create ( & self , cmd : & str ) -> Result < ( ) > {
146- let path_str =
147- env:: var ( "HOME" ) . expect ( "Error retrieving HOME directory." ) + "/.config/systemd/user/" ;
148+ let path_str = match self . user_service {
149+ true => USER_DIR . to_string ( ) ,
150+ false => SYSTEM_DIR . to_string ( ) ,
151+ } ;
152+
148153 let path = PathBuf :: from ( path_str) ;
149154
150155 eprintln ! ( "Writing '{}' unit" , self . service_name) ;
@@ -265,12 +270,12 @@ impl InitSystem for Systemd {
265270 }
266271
267272 fn list ( & self ) -> Result < Vec < String > > {
268- let output = self . run_command ( vec ! [ "list-unit-files" ] ) ?;
273+ let output = self . run_command ( vec ! [ "list-unit-files" , "cres.*.service" ] ) ?;
269274 let out = String :: from_utf8 ( output. stdout ) ?;
270275 let output_lines = out. lines ( ) . collect :: < Vec < & str > > ( ) ;
271276 let names: Vec < String > = output_lines
272277 . iter ( )
273- . filter ( |line| line. contains ( "cres." ) && line . contains ( ".service ") )
278+ . filter ( |line| line. starts_with ( "cres." ) )
274279 . map ( |s| s. split_whitespace ( ) . next ( ) . unwrap_or ( "" ) . to_string ( ) )
275280 . collect ( ) ;
276281 Ok ( names)
0 commit comments