blob: 7828ce6f049bb978cbed2f8e7db55300304ab698 [file] [log] [blame]
khenaidooffe076b2019-01-15 16:08:08 -05001// Copyright 2015 CoreOS, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package util contains utility functions related to systemd that applications
16// can use to check things like whether systemd is running. Note that some of
17// these functions attempt to manually load systemd libraries at runtime rather
18// than linking against them.
19package util
20
21import (
22 "fmt"
23 "io/ioutil"
24 "os"
25 "strings"
26)
27
28var (
29 ErrNoCGO = fmt.Errorf("go-systemd built with CGO disabled")
30)
31
32// GetRunningSlice attempts to retrieve the name of the systemd slice in which
33// the current process is running.
34// This function is a wrapper around the libsystemd C library; if it cannot be
35// opened, an error is returned.
36func GetRunningSlice() (string, error) {
37 return getRunningSlice()
38}
39
40// RunningFromSystemService tries to detect whether the current process has
41// been invoked from a system service. The condition for this is whether the
42// process is _not_ a user process. User processes are those running in session
43// scopes or under per-user `systemd --user` instances.
44//
45// To avoid false positives on systems without `pam_systemd` (which is
46// responsible for creating user sessions), this function also uses a heuristic
47// to detect whether it's being invoked from a session leader process. This is
48// the case if the current process is executed directly from a service file
49// (e.g. with `ExecStart=/this/cmd`). Note that this heuristic will fail if the
50// command is instead launched in a subshell or similar so that it is not
51// session leader (e.g. `ExecStart=/bin/bash -c "/this/cmd"`)
52//
53// This function is a wrapper around the libsystemd C library; if this is
54// unable to successfully open a handle to the library for any reason (e.g. it
55// cannot be found), an error will be returned.
56func RunningFromSystemService() (bool, error) {
57 return runningFromSystemService()
58}
59
60// CurrentUnitName attempts to retrieve the name of the systemd system unit
61// from which the calling process has been invoked. It wraps the systemd
62// `sd_pid_get_unit` call, with the same caveat: for processes not part of a
63// systemd system unit, this function will return an error.
64func CurrentUnitName() (string, error) {
65 return currentUnitName()
66}
67
68// IsRunningSystemd checks whether the host was booted with systemd as its init
69// system. This functions similarly to systemd's `sd_booted(3)`: internally, it
70// checks whether /run/systemd/system/ exists and is a directory.
71// http://www.freedesktop.org/software/systemd/man/sd_booted.html
72func IsRunningSystemd() bool {
73 fi, err := os.Lstat("/run/systemd/system")
74 if err != nil {
75 return false
76 }
77 return fi.IsDir()
78}
79
80// GetMachineID returns a host's 128-bit machine ID as a string. This functions
81// similarly to systemd's `sd_id128_get_machine`: internally, it simply reads
82// the contents of /etc/machine-id
83// http://www.freedesktop.org/software/systemd/man/sd_id128_get_machine.html
84func GetMachineID() (string, error) {
85 machineID, err := ioutil.ReadFile("/etc/machine-id")
86 if err != nil {
87 return "", fmt.Errorf("failed to read /etc/machine-id: %v", err)
88 }
89 return strings.TrimSpace(string(machineID)), nil
90}