engine: resources: Fix up some issues with cron
This really needs looking at again, since it's so old and buggy or broken.
This commit is contained in:
@@ -36,7 +36,6 @@ import (
|
|||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
"github.com/purpleidea/mgmt/engine/traits"
|
"github.com/purpleidea/mgmt/engine/traits"
|
||||||
@@ -76,10 +75,6 @@ const (
|
|||||||
// in 'man systemd-timer', and whose format is a time span as defined in
|
// in 'man systemd-timer', and whose format is a time span as defined in
|
||||||
// 'man systemd-time'.
|
// 'man systemd-time'.
|
||||||
OnUnitInactiveSec = "OnUnitInactiveSec"
|
OnUnitInactiveSec = "OnUnitInactiveSec"
|
||||||
|
|
||||||
// ctxTimeout is the delay, in seconds, before the calls to restart or stop
|
|
||||||
// the systemd unit will error due to timeout.
|
|
||||||
ctxTimeout = 30
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -104,6 +99,11 @@ type CronRes struct {
|
|||||||
// State must be 'exists' or 'absent'.
|
// State must be 'exists' or 'absent'.
|
||||||
State string `lang:"state" yaml:"state"`
|
State string `lang:"state" yaml:"state"`
|
||||||
|
|
||||||
|
// Startup specifies what should happen on startup. Values can be:
|
||||||
|
// enabled, disabled, and undefined (empty string). We default to
|
||||||
|
// enabled.
|
||||||
|
Startup string `lang:"startup" yaml:"startup"`
|
||||||
|
|
||||||
// Session, if true, creates the timer as the current user, rather than
|
// Session, if true, creates the timer as the current user, rather than
|
||||||
// root. The service it points to must also be a user unit. It defaults
|
// root. The service it points to must also be a user unit. It defaults
|
||||||
// to false.
|
// to false.
|
||||||
@@ -154,6 +154,7 @@ type CronRes struct {
|
|||||||
func (obj *CronRes) Default() engine.Res {
|
func (obj *CronRes) Default() engine.Res {
|
||||||
return &CronRes{
|
return &CronRes{
|
||||||
State: "exists",
|
State: "exists",
|
||||||
|
Startup: "enabled",
|
||||||
RemainAfterElapse: true,
|
RemainAfterElapse: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,6 +189,9 @@ func (obj *CronRes) Validate() error {
|
|||||||
if obj.State != "absent" && obj.State != "exists" {
|
if obj.State != "absent" && obj.State != "exists" {
|
||||||
return fmt.Errorf("state must be 'absent' or 'exists'")
|
return fmt.Errorf("state must be 'absent' or 'exists'")
|
||||||
}
|
}
|
||||||
|
if obj.Startup != "enabled" && obj.Startup != "disabled" && obj.Startup != "" {
|
||||||
|
return fmt.Errorf("startup must be either `enabled` or `disabled` or undefined")
|
||||||
|
}
|
||||||
|
|
||||||
// validate trigger
|
// validate trigger
|
||||||
if obj.State == "absent" && obj.Trigger == "" {
|
if obj.State == "absent" && obj.Trigger == "" {
|
||||||
@@ -264,12 +268,12 @@ func (obj *CronRes) Watch(ctx context.Context) error {
|
|||||||
args := []string{}
|
args := []string{}
|
||||||
args = append(args, "type='signal'")
|
args = append(args, "type='signal'")
|
||||||
args = append(args, "interface='org.freedesktop.systemd1.Manager'")
|
args = append(args, "interface='org.freedesktop.systemd1.Manager'")
|
||||||
args = append(args, "eavesdrop='true'")
|
//args = append(args, "eavesdrop='true'") // XXX: not allowed anymore?
|
||||||
args = append(args, fmt.Sprintf("arg2='%s.timer'", obj.Name()))
|
args = append(args, fmt.Sprintf("arg2='%s.timer'", obj.Name()))
|
||||||
|
|
||||||
// match dbus messsages
|
// match dbus messsages
|
||||||
if call := bus.BusObject().Call(engineUtil.DBusAddMatch, 0, strings.Join(args, ",")); call.Err != nil {
|
if call := bus.BusObject().Call(engineUtil.DBusAddMatch, 0, strings.Join(args, ",")); call.Err != nil {
|
||||||
return err
|
return call.Err
|
||||||
}
|
}
|
||||||
defer bus.BusObject().Call(engineUtil.DBusRemoveMatch, 0, args) // ignore the error
|
defer bus.BusObject().Call(engineUtil.DBusRemoveMatch, 0, args) // ignore the error
|
||||||
|
|
||||||
@@ -394,10 +398,6 @@ func (obj *CronRes) unitCheckApply(ctx context.Context, apply bool) (bool, error
|
|||||||
return false, errwrap.Wrapf(err, "error reloading daemon")
|
return false, errwrap.Wrapf(err, "error reloading daemon")
|
||||||
}
|
}
|
||||||
|
|
||||||
// context for stopping/restarting the unit
|
|
||||||
ctx, cancel := context.WithTimeout(ctx, ctxTimeout*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// godbus connection for stopping/restarting the unit
|
// godbus connection for stopping/restarting the unit
|
||||||
if obj.Session {
|
if obj.Session {
|
||||||
godbusConn, err = util.SessionBusPrivateUsable()
|
godbusConn, err = util.SessionBusPrivateUsable()
|
||||||
@@ -409,6 +409,18 @@ func (obj *CronRes) unitCheckApply(ctx context.Context, apply bool) (bool, error
|
|||||||
}
|
}
|
||||||
defer godbusConn.Close()
|
defer godbusConn.Close()
|
||||||
|
|
||||||
|
// We probably always want to enable this...
|
||||||
|
svc := fmt.Sprintf("%s.timer", obj.Name()) // systemd name
|
||||||
|
files := []string{svc} // the svc represented in a list
|
||||||
|
if obj.Startup == "enabled" {
|
||||||
|
_, _, err = conn.EnableUnitFilesContext(ctx, files, false, true)
|
||||||
|
} else if obj.Startup == "disabled" {
|
||||||
|
_, err = conn.DisableUnitFilesContext(ctx, files, false)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false, errwrap.Wrapf(err, "unable to change startup status")
|
||||||
|
}
|
||||||
|
|
||||||
// stop or restart the unit
|
// stop or restart the unit
|
||||||
if obj.State == "absent" {
|
if obj.State == "absent" {
|
||||||
return false, engineUtil.StopUnit(ctx, godbusConn, fmt.Sprintf("%s.timer", obj.Name()))
|
return false, engineUtil.StopUnit(ctx, godbusConn, fmt.Sprintf("%s.timer", obj.Name()))
|
||||||
@@ -426,6 +438,9 @@ func (obj *CronRes) Cmp(r engine.Res) error {
|
|||||||
if obj.State != res.State {
|
if obj.State != res.State {
|
||||||
return fmt.Errorf("state differs: %s vs %s", obj.State, res.State)
|
return fmt.Errorf("state differs: %s vs %s", obj.State, res.State)
|
||||||
}
|
}
|
||||||
|
if obj.Startup != res.Startup {
|
||||||
|
return fmt.Errorf("the Startup differs")
|
||||||
|
}
|
||||||
if obj.Trigger != res.Trigger {
|
if obj.Trigger != res.Trigger {
|
||||||
return fmt.Errorf("trigger differs: %s vs %s", obj.Trigger, res.Trigger)
|
return fmt.Errorf("trigger differs: %s vs %s", obj.Trigger, res.Trigger)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user