This make the LogBackend `log` method into an async method in
preparation for upcoming changes that will use backpressure from the
connection to delay logging coming from containers.
This also removes unnecessary imageId from the LogMessage type
Change-type: patch
This removes the dependence of the supervisor on the containerLogs
database for remembering the last sent timestamp. This commit instead
uses the supervisor startup time as the initial time for log retrieval.
This might result in some logs missing for services that may start
before the supervisor after a boot, or if the supervisor restarts.
However this seems like an acceptable trade-off as the current
implementation seems to make things worst in resource contrained
environments.
We'll move storing the last sent timestamp to a better storage medium in
a future commit.
Change-type: minor
The host-config module exposes the following interfaces: get,
patch, and parse.
`get` gets host configuration such as redsocks proxy configuration
and hostname and returns it in an object of type HostConfiguration.
`patch` takes an object of type HostConfiguration or LegacyHostConfiguration
and updates the hostname and redsocks proxy configuration, optionally
forcing the patch through update locks.
`parse` takes a user input of unknown type and parses it into type
HostConfiguration or LegacyHostConfiguration for patching, erroring if
parse was unsuccessful.
LegacyHostConfiguration is a looser typing of the user input which does
not validate values of the five known proxy fields of type, ip, port,
username, and password. We should stop supporting it in the next
major Supervisor API release.
Change-type: minor
Signed-off-by: Christina Ying Wang <christina@balena.io>
Parses input from PATCH /v1/device/host-config into either
type HostConfiguration, or if LegacyHostConfiguration if
input is of an acceptable shape (for backwards compatibility).
Once input has been determined to be of type HostConfiguration,
we can easily extract ProxyConfig from the object for patching,
stringifying, and writing to redsocks.conf.
Change-type: minor
Signed-off-by: Christina Ying Wang <christina@balena.io>
`stringify` takes a RedsocksConfig, an internal object
representation of the redsocks.conf file, and transforms
it into a valid string that can be written to redsocks.conf.
Signed-off-by: Christina Ying Wang <christina@balena.io>
This is part of the host-config refactor which
enables easier encoding to / decoding from `redsocks.conf`.
Signed-off-by: Christina Ying Wang <christina@balena.io>
This fixes a regression on the supervisor state engine computation
(added on v16.2.0) when
the target state removes a network at the same time that a service
referencing that network is changed. Example going from
```
services:
one:
image: alpine: 3.18
networks: ['balena']
networks:
balena:
```
to
```
services:
one:
image: alpine: latest
```
Would never reach the target state as killing the service in order to
remove the network is prioritized, but one of the invariants in the target state calculation is
to not kill any services until all images have been downloaded. These
two instructions were in contradiction leading to a deadlock.
The fix involves only adding removal steps for services depending on a
changing network or volume if the service container is not being removed
already.
Change-type: patch
This goes in the direction of grouping modules by responsibility. The
api-binder module is the middleware between the device and the backend,
thus the target state polling code makes more sense there.
Change-type: patch
This also deprecates the `getOSVariant` function of the `os-release`
module, as the OS variant are no longer defined in `/etc/os-release`.
Change-type: patch
Instead, add `getBalenaApi` function to api-helper so other modules can
access a balena API instance.
Further reduces circular dependencies to 5
Change-type: patch
This reduces circular dependencies from 250 to 80 by ensuring that
modules that only require types do not import the full module with all
its dependencies.
Change-type: patch
This splits `App`, `Network`, `Service` and `Volume` which used to be
defined as classes into an interface and a class implementation that is
not exported. This will allow to work with just the types in some cases
and prevent circular dependencies when importing.
Change-type: patch
This bumps dockerode, removes resin-docker-build in favor of
@balena/compose, and updates docker-delta and docker-progress packages.
Change-type: patch
The `mdns-resolver` module does not provide a default export. Trying to
use a default import notation, causes the `resolve` function to not be
found, breaking MDNS resolution.
Change-type: patch
Since HTTP's server.close() is async, there is a slim chance
for two instances of /v1/reboot or /v1/shutdown to be processed.
If the server is already closed when server.close() is called,
the call throws ERR_SERVER_NOT_RUNNING
which doesn't need to be surfaced to the user. This change
only allows one server.close() attempt to occur at a time.
Change-type: patch
Signed-off-by: Christina Ying Wang <christina@balena.io>
The Supervisor should only care whether a lockfile exists or
not. This also fixes an edge case where a user symlinked a lockfile
to a nonexistent file, causing the Supervisor to enter an error
loop as it was not able to `stat` the nonexistent file.
Change-type: patch
Signed-off-by: Christina Ying Wang <christina@balena.io>
This healthcheck fails when Supervisor memory usage is above a threshold
based on initial memory measurements after device state has settled.
Change-type: patch
Signed-off-by: Christina Ying Wang <christina@balena.io>
io-ts types that were generated using `shortStringWithRegex` were testing
against `VAR_NAME_REGEX`, instead of the Regex that was specified when
generating the type. This affected `DockerName` such that service names with
a dash in the middle were returning as false when passed through the
`DockerName.is` type guard, affecting how `getServicesLockedByAppId` was
returning a map of locked services.
Change-type: patch
Signed-off-by: Christina Ying Wang <christina@balena.io>
We don't want any Supervisor lockfiles to remain on the device
when a takeLock step fails because this would interfere with the user app.
Signed-off-by: Christina Ying Wang <christina@balena.io>
* Remove Supervisor lockfile cleanup SIGTERM listener
* Modify lockfile.getLocksTaken to read files from the filesystem
* Remove in-memory tracking of locks taken in favor of filesystem
* Require both `(resin-)updates.lock` to be locked with `nobody` UID
for service to count as locked by the Supervisor
Signed-off-by: Christina Ying Wang <christina@balena.io>
A takeLock step should be generated before any of the following steps:
* kill
* start
* stop
* updateMetadata
* restart
* handover
ALL services in an app will be locked for any of the above actions,
unless the action is generated through Supervisor API's
`POST /v2/applications/:appId/(start|stop|restart)-service` endpoints,
in which case only the target service will be locked.
A lock will be taken for a service before it starts by creating the
directory in /tmp before the Engine creates it through bind mounts.
Also, the commit simplifies the generation of service kill
steps from network/volume changes or removals.
Signed-off-by: Christina Ying Wang <christina@balena.io>
This commit changes a few things:
* Pass `force` to `takeLock` step directly. This allows us to remove
the `lockFn` used by app manager's action executors, setting takeLock
as the main interface to interact with the update lock module. Note
that this commit by itself will not pass tests, as no update locking
occurs where it once did. This will be amended in the next commit.
* Remove locking functions from doRestart & doPurge, as this is
the only area where skipLock is required.
* Remove `skipLock` interface, as it's redundant with the functionality
of `force`. The only time `skipLock` is true is in doRestart/doPurge,
as those API methods are already run within a lock function. We removed
the lock function which removes the need for skipLock, and in the next
commit we'll add locking as a composition step to replace the
functionality removed here.
* Remove some methods not in use, such as app manager's `stopAll`.
Signed-off-by: Christina Ying Wang <christina@balena.io>
This commit only implements the action that a takeLock step
results in. It does not add takeLock step generation logic
to the state funnel yet.
Signed-off-by: Christina Ying Wang <christina@balena.io>
releaseLock is a step that will be inferred if there are services
in target state, and if some of those services have locks taken by
the Supervisor.
The releaseLock composition step calls the method of the same name
in the updateLock module, which takes the exclusive process lock before
disposing all Supervisor lockfiles in the target appId.
This is half of the update lock incorporation into the state funnel, as
we also need to introduce a takeLock step which triggers during crucial
stages of device state transition.
Signed-off-by: Christina Ying Wang <christina@balena.io>
We need the supervisor to be able to manage config.txt changes for the
RevPi Connect 4.
Change-type: patch
Signed-off-by: Shreya Patel <shreya@dynamicdevices.co.uk>
The message can be an empty string or similarly unhelpful, therefore
logging the entire error means that we will have whatever the message
may be along with the stack trace and other info that will be helpful
even when the message is not
Change-type: patch