Using safeStateClone within doPurge to applyIntermediateTarget after
successful volume purge has led to various type deficiencies being revealed
in common.js. Add several inline types in common.js to satisfy
the type checker (credit: Page <page@balena.io>). Delete common.d.ts
since it's not required and might mistakenly mask true I/O types of
functions in common.js.
Closes: #1611
Change-type: patch
Signed-off-by: Christina Wang <christina@balena.io>
The device request object was created with untouched fields left unset. When
comparing state to determine if a transition is required this would
result in a mismatch between:
{
Driver: '',
Count: 1,
DeviceIDs: null,
Capabilities: [Array],
Options: null
}
and
{
Count: 1,
Capabilities: [Array],
}
Which in turn resulted in the target service being continously restarted.
The fix is to instantiate the object in full.
Connects-to: https://github.com/balena-io/balena-supervisor/issues/1449
Connects-to: ae646a07ec
Change-type: patch
Signed-off-by: Robert Günzler <robertg@balena.io>
Setting this this variable to a base64 encoded string will replace the splash
image on the device by rewriting `/mnt/boot/splash/balena-logo.png`.
This will also make a copy of the default balena logo so the splash can
be restored if the variable is removed.
Change-type: minor
Signed-off-by: Felipe Lalanne <felipe@balena.io>
The `ensureRequiredOverlay` function is currently ran for any backend,
at this moment this causes no issue, since most configuration backends
are defined per single device type. However, with the option to modify splash
images, which is available for all device types, the function would add
unwanted configuration vars to the splash image configuration. Moving it
to the config txt backend solves this issue.
This PR adds the following
* Supervisor v1 API application actions now return HTTP status code 423 when locks
are preventing the action to be performed. Previously this resulted in a
503 error
* Supervisor API v2 service actions now returns HTTP status code 423 when locks are
preventing the action to be performed. Previously, this resulted in an
exception logged by the supervisor and the API query timing out
* Supervisor API `/v2/applications/:appId/start-service` now does not
check for a lock. Lock handling in v2 actions is now performed by each
step executor
* `/v1/apps/:appId/start` now queries the target state and uses that
information to execute the start step (as v2 does). Previously start
resulted in `cannot get appId from undefined`
* Extra tests for API methods
Change-type: patch
Connects-to: #1523
Signed-off-by: Felipe Lalanne <felipe@balena.io>
During first time run of the supervisor, the target state is queried
by `reportInitialEnv`. Since this happens early on the initialization
process, this target state report is missed by any listeners and this
can lead to the initial target state not beeing applied (see #1455).
This PR ensures that target state is re-emitted if there were no
listeners setup on call to update.
Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1455
Some endpoints filter data based on the scope of the API key
used to make the request. When in LocalMode the check was not
being made correctly and all apps were considered out of scope.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
This paves the way for running multiple applications and storing
information related to the application against the application itself. A
couple of hacks have been added to v1 and v2 endpoints to maintain
compatability but these should eventually be removed with the addition
of a v3 api.
Change-type: minor
Signed-off-by: Cameron Diver <cameron@balena.io>
Currently, when the label `io.balena.features.balena-socket` is set,
the balena engine socket is mounted under `/run/balena-engine.sock`.
This causes a problem when using systemd inside the container, since
this service remounts `/run` and `/run/lock` as tmpfs, causing the
socket to become unavailable.
Making a mount of the socket into `/host/run` solves this issue. This is
the same approach taken with DBUS.
Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1494
The source of truth for the device-type should be
device-type.json instead of config.json
Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1472
A docker-compose.yml with the following structure
```
version: '2.1'
services:
app_1:
build: ./noisy-1
image: noisy1
app_2:
build: ./noisy-1
image: noisy1
app_3:
build: ./noisy-1
image: noisy1
```
Will lead to the supervisor creating multiple image database entries
with the same dockerId (this is because of how the engine handles this
particular case). This case is not handled by the removal process
leading to image pile up and increased disk usage.
Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1434
The memory information reported by the supervisor currently
estimates the value of used memory as `MemTotal - MemFree`.
However, linux systems will try to cache and buffer as much
memory as possible, which will affect the output of `MemFree`
(from /proc/meminfo) and in consequence the memory usage seen
by the user on the dashboard, which will appear much greater than
it is.
The correct calculation should be `MemTotal - MemFree - Buffers - Cached`,
which the calculation performed by `htop` and the `free` commands.
Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1471
With the addition of the system information feature (CPU temp) etc if
there wasn't any changes in the docker or config state of the device,
updates in system information would not be sent to the API. Now we
attempt to send data once every maxReportFrequency (although this does
not mean that we will be sending data that often, we still only send the
delta, if one exists)
Change-type: patch
Closes: #1481
Signed-off-by: Cameron Diver <cameron@balena.io>
In order to make supervisor upgrades more transparent, lets move away
from this env var since it requires a container restart any time the supervisor
is upgraded. We should ultimately move towards providing the supervisors
set of capabilities, but that can come later
Connects-to: #1447
Change-type: major
Signed-off-by: Matthew McGinn <matthew@balena.io>
Due to the singleton work, when performing migration M00005 and there
are apps with services created in the database, a deadlock occurs
during database initialization due to a circular
dependency for generating scoped keys.
Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1468
When trying to apply SSDT overlays in Up Board, the supervisor currently
gets stuck in a loop trying to apply target state. See #1465
This was due to a bug in parsing the configuration, which lead to
the method bootConfigChangeRequired returning true when no change was
needed.
Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1465
Each service, when requesting access to the Supervisor API, will
now get an individual key which can be scoped to specific resources.
In this iteration the default scope will be to the application that
the service belongs to.
We also have a `global` scope which is used by the cloud API when in
managed mode.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
Due to switching to Alpine the ability to resolve mDNS
hostnames was lost. This patch overrides the lookup and
manually resolves the names.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
We provide a local DNS server for containers to use and this
was not allowed through the firewall when enabled.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
When invoking iptables-restore it can fail. This wasn't handled
and this makes sure that it fails gracefully.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
The host config variable HOST_DISCOVERABILITY can be set to
true or false, controlling the state of the avahi service. This
determines if the device advertises it's presence over mDNS.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
Signed-off-by: Rich Bayliss <rich@balena.io>
Controlled by BALENA_HOST_FIREWALL_MODE, the firewall can
either be 'on' or 'off'.
- In the 'off' state, all traffic is allowed.
- In the 'on' state, only traffic for the core services provided
by Balena is allowed.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
When reporting device information, send the MAC address of any
interfaces on the system. Also expose in the Supervisor API at
the route GET /v1/device.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
This is part of the work to make the application-manager module much
less monolithic, in preperation for system apps and more generally
multi-app.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
We were treating the database class as a singleton, but still having to pass
around the db instance. Now we can simply require the db module and have
access to the database handle.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
This allows a response to an input with dport=`supevisor api port` and
is required when the host OS is doing stateful firewalling.
This should not affect things when stateful firewalling is not in
effect, as the standard OUTPUT chain policy is ACCEPT, so we're just
being explicit about it.
Change-type: patch
Backport-to: next, current, sunset
Signed-off-by: Cameron Diver <cameron@balena.io>
We add an implicit .0 to the end of l4t versions which do not fulfill
semver, which allows us to always match using comparison operators, such
as < and <=.
Change-type: minor
Signed-off-by: Cameron Diver <cameron@balena.io>
The new label `io.balena.features.sysfs` will mount the host /sys into
the container at /sys.
Relates to issue: #743
Change-type: minor
Signed-off-by: Cameron Diver <cameron@balena.io>
Bring the labels into a more declarative format and run through them to
apply the various labels and env vars.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
This change will start the minimum backoff from 15s (up from 500ms) and
will use the appUpdatePollInterval configuration variable as the max.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
ConfigJson users now don't need to worry about initialization.
It's done lazily on the first public method call.
Implementation is also rewritten to follow async/await pattern.
Change-type: patch
Signed-off-by: Roman Mazur <roman@balena.io>
This means that if an image is created with a committed container, we
won't assume that it does not contain the balena env vars
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
A compose file can now contain a volume which uses a different driver
from the default one; local.
Change-type: patch
Signed-off-by: Rich Bayliss <rich@balena.io>
Before this change a mixed device fleet with a subset using l4t would
not be able to have containers which only run on the l4t based boards.
We add a mock l4t version so the contracts will always be denied on
non-l4t boards, but the release itself won't fail to validate.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
Part of device-state refactor
Fix the wrong usage of TargetState as DeviceApplicationState
Change-type: patch
Signed-off-by: Theodor Gherzan <theodor@balena.io>
Custom type definitions are removed for mixpanel module since they are embedded
into their npm package.
Change-type: patch
Signed-off-by: Roman Mazur <roman@balena.io>
These contracts can specify an OS version and supervisor version that
they require. If any of the containers in a release have requirements
that are not met, the release is rejected, and the previous release
continues to run.
Change-type: minor
Closes: #1086
Signed-off-by: Cameron Diver <cameron@balena.io>
This also required refactoring the request library to be generated with
a promise, as we now no longer get the information synchronously.
We also cache the release info, to avoid grabbing it again within the
same runtime, which does not make sense.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
With this change, we define a custom error handler as express middleware
which renders 503 error with JSON response that includes status and message
fields.
The handler also logs the error, so the stack can be inspected in supervisor
logs. It's also a point where we can report the error to analytics services.
This removes a bunch of error handlers written in every request handler
function. Behaviour should remain unchanged except the fact that
/healthy endpoint now returns 503 in case of failure instead of 500.
Change-type: patch
Signed-off-by: Roman Mazur <roman@balena.io>
If an error fires when writing to the cloud stream, it can stop any
calling processes from completing. Given that a logging failure should
not cause other processes to cancel, we catch and report the error but
otherwise do nothing else.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
The `createFromPath` method takes 3 parameters, while in a previous
version it was only 2 (the new format splits the old format's first
parameter into two, and keeping the last), before the refactor in commit
23e564389d (supervisor v9.18.4)
The backup restoration call has not been updated and thus calls that
function the old (wrong) way, resulting in failed restore, and volume
management errors on a device that attempted a restore.
Change-type: patch
Signed-off-by: Gergely Imreh <gergely@balena.io>
Various fields returned from the docker daemon don't retain order (for
example the volumes field). We now only select certain array values to
compare taking order into account.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
This can cause issues where the stack is exhausted
on large applications.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
Signed-off-by: Heds Simons <heds@balena.io>
The docker daemon can sometimes return null for various fields,
or omit the field altogether. The best thing to do with using
the docker api is to always use == null to cover both instances.
Change-type: patch
Signed-off-by: Roman Mazur <roman@balena.io>
This will throw a typed error in case when supervisor cannot inspect
its own container.
Change-type: patch
Signed-off-by: Roman Mazur <roman@balena.io>
With recent changes to local mode behavior, supervisor removes all engine objects
that were not present before entering local mode.
With this change, supervisor also detects its own resources and does not delete them
if it was updated during local mode operations.
Change-type: patch
Signed-off-by: Roman Mazur <roman@balena.io>
That way that this is performed is by first adding a depends_on entry
for the target service if it appears in a network mode. Then when we
generate the docker container for this service, we use the containerId
of the target container and replace the network_mode with
`container:<id>`.
When comparing state, we check that the containerId still points to the
contianerId of the target container, and in this way we ensure that
when a network mode target container changes, we change the dependent
container too.
Change-type: minor
Closes: #851
Signed-off-by: Cameron Diver <cameron@balena.io>
The code before this change could potentially remove a volume which
should not be removed if a container was deleted before the call that
references said volume.
To avoid this, we additionally filter the list of volumes to cleanup by
any that are referenced in the target state. This means that cleanup
will never remove it, as long as it's still supposed to be there,
regardless of if a container references it or not.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
This change also makes sure that in the application-manager workflow we
pass around instances of the Volume class, rather than just the config.
Change-type: patch
Signed-off-by: Cameron Diver <cameron@balena.io>
Since we were comparing the VPN's value before adding the explicit "true", there were cases
were the VPN is off, and therefore "value" didn't match the default, so the supervisor would
create a device specific SUPERVISOR_VPN_CONTROL = true, which is unnecessary and causes issues if
users don't expect this and move the device to an app that has VPN disabled. The correct behavior
is to compare "varValue" and only create a device config var if this value differs from the default.
(This was the behavior before the TS conversion in 01ed7bb103 )
Change-type: patch
Signed-off-by: Pablo Carranza Velez <pablo@balena.io>