resource/systemd/unit/preparer.go
// Copyright © 2016 Asteris, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package unit
import (
"github.com/asteris-llc/converge/load/registry"
"github.com/asteris-llc/converge/resource"
"golang.org/x/net/context"
)
// Preparer for UnitState
//
// UnitState configures loaded systemd units, allowing you to start, stop, or
// restart them, reload configuration files, and send unix signals.
type Preparer struct {
// The name of the unit. This may optionally include the unit type,
// e.g. "foo.service" and "foo" are both valid.
Name string `hcl:"unit" required:"true"`
// The desired state of the unit. This will affect the current unit job. Use
// `systemd.unit.file` to enable and disable jobs, or `systemd.unit.config` to
// set options.
State string `hcl:"state" valid_values:"running,stopped,restarted"`
// If reload is true then the service will be instructed to reload it's
// configuration as if the user had run `systemctl reload`. This will reload
// the actual confguration file for the service, not the systemd unit file
// configuration. See `systemctl(1)` for more information.
Reload bool `hcl:"reload"`
// Sends a signal to the process, using it's name. The signal may be in upper
// or lower case (the `SIG` prefix) is optional. For example, to send user
// defined signal 1 to the process you may write any of: usr1, USR1, SIGUSR1,
// or sigusr1
//
// see `signal(3)` on BSD/Darwin, or `signal(7)` on GNU Linux systems for more
// information on signals
SignalName string `hcl:"signal_name" mutually_exclusive:"signal_name,signal_num"`
// Sends a signal to the process, using it's signal number. The value must be
// an unsigned integer value between 1 and 31 inclusive.
SignalNumber uint `hcl:"signal_number" mutually_exclusive:"signal_name,signal_num"`
executor SystemdExecutor
}
// Prepare a new task
func (p *Preparer) Prepare(ctx context.Context, render resource.Renderer) (resource.Task, error) {
var signal *Signal
if p.SignalName != "" {
num, err := ParseSignalByName(p.SignalName)
if err != nil {
return nil, err
}
signal = &num
} else if p.SignalNumber != 0 {
name, err := ParseSignalByNumber(p.SignalNumber)
if err != nil {
return nil, err
}
signal = &name
}
if p.executor == nil {
executor, err := realExecutor()
if err != nil {
return nil, err
}
p.executor = executor
}
r := &Resource{
Reload: p.Reload,
Name: p.Name,
State: p.State,
systemdExecutor: p.executor,
}
if signal != nil {
r.SignalName = signal.String()
r.SignalNumber = uint(*signal)
r.sendSignal = true
}
return r, nil
}
func init() {
registry.Register("systemd.unit.state", (*Preparer)(nil), (*Resource)(nil))
}