Skip to content

systemd-js/systemd

Repository files navigation

Systemd.js

Collection of packages useful when interfacing with systemd.

@systemd-js/conf

  • INI parser for systemd config files.
  • Fluent builders to create and modify unit files.

Based on systemd v255.4

Installation

yarn add @systemd-js/conf

Examples

Parse systemd ini file into object.

Note: Ini parser is not fully implemented, lacks support for escaping and quoting.

import {INI} from "@systemd-js/conf";

const unit = `
[Unit]
Description=example
After=network.target

[Install]
WantedBy=multi-user.target

[Service]
ExecPreStart=/opt/example/agent start-1
ExecPreStart=/opt/example/agent start-2
ExecStart=/opt/example/agent start
EnvironmentFile=/opt/example/.env
Restart=always
PrivateTmp=yes
User=root
`;

const ini = INI.fromString(unit).toObject();

{
  Unit: {
    Description: "example",
    After: "network.target",
  },
  Install: {
    WantedBy: "multi-user.target",
  },
  Service: {
    ExecPreStart: [
      "/opt/example/agent start-1",
      "/opt/example/agent start-2",
    ],
    ExecStart: "/opt/example/agent start",
    EnvironmentFile: "/opt/example/.env",
    Restart: "always",
    PrivateTmp: true,
    User: "root",
  },
};

Create service unit for ini string and modify service user definition.

const unit = `
[Unit]
Description=example
After=network.target

[Install]
WantedBy=multi-user.target

[Service]
ExecPreStart=/opt/example/agent start-1
ExecPreStart=/opt/example/agent start-2
ExecStart=/opt/example/agent start
EnvironmentFile=/opt/example/.env
Restart=always
PrivateTmp=yes
User=root
`;

const ini = INI.fromString(unit)
const service = Service.fromINI(ini)

service
  .getServiceSection()
  .setUser("test")

service.toINIString();

Create service unit using fluent builder

import {Service} from "@systemd-js/config";

const service = new Service();

service
  .getUnitSection()
  .setDescription("This is a example unit")

service
  .getInstallSection()
  .setWantedBy("multi-user.target")
  
service
 .getServiceSection()
 .setType("simple")
 .setWorkingDirectory("/tmp")
 .setRestart("always")
 .setExecStartPre("/usr/bin/echo 'Before'")
 .setExecStart("/usr/bin/echo 'Hello World'")
 .setExecStartPost("/usr/bin/echo 'After'")

Create timer unit using fluent builder

import {Timer} from "@systemd-js/config";
const timer = new Timer()

timer
  .getUnitSection()
  .setDescription("example")
  .setAfter("network.target");

timer
  .getInstallSection()
  .setWantedBy("multi-user.target");  

timer
  .getTimerSection()
  .setOnCalendar("daily")
  .setUnit("postgresql-dump.target");

@systemd-js/ctl

Control over units. Interface to systemctl. At the moment this lack proper error handling.

Installation

yarn add @systemd-js/ctl

Examples

State manipulation of existing service.

import {Ctl} from "@systemd-js/ctl";

const ctl = new Ctl("test.service")

ctl.disable()
ctl.enable()
ctl.stop()
ctl.start()
ctl.restart()

Creation of new service "example.service"

import {Service} from "@systemd-js/config";
import {Ctl} from "@systemd-js/ctl";

const service = new Service();

service
  .getUnitSection()
  .setDescription("This is a example unit")

service
  .getInstallSection()
  .setWantedBy("multi-user.target")
  
service
 .getServiceSection()
 .setType("simple")
 .setExecStart("/usr/bin/echo 'Hello World'")

const ctl = new Ctl("example", service)

ctl.create()
ctl.enable()
ctl.start()

In addition to Ctl class, package expose functions to call systemctl directly.

import {restart, start, stop} from "@systemd-js/ctl";

stop("example.service")
start("example.service")
enable("example.service")
disable("example.service")
reload("example.service")
restart("example.service")