package app import ( "fmt" "strings" ) func (transportSystemdBackend) ID() string { return "systemd" } func (transportSystemdBackend) Action(client TransportClient, action string) transportBackendActionResult { action = strings.ToLower(strings.TrimSpace(action)) if action != "start" && action != "stop" && action != "restart" { return transportBackendActionResult{ OK: false, Code: "TRANSPORT_BACKEND_ACTION_FAILED", Message: "unsupported action: " + action, ExitCode: -1, } } units, errCode, errMsg := transportSystemdActionUnits(client, action) if len(units) == 0 { return transportBackendActionResult{ OK: false, Code: errCode, Message: errMsg, ExitCode: -1, } } aggOut := make([]string, 0, len(units)) aggErr := make([]string, 0, len(units)) netnsEnabled := transportNetnsEnabled(client) if res := transportSystemdRunPreActionHooks(client, action, units, netnsEnabled, &aggOut, &aggErr); res != nil { return *res } if res := transportSystemdRunActionUnits(client, action, units, &aggOut, &aggErr); res != nil { return *res } if netnsEnabled && action == "stop" && transportNetnsAutoCleanup(client) { transportSystemdRunPostStopCleanup(client, action, &aggOut, &aggErr) } msg := fmt.Sprintf("systemctl %s ok (%s)", action, strings.Join(units, ", ")) if len(aggErr) > 0 { msg += "; with warnings" } return transportBackendActionResult{ OK: true, ExitCode: 0, Stdout: strings.Join(aggOut, "\n"), Stderr: strings.Join(aggErr, "\n"), Message: msg, } } func transportSystemdStopMissingUnitNoop(stdout, stderr string, exitCode int, err error) bool { return transportSystemdUnitMissingError(stdout, stderr, exitCode, err) } func transportSystemdUnitMissingError(stdout, stderr string, exitCode int, err error) bool { if err == nil && exitCode == 0 { return false } msg := strings.ToLower(strings.TrimSpace(stderr + "\n" + stdout)) if msg == "" { return false } return strings.Contains(msg, "not loaded") || strings.Contains(msg, "not found") || strings.Contains(msg, "could not be found") || strings.Contains(msg, "unknown unit") }