-
Notifications
You must be signed in to change notification settings - Fork 47
Startup
The main method of Nucleus handles argument parsing and then automatic provisioning if requested. Very early on in the startup process Greengrass creates the Kernel instance. Kernel is the primary launchpad for all the Greengrass does in its state machine to create and run services. Next during startup, DeviceConfiguration is created which is used as a more ergonomic wrapper to read common configuration values from the global Greengrass configuration. If the device needs to be provisioned, then Greengrass calls out to the provisioning code. If the component default user does not exist, then Greengrass will try to create the user and group. If requested, Greengrass then configures itself as a system service. Finally, Greengrass can startup the Kernel.
Kernel launch begins by validating that we have a valid user configured for components to execute with. Next, Kernel checks to see if there is an ongoing deployment which restarted Greengrass and what to do next.
If Greengrass is in the BOOTSTRAP
phase, then it needs to identify which components need to execute their bootstrap steps and then execute them all sequentially. If any bootstrap step fails, then Greengrass will log the error and quit with an error in order to trigger the rollback.
If Greengrass is in the KERNEL_ACTIVATE
or KERNEL_ROLLBACK
phase when starting it will read the currently active deployment details from a persistent file and insert it as a deployment into the deployment queue.
If Greengrass is in the default state, then it will read the configuration and simply continue to the KernelLifecycle.launch.
Greengrass is entirely controlled by the configuration that it keeps on the device. The source of truth for everything on the device is the config file config.tlog
. This is a transaction log of all configuration changes in a newline separated JSON format. Because this file is the source of truth for everything, Greengrass takes great pains to ensure that its contents are correct and never corrupted, and if it is corrupted then to try and fallback as gracefully as possible. This logic is in KernelLifecycle.initConfigAndTlog.
- If Greengrass is provided a config file using the
--config
flag, then all other configuration which may exist will be ignored. This flag must not be used by anyone manually as it is very likely to cause problems. This flag is used by Greengrass when doing aBOOTSTRAP
orKERNEL_ROLLBACK
. - Assuming that no
--config
is provided, Greengrass attempts to validate theconfig.tlog
to see if we can trust it - If we believe
config.tlog
is valid, then we read it into the configuration in memory - If we do not believe that it is valid, then we attempt to read from one or more backup locations
- Greengrass reads
config.tlog~
,bootstrap.tlog
, andbootstrap.tlog~
in order until it finds one which is valid - Greengrass then loads the valid configuration (if any) into memory
- Greengrass reads
- If no
--init-config
is provided and there is noconfig.tlog
, Greengrass checks forconfig.yaml
and will load that file if it exists - If
--init-config
is provided, then that config file is read into the in memory configuration which will merge with the existing configuration based on the timestamp when the--init-config
file was last modified - If Greengrass did not read from the
config.tlog
, then it dumps the configuration that it just built up intoconfig.tlog
- Greengrass then dumps the effective configuration to
effectiveConfig.yaml
- Last, Greengrass configures a
ConfigurationWriter
to keep theconfig.tlog
updated with configuration changes as they happen
KernelLifecycle.launch is where the Greengrass state machine starts up services and starts doing real work. The launch starts by starting startables. This is done so that these services are guaranteed to be in a running state before anything else begins to start which may wish to use these services. Next, Greengrass finds any provisioning plugins, then builtin services and non-provisioning plugins, then the builtin services and non-provisioning plugins are loaded into the JVM. If the device is not configured to connect to IoT Core yet, the provisioning plugin (if any) will be executed to get the connection to IoT Core configured. Next, Greengrass locates the main
service. The main
service is a dummy service which does nothing itself except to have a HARD dependency on all Greengrass components and services. Greengrass then starts up all services.
To startup all services, Greengrass determines the dependency ordering from main
since all services were added as dependencies of main
. For each dependency, Greengrass checks if it should start and if it should start then Greengrass requests it to startup.