Documentation
¶
Overview ¶
Package systemd writes the systemd units that run the instances of an application installed in the system scope, and the mark that tells the instance commands which instances the units manage (decisions 20 and 39). It takes what the units are made of and knows nothing of how tt finds an application or runs an instance.
Units ¶
An application gets one template unit, <app>@.service. Its ExecStart runs tt instance start --foreground <app>:%i: tt stays in the foreground while the instance runs under a watchdog that never restarts it, and exits when the instance does (decision 37), so the restart is up to systemd. The unit gives tt the root of the system scope in TT_SYSTEM_ROOT, since tt run by systemd would look for the application in the default root otherwise, and its own name in TT_SYSTEMD_UNIT (UnitEnv), by which tt tells the start the unit asks for from a start next to the unit.
A template is one for all its instances, so what differs between them goes into a drop-in of every instance, <app>@<inst>.service.d/tt.conf: Restart= from the restart field of its record, whose values are those of systemd, and TimeoutStopSec= from its stop_timeout. The template carries the defaults of both for an instance without a drop-in.
tt stops the instance itself: it sends the instance its stop signal and kills it once its stop_timeout is up (decision 31). So the stop signal of systemd, SIGTERM, goes to tt alone (KillMode=mixed), and TimeoutStopSec= leaves tt its stop_timeout and a margin to kill the instance and exit; SIGKILL to the whole unit comes after that, or once tt has exited, for what is left.
Mark ¶
tt service systemd install writes the units and the mark, <root>/etc/<app>/ systemd.yaml (MarkFileName): the unit directory, the template, the user and the group the units run the instances as, which an install that names none keeps, and the unit of every instance the units manage. tt instance start, stop, restart and kill refuse those instances, pointing at systemctl: a watchdog of tt next to the unit would supervise the instance twice, and a stop behind the back of the unit would leave it out of step. tt service systemd uninstall removes the units and the mark.
The files tt writes start with GeneratedHeader. install overwrites only such files, and uninstall removes only such files: a unit of the same name written by someone else is not tt's to replace or remove.
Index ¶
- Constants
- Variables
- func DropInPath(unit string) string
- func Install(installation Installation) error
- func IsGenerated(content []byte) bool
- func MarkPath(hostDir string) string
- func RemoveMark(hostDir string) error
- func TemplateName(app string) string
- func Uninstall(hostDir string, mark Mark) ([]string, error)
- func UnitName(app, inst string) string
- func WriteFiles(dir string, files []File) error
- func WriteMark(hostDir string, mark Mark) error
- type File
- type Installation
- type Instance
- type Mark
- type RunAs
- type Units
Constants ¶
const ( // GeneratedHeader starts every file tt writes (IsGenerated). GeneratedHeader = "# Generated by tt service systemd" // UnitEnv is the variable the template unit sets to the name of the // unit, %n: tt instance start --foreground started with it is the start // the unit of the instance asks for, which the instance commands do not // refuse. UnitEnv = "TT_SYSTEMD_UNIT" // DefaultRunAs is the user and the group the units run the instances as // by default: the system user the deb and rpm packages of tt create, as // the units tt2 packed ran them. DefaultRunAs = "tarantool" // DropInName is the name of the drop-in of an instance in its drop-in // directory. DropInName = "tt.conf" )
const MarkFileName = "systemd.yaml"
MarkFileName is the mark of the units of an application in the directory of its host files, <root>/etc/<app>/.
Variables ¶
var ( // ErrForeignFile is wrapped by the error for a file in the place of a // unit that tt did not write: tt does not replace it. ErrForeignFile = errors.New("was not written by tt service systemd") // ErrNoUnitDir is wrapped by the error for a unit directory that does // not exist. ErrNoUnitDir = errors.New("no unit directory") )
var ( // ErrUnitName is wrapped by the error for an application or an instance // whose name cannot go into the name of a unit as it is. ErrUnitName = errors.New("cannot name a systemd unit") // ErrUnitPath is wrapped by the error for a path that cannot go into a // unit as it is. ErrUnitPath = errors.New("cannot be written into a systemd unit") // ErrUnitAccount is wrapped by the error for a user or a group whose // name cannot go into a unit as it is. ErrUnitAccount = errors.New("cannot be written into a systemd unit") )
var ErrInvalidMark = errors.New("invalid mark of systemd units")
ErrInvalidMark is wrapped by the error for a mark that cannot be read.
Functions ¶
func DropInPath ¶
DropInPath returns the path of the drop-in of the unit, relative to the unit directory: <unit>.d/tt.conf.
func Install ¶
func Install(installation Installation) error
Install writes the units and the mark of installation, and removes the stale files of the units installed before.
The unit directory must exist: it is the directory of the service manager, which tt does not create. A file in the place of a unit that tt did not write is an error before anything is written (ErrForeignFile).
The units go next to their places first, then the mark is written, then the units are moved into their places. A unit directory tt cannot write to fails the install before the mark is written, and once the mark is there the instance commands leave the instances to the units before the units can start them: tt never supervises an instance next to a unit that has not been marked.
func IsGenerated ¶
IsGenerated reports whether content is that of a file tt wrote.
func MarkPath ¶
MarkPath returns the path of the mark in hostDir, the directory of the host files of an application.
func RemoveMark ¶
RemoveMark removes the mark in hostDir, if there is one.
func TemplateName ¶
TemplateName returns the name of the template unit of the application app, <app>@.service.
func Uninstall ¶
Uninstall removes the files of the units mark records from the unit directory of mark, then the drop-in directories it leaves empty, and then the mark in hostDir. A file tt did not write is left in place and returned in kept, by its path; a file that is gone already is no failure.
A failure stops the removal before the mark is removed, so that tt service systemd uninstall can be run again.
func UnitName ¶
UnitName returns the name of the unit of the instance inst of the application app, <app>@<inst>.service.
func WriteFiles ¶
WriteFiles writes files into dir, which it creates if need be, as tt service systemd generate writes them into a directory: without a mark, and replacing only the files tt wrote (ErrForeignFile).
Types ¶
type File ¶
type File struct {
// Name is the path of the file relative to the unit directory.
Name string
// Content is what the file holds.
Content []byte
}
File is a file of the units.
func Generate ¶
Generate returns the files of units: the template unit, then the drop-in of every instance, in their order.
A name or a path that a unit would have to escape or quote is an error rather than escaped: %i passes the instance name to tt as the unit name has it, so a name must be one that needs no escaping in a unit name, and the paths go into ExecStart= and Environment= as they are.
type Installation ¶
type Installation struct {
// UnitDir is the directory the units go to.
UnitDir string
// HostDir is the directory of the host files of the application, which
// the mark goes to.
HostDir string
// Files are the files of the units.
Files []File
// Mark is the mark of the units.
Mark Mark
// Stale are the files of the units installed before, relative to
// UnitDir, that the new ones do not have: the drop-ins of instances gone
// from the description. Install removes them.
Stale []string
}
Installation is what Install writes.
type Instance ¶
type Instance struct {
// Name is the name of the instance.
Name string
// Restart is the restart field of its record.
Restart instances.RestartPolicy
// StopTimeout is TimeoutStopSec= of the instance: how long systemd waits
// for tt to stop it before it kills what is left.
StopTimeout time.Duration
}
Instance is what the drop-in of an instance is made of.
type Mark ¶
type Mark struct {
// UnitDir is the directory the units are in.
UnitDir string `yaml:"unit_dir"`
// Template is the name of the template unit, <app>@.service.
Template string `yaml:"template"`
// RunAs is the user and the group the units run the instances as,
// <user>:<group>, so that an install that names none keeps them. Empty
// is the default, DefaultRunAs.
RunAs string `yaml:"run_as,omitempty"`
// Instances maps the name of every instance the units manage to its
// unit, <app>@<inst>.service.
Instances map[string]string `yaml:"instances"`
}
Mark tells which instances of an application run under the systemd units tt service systemd install wrote, and where the units are.
type RunAs ¶
type RunAs struct {
// User is the name or the numeric id of the user.
User string
// Group is the name or the numeric id of the group.
Group string
}
RunAs is the user and the group the units run the instances as, User= and Group= of the template.
func ParseRunAs ¶
ParseRunAs parses <user>[:<group>]; without a group the group is the user's name. A name is made of what a unit takes without escaping (checkAccount).
type Units ¶
type Units struct {
// App is the name of the application.
App string
// RunAs is the user and the group the units run the instances as.
RunAs RunAs
// Root is the root of the system scope the application is installed in,
// which the units pass to tt as TT_SYSTEM_ROOT.
Root string
// TT is the tt executable the units run, an absolute path.
TT string
// StopTimeout is TimeoutStopSec= of the template, for an instance without
// a drop-in: how long systemd waits for tt to stop an instance whose
// record sets no stop_timeout.
StopTimeout time.Duration
// Instances are the instances of the application, in the order of its
// description.
Instances []Instance
}
Units is what the units of an application are made of.