running

package
v3.0.0-alpha.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: BSD-2-Clause Imports: 42 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// WatchdogFlag makes tt instance start run the watchdog of its one
	// target.
	WatchdogFlag = "watchdog"
	// ScopeFlag is the scope of the application.
	ScopeFlag = sdk.ScopeFlag
	// TemplateFlag is the template the instance was resolved with.
	TemplateFlag = sdk.TemplateFlag
	// AppDirFlag pins the application directory (app.Options.Dir).
	AppDirFlag = "app-dir"
)

The flags of tt instance start that make it the watchdog of one instance (StartWatchdog), and pin the application the watchdog runs the instance from: the watchdog must find the same application directory that the command that started it found, not whatever <root>/apps/<app> points to by the time it comes up. --watchdog and --app-dir are hidden; --scope and --template are the flags every command of tt instance takes.

View Source
const (
	// DefaultStopTimeout is how long the watchdog lets an instance whose
	// record sets no stop_timeout take to stop before it kills it.
	DefaultStopTimeout = instanceStopTimeout
	// StopMargin is what tt instance stop waits for the watchdog of an
	// instance over its stop timeout: the time the watchdog takes to kill the
	// instance that outlived it, and to exit.
	StopMargin = process_utils.TerminationTimeout - instanceStopTimeout
)
View Source
const (

	// ExitKilledOnStop is the exit code of the watchdog of tt instance start
	// --foreground whose instance did not stop in time and was killed: that
	// of a process killed by SIGKILL.
	ExitKilledOnStop = signalExitBase + int(syscall.SIGKILL)
)
View Source
const ForegroundFlag = "foreground"

ForegroundFlag is the flag of tt instance start that runs the instances in the foreground, and with WatchdogFlag runs the watchdog of one of them.

View Source
const InstanceDelimiter = ':'

InstanceDelimiter is the delimiter of the app and instance name.

Variables

View Source
var ErrConfigStorageCE = errors.New("a config storage needs Tarantool Enterprise Edition")

ErrConfigStorageCE is wrapped by the error for a Tarantool instance of the cluster config whose config is kept in a config storage, to be run on Tarantool Community Edition, which does not read one.

View Source
var ErrNotClusterInstance = errors.New("not an instance of the cluster config")

ErrNotClusterInstance is wrapped by the error for an instance given to a command that acts on the instances of the cluster config, such as tt cluster show, while no cluster config configures it: an instance that runs its script, or an external process.

View Source
var ErrNotTarantool = errors.New("not a Tarantool instance")

ErrNotTarantool is wrapped by the error for an external process given to a command that has something to do only with a Tarantool instance, such as tt connect: an external process has no sockets to reach, no config and no data.

Functions

func AppFile

func AppFile(inst *InstanceCtx) (string, bool, error)

AppFile returns the application file of inst, the Lua file it runs: the script of an instance that runs one, or app.file of its effective config, resolved against its application directory, which is what tarantool resolves it against. found is false when the config names none.

func AppIntegrity

func AppIntegrity(cmdCtx *cmdcontext.CmdCtx) func(app.Scope, string) (
	integrity.IntegrityCtx, error,
)

AppIntegrity returns how tt finds the integrity checks of an application, for app.Options.IntegrityFor, or nil when the checks are off.

The checks of an application are rooted at its directory - the project, or the installed version - whatever the directory tt runs in: an installed version is signed as the package it was packed from, and is checked where it is installed. They are rooted at the directories of the runtimes it runs on as well: the tarantool it is resolved to and the tt that runs its watchdog. A runtime a signed package bundles is installed with its hashes files there; one that has none adds nothing, and is refused when it is to run (checkSignedTarantool, watchdogCommandLine).

func AttachUnits

func AttachUnits(insts []InstanceCtx) error

AttachUnits sets Unit of every instance of insts that a systemd unit manages: one of an application of the system scope whose mark of the units, <root>/etc/<app>/systemd.yaml, names it (decision 20). Other scopes have no units (decision 39). The mark of every application is read once; a mark that cannot be read is an error, since the instances it may name cannot be told apart then.

It is the commands that act on instances that ask, when they resolve their targets: the watchdog does not ask again before it restarts its instance (reload), and a mark broken meanwhile does not keep it from doing so.

func Check

func Check(ctx context.Context, inst *InstanceCtx, file string) error

Check checks the syntax of file, a Lua file of the application of inst, with the tarantool the instance runs on: the syntax that counts is the one that tarantool accepts.

func CheckTarantool

func CheckTarantool(ctx context.Context, inst *InstanceCtx) error

CheckTarantool checks that the tarantool inst runs on can run it, for tt instance check: a Tarantool instance of the cluster config whose config points to a config storage needs Tarantool Enterprise Edition (checkConfigStorage). The other instances are not checked.

func DescribeTarantool

func DescribeTarantool(inst *InstanceCtx) (string, []string, error)

DescribeTarantool names the tarantool the Tarantool instance inst starts on and where it comes from, as a phrase such as "/usr/bin/tarantool, the first tarantool on PATH", with the warnings of the choice, for tt instance status --details.

The choice is made as the next start of the instance makes it (resolveTarantool), and runs no tarantool: an instance that runs already may have started on another one, should the choice have changed since, such as by tt binary switch in a project.

func ExitCodeOf

func ExitCodeOf(state *os.ProcessState) int

ExitCodeOf returns the exit code of the process that ended as state says: its exit status, or 128 plus the number of the signal that killed it.

func GetAppInstanceName

func GetAppInstanceName(instance InstanceCtx) string

GetAppInstanceName returns the target that names the instance, <app>:<instance>.

func IsAbleToStartInstances

func IsAbleToStartInstances(instances []InstanceCtx) (bool, error)

IsAbleToStartInstances checks if it is possible to start instances: each passes the checks before a start and its application has a tarantool, whose warnings are logged once per application, and which can run it (checkConfigStorage). An external process needs no tarantool, only its binary (checkExternal), and must not run already without its watchdog (Orphan): a second copy would start next to it.

The command that starts the instances calls it before it detaches their watchdogs, so that what stops an instance from starting reaches the user rather than only the log of the watchdog.

func IsExternal

func IsExternal(inst *InstanceCtx) bool

IsExternal reports whether inst is an external process, a record with binary, rather than a Tarantool instance.

func IsInstanceActive

func IsInstanceActive(instance *InstanceCtx) bool

IsInstanceActive returns true if the instance have running status.

func IsInstanceInactive

func IsInstanceInactive(instance *InstanceCtx) bool

IsInstanceInactive return true if the instance have not running status.

func IsScript

func IsScript(inst *InstanceCtx) bool

IsScript reports whether inst is a Tarantool instance that runs its script, a record with script, which configures it with box.cfg rather than the cluster config.

func IsStopped

func IsStopped(run *InstanceCtx) bool

IsStopped reports whether nothing of run runs: no watchdog holds its pid file, which is missing or stale (Status), and no process of an external process runs without its watchdog (Orphan). A pid file that cannot be read is not taken for stopped.

func Kill

func Kill(run InstanceCtx) error

Kill kills instance process: the process group of its watchdog, and the process group of an external process, which is a group of its own, also when its watchdog is gone (killOrphan).

Only the watchdog that holds the pid file is killed. An instance whose pid file is missing or nobody holds is not running, which is no failure: there is nothing to kill, and a stale file goes with what the watchdog that died left (removeStale). The pid in a stale file may name an unrelated process by now, whose group must not be killed.

func Logrotate

func Logrotate(run *InstanceCtx) error

Logrotate rotates logs of a started instance: its watchdog reopens tt.log on SIGHUP and passes SIGHUP on to tarantool, which reopens its own log, or sends an external process its logrotate_signal, if it has one. Only the watchdog that holds the pid file gets the signal: the pid in a file nobody holds may name an unrelated process by now.

func NewColorizedPrefixWriter

func NewColorizedPrefixWriter(writer io.Writer, color color.Color, prefix string) io.Writer

NewColorizedPrefixWriter creates a writer which colors the prefix or the whole line depending on its log level.

func Orphan

func Orphan(inst *InstanceCtx) int

Orphan returns the pid of the process of the external process inst that runs without its watchdog, or zero: no watchdog holds tt.pid, which is missing or stale (pidfile.Owner), while process.pid, which the watchdog wrote, names a live process that leads its process group, as the process does.

A watchdog killed by anything but tt instance kill leaves its process running in its group, which killing the group of the watchdog does not reach. Such a process is not the instance running, since nothing supervises it, and not an instance stopped either: tt instance start refuses to start a second copy next to it, tt instance stop and tt instance kill stop it, and tt instance status reports it.

A pid that leads no group is not the process, which leads its own; a pid reused by another group leader, which nothing tells from the process, is taken for it.

func PIDFile

func PIDFile(root, appName, inst string) (string, error)

PIDFile returns the pid file of the watchdog of the instance inst of the application appName under root, the root of its scope. It is for what knows an instance by its name alone, such as an instance that the description of its application no longer has.

func PIDFileStatus

func PIDFileStatus(path string) process_utils.ProcessState

PIDFileStatus returns the state of the watchdog whose pid file is path: RUNNING while a watchdog holds the file, which it does for its whole life (pidfile.Owner); NOT RUNNING without a file, or with one that holds no pid; and the dead state, with the pid in it, for a file nobody holds: the watchdog died without removing it, killed, crashed or gone with a reboot. The pid in such a file is not asked about, since it may name an unrelated process by now. A file that cannot be read counts as none.

func PinnedOptions

func PinnedOptions(inst *InstanceCtx, integ integrity.IntegrityCtx) app.Options

PinnedOptions are the options that find the application of inst again where it runs from: the scope and the application directory it was built with, the version itself rather than <root>/apps/<app>, and the template it was resolved with. The pair is chosen and read anew, its cluster config included: the watchdog starts the instance as the config says.

func Quit

func Quit(run InstanceCtx) error

Quit the Instance.

An external process is refused: the watchdog stops it with its stop signal whatever stopped the watchdog, so it would stop without a dump while the command reported one. So is an instance whose pid file no watchdog holds: it is not running, and there is nothing to take a dump of.

func RequireClusterRecord

func RequireClusterRecord(application *app.App, name string) error

RequireClusterRecord returns an error when the record of application named name is not configured by the cluster config: one wrapping ErrNotTarantool for an external process, as RequireTarantoolRecord does, and one wrapping ErrNotClusterInstance for an instance that runs its script. Like RequireTarantoolRecord, it passes a name the description does not declare.

func RequireTarantool

func RequireTarantool(inst *InstanceCtx) error

RequireTarantool returns an error wrapping ErrNotTarantool when inst is an external process.

func RequireTarantoolRecord

func RequireTarantoolRecord(application *app.App, name string) error

RequireTarantoolRecord returns an error wrapping ErrNotTarantool when the record of application named name is an external process. It is for a command that takes an instance by its name without acting on it, such as tt cluster show: a name the description does not declare passes, since such a command may name an instance that runs on another host.

func ResolveBinary

func ResolveBinary(inst *InstanceCtx) (string, error)

ResolveBinary returns the executable the external process inst runs, or an error wrapping errNoExecutable that says where it was looked for.

A binary with a slash is a path, resolved against the application directory when the description was read. A binary without one names a program: it is looked up first in .rocks/bin/ of the application directory, where the executable components of the package put what they build, then in PATH of tt (decision 52). So gw: {binary: gw} reads the same in the project and in an installed version, as a script of node_modules/.bin does, and runs the program the package built rather than one of the host that has its name. A file of .rocks/bin/ that cannot be run is an error rather than a reason to run another program of that name.

tt instance start builds nothing: when the program is missing from a project whose manifest has an executable component that builds it, the error says to run tt package build (buildHint).

With the integrity checks on, a program is not looked up in PATH: an instance runs only what its package and its runtimes sign, and the binary found is checked against the signature before it runs.

func SettleStopped

func SettleStopped(run *InstanceCtx) (bool, error)

SettleStopped reports whether nothing of run runs, as IsStopped does, and if so removes a stale pid file and what else the watchdog that died without cleaning up left (removeStale). It is for a command that acts on the files of a stopped instance, such as tt instance clean.

func Start

func Start(ctx context.Context, cmdCtx *cmdcontext.CmdCtx, inst *InstanceCtx) error

Start runs the watchdog of an instance, the process tt instance start detaches with --watchdog, until the supervision is over. The pid file of the instance names the watchdog, so tt instance stop, status, kill and logrotate reach it; watchdogOptions says what it does with their signals.

Before every start the watchdog reads the instance anew from the pair of the application directory it started from (reload): a restart after an exit picks up an edited config and restart policy, and stays on the version it started from. ctx bounds those reads, which may go to a config storage.

func StartForeground

func StartForeground(ctx context.Context, cmdCtx *cmdcontext.CmdCtx, inst *InstanceCtx,
	echo io.Writer,
) (int, error)

StartForeground runs the watchdog of inst as tt instance start --foreground runs it, in the current process: the watchdog Start runs, which never restarts the instance and copies its output to echo as well. It returns the exit code that tells how the instance ended, as the comment above says, or the error that kept the watchdog from running.

func StartForegroundWatchdog

func StartForegroundWatchdog(cmdCtx *cmdcontext.CmdCtx, ttExecutable string,
	instance InstanceCtx, args []string, stdout, stderr io.Writer,
) (*exec.Cmd, error)

StartForegroundWatchdog starts the watchdog of instance for tt instance start --foreground: tt instance start --watchdog --foreground, the watchdog StartForeground runs, as a child of the current process that is not detached from it but leads a process group of its own. The standard input of the watchdog is the null device, its standard output and error go to stdout and stderr. args go before the arguments that run the watchdog. The caller waits for the watchdog and passes the stop signals on to it.

The caller has made sure that the instance does not run; a pid file nobody holds is removed first, as StartWatchdog removes it (clearForWatchdog).

func StartWatchdog

func StartWatchdog(cmdCtx *cmdcontext.CmdCtx, ttExecutable string, instance InstanceCtx,
	args []string,
) error

StartWatchdog starts the watchdog of instance in the background, a tt instance start --watchdog detached from the command, unless the instance is already running: unless a watchdog holds its pid file. args go before the arguments that run the watchdog.

The watchdog gets no tt.yaml: it finds the application from what it is given (watchdogArgs).

func Status

Status returns the state of the watchdog of run, judged by its pid file (PIDFileStatus).

func Stop

func Stop(run *InstanceCtx) error

Stop stops an instance and reports any interruption or termination error.

func StopAll

func StopAll(runs []InstanceCtx) error

StopAll interrupts all selected instances before waiting for them to exit. A missing pid file means the instance is already stopped. Other errors are collected without preventing the remaining instances from stopping.

func StopAllResults

func StopAllResults(runs []InstanceCtx) []error

StopAllResults stops the batch and returns one error per input instance, in order. The process of an external process whose watchdog is gone is stopped as the watchdog would have stopped it (stopOrphan). An instance whose pid file nobody holds is not running: the file is stale, and goes (interruptWatchdog).

func StopTimeoutOf

func StopTimeoutOf(inst *InstanceCtx) time.Duration

StopTimeoutOf returns how long the watchdog of inst lets it take to stop before it kills it: stop_timeout of its record, or the default.

Types

type InstanceCtx

type InstanceCtx struct {
	// AppDir is the application directory, the working directory of the
	// instance: the project directory, or the version directory
	// <root>/apps/<app> pointed to when the application was resolved.
	AppDir string
	// InstanceScript is the script of a Tarantool instance that configures
	// itself (IsScript), an absolute path, which scriptSpec runs; empty for
	// the other kinds.
	InstanceScript string
	// Kind tells how the instance runs: a Tarantool instance configured by
	// the cluster config or by its script (IsScript), or an external process
	// (IsExternal).
	Kind instances.Kind
	// Binary is the executable of an external process: an absolute path, or
	// the name of a program looked up when the process starts, in .rocks/bin
	// of the application and then in PATH (ResolveBinary).
	Binary string
	// Args are the arguments of an external process.
	Args []string
	// Workdir is the working directory of an external process: workdir of
	// its record, or else DataDir.
	Workdir string
	// DataDir is the data directory of an external process that runs in it,
	// one whose record sets no workdir: <root>/var/lib/<app>/<inst>/, which
	// the start creates and tt instance clean empties. It is empty for a
	// process with workdir and for a Tarantool instance, whose data
	// directories are WalDir, MemtxDir and VinylDir.
	DataDir string
	// LogrotateSignal is the signal tt instance logrotate sends an external
	// process after reopening tt.log; zero sends it none.
	LogrotateSignal syscall.Signal
	// AppName is the name of the application.
	AppName string
	// Instance name.
	InstName string
	// Directory that stores various instance runtime artifacts like
	// console socket, PID file, etc.
	RunDir string
	// Directory that stores log files.
	LogDir string
	// Log is the name of log file.
	Log string
	// WalDir is a directory where write-ahead log (.xlog) files are stored.
	WalDir string
	// MemtxDir is a directory where memtx stores snapshot (.snap) files.
	MemtxDir string `mapstructure:"memtx_dir" yaml:"memtx_dir"`
	// VinylDir is a directory where vinyl files or subdirectories will be stored.
	VinylDir string `mapstructure:"vinyl_dir" yaml:"vinyl_dir"`
	// The name of the file with the watchdog PID under which the
	// instance was started.
	PIDFile string
	// ProcessPIDFile is the pid file of an external process, which its
	// watchdog writes; empty for a Tarantool instance.
	ProcessPIDFile string
	// Restart is the restart policy of the instance record, which the
	// watchdog follows after the instance exits on its own (restartsAfter).
	Restart instances.RestartPolicy
	// StopSignal is the signal the instance record stops the instance
	// with. Zero leaves tarantool the stop signal the watchdog receives,
	// SIGINT from tt instance stop, and stops an external process with SIGTERM.
	StopSignal syscall.Signal
	// StopTimeout is how long the instance record lets the instance take to
	// stop before it is killed. Zero is instanceStopTimeout.
	StopTimeout time.Duration
	// Control UNIX socket for started instance.
	ConsoleSocket string
	// Unix socket used as "binary port".
	BinaryPort string
	// ClusterConfigPath is the cluster config of the pair of the
	// application, the file tarantool -c gets; empty for an instance the
	// cluster config does not configure.
	ClusterConfigPath string
	// Configuration is instance configuration loaded from cluster config.
	// Nil when no cluster config is loaded.
	Configuration *goconfig.Config
	// Scope is the scope of the application.
	Scope app.Scope
	// Root is the root of that scope, which the runtime artifacts of the
	// instance are under (layout.ScopeLayout).
	Root string
	// Template is the --template value the instance was resolved with,
	// empty for none: the watchdog resolves the instance again with it
	// (PinnedOptions).
	Template string
	// Env holds the variables the instance record sets on top of the
	// inherited environment of tarantool.
	Env map[string]string
	// Unit is the systemd unit that manages the instance, as the mark of the
	// units tt service systemd install wrote says, or empty. AttachUnits sets
	// it; NewInstanceCtx leaves it empty.
	Unit string
	// Integrity are the integrity checks of the application of the instance
	// and of the runtimes it runs on (AppIntegrity), nil when they are off.
	// What the instance runs is checked with them before it is run: its
	// tarantool, its script, its binary, the tt of its watchdog.
	Integrity *integrity.IntegrityCtx
	// contains filtered or unexported fields
}

InstanceCtx contains information about application instance.

func Collect

func Collect(ctx context.Context, targets []app.Target, opts app.Options) ([]InstanceCtx, error)

Collect resolves targets, as app.ParseTargets parses them, to the contexts of the instances they select: the instances of the applications the targets name, in the order app.Resolve gives them. No targets select every instance of the project the command runs in.

It is the one way the commands that act on instances find them: the application comes from its scope, the instances and the config from its pair, and the runtime artifacts go under the root of the scope (NewInstanceCtx). opts.Template is kept in every context, so that the watchdog of an instance resolves it again from the same pair (StartWatchdog).

func InstancesOf

func InstancesOf(application *app.App, records []instances.Instance) ([]InstanceCtx, error)

InstancesOf builds the contexts of records, instance records of application, in their order. A record whose context cannot be built fails them all (NewInstanceCtx): a command must not act on part of what it was asked for while reporting success.

A config the application read by the best effort and could not read goes to the debug log: the command acts on the instances all the same, with the paths of the layout.

func NewInstanceCtx

func NewInstanceCtx(application *app.App, inst instances.Instance) (InstanceCtx, error)

NewInstanceCtx builds the context of the instance record inst of application, as app.Load and app.Resolve return them: what the commands that start, stop, inspect and clean up an instance need from it. It reads nothing but what application holds.

The runtime artifacts of the instance go under the root of the scope of the application (layout.ScopeLayout), and its working directory is the application directory: the project directory, or the version directory <root>/apps/<app> pointed to when the application was loaded, never the link itself, so that an instance keeps running the version it started from when the link moves. The config of the instance has the last word on the paths it sets, as it always has: wal.dir, snapshot.dir, vinyl.dir and console.socket, relative ones resolved against the application directory, which is what tarantool resolves them against.

What may stop an instance from starting, such as a relative path in the config of an installed one, is not checked here but at its start (IsAbleToStartInstances, Start, RunInstance and the Spec of every start): the context of an instance that cannot start is still the one to stop, inspect and clean it with.

An external process, a record with binary, keeps its log and its pid files in the same layout. It runs in workdir of its record, or else in its data directory in the layout, the one data directory it has. It has no sockets and no config, so tt instance status asks it nothing.

A Tarantool instance that runs its script, a record with script, has every path of the layout, and no cluster config: its script configures it with box.cfg (setScriptCtx).

A config read by the best effort (app.App.BestEffortConfig) that does not declare the instance, or does not fit it, is left out for it, as one that cannot be read is: the instance gets the paths of the layout, and the reason goes to the debug log.

type RunningCtx

type RunningCtx struct {
	// Instances contains information about application instances.
	Instances []InstanceCtx
}

RunningCtx contains information about application instances.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL