@@ -108,13 +108,33 @@ func (h *HandlerSystemd) DisplayStatus(profileName string) error {
108108
109109// CreateJob is creating the systemd unit and activating it
110110func (h * HandlerSystemd ) CreateJob (job * Config , schedules []* calendar.Event , permission Permission ) error {
111- unitType , user := permissionToSystemd (user .Current (), permission )
111+ u := user .Current ()
112+ unitType , user := permissionToSystemd (u , permission )
112113
113114 if unitType == systemd .UserUnit && job .AfterNetworkOnline {
114115 return fmt .Errorf ("after-network-online is not available for \" user_logged_on\" permission schedules" )
115116 }
116117
117- err := systemd .Generate (systemd.Config {
118+ // check the user hasn't changed the permission, which could duplicate the unit (system & user)
119+ otherUnitType := systemd .SystemUnit
120+ if unitType == systemd .SystemUnit {
121+ otherUnitType = systemd .UserUnit
122+ }
123+ if cfgs , _ := getConfigs (job .ProfileName , otherUnitType ); len (cfgs ) > 0 { // ignore errors here
124+ for _ , cfg := range cfgs {
125+ if cfg .CommandName == job .CommandName && cfg .ProfileName == job .ProfileName {
126+ // we'd better remove this schedule first
127+ clog .Infof ("removing existing unit with different permission" )
128+ err := h .RemoveJob (& cfg , PermissionFromConfig (cfg .Permission ))
129+ if err != nil {
130+ return fmt .Errorf ("cannot remove existing unit before scheduling with different permission. You might want to retry using sudo." )
131+ }
132+ }
133+ }
134+ }
135+
136+ unit := systemd .NewUnit (u )
137+ err := unit .Generate (systemd.Config {
118138 CommandLine : job .Command + " --no-prio " + job .Arguments .String (),
119139 Environment : job .Environment ,
120140 WorkingDirectory : job .WorkingDirectory ,
@@ -169,7 +189,9 @@ func (h *HandlerSystemd) CreateJob(job *Config, schedules []*calendar.Event, per
169189// RemoveJob is disabling the systemd unit and deleting the timer and service files
170190func (h * HandlerSystemd ) RemoveJob (job * Config , permission Permission ) error {
171191 var err error
172- unitType , _ := permissionToSystemd (user .Current (), permission )
192+ unit := systemd .NewUnit (user .Current ())
193+ u := user .Current ()
194+ unitType , _ := permissionToSystemd (u , permission )
173195 serviceFile := systemd .GetServiceFile (job .ProfileName , job .CommandName )
174196 unitLoaded , err := unitLoaded (serviceFile , unitType )
175197 if err != nil {
@@ -195,7 +217,7 @@ func (h *HandlerSystemd) RemoveJob(job *Config, permission Permission) error {
195217
196218 systemdPath := systemd .GetSystemDir ()
197219 if unitType == systemd .UserUnit {
198- systemdPath , err = systemd .GetUserDir ()
220+ systemdPath , err = unit .GetUserDir ()
199221 if err != nil {
200222 return nil
201223 }
@@ -241,7 +263,12 @@ func (h *HandlerSystemd) DisplayJobStatus(job *Config) error {
241263 if ! unitLoaded {
242264 return ErrScheduledJobNotFound
243265 }
244- _ = runJournalCtlCommand (timerName , systemdType ) // ignore errors on journalctl
266+ if systemdType == systemd .UserUnit && user .Current ().IsRoot () {
267+ // journalctl doesn't accept the parameter "-M user@" (yet?)
268+ clog .Warning ("cannot load the journal from a user service as root" )
269+ } else {
270+ _ = runJournalCtlCommand (timerName , systemdType ) // ignore errors on journalctl
271+ }
245272 return runSystemctlCommand (timerName , systemctlStatus , systemdType , false )
246273}
247274
@@ -294,7 +321,7 @@ func (h *HandlerSystemd) CheckPermission(user user.User, p Permission) bool {
294321 return true
295322
296323 default :
297- if user .SudoRoot || user . Uid == 0 {
324+ if user .IsRoot () {
298325 return true
299326 }
300327 // last case is system (or undefined) + no sudo
@@ -476,7 +503,7 @@ func getConfigs(profileName string, unitType systemd.UnitType) ([]Config, error)
476503 if unit .Load == unitNotFound {
477504 continue
478505 }
479- cfg , err := systemd .Read (unit .Unit , unitType )
506+ cfg , err := systemd .NewUnit ( user . Current ()). Read (unit .Unit , unitType )
480507 if err != nil {
481508 clog .Errorf ("cannot read information from unit %q: %s" , unit .Unit , err )
482509 continue
0 commit comments