Custom Preflight Checks

Marc Campbell
 | 
Feb 10, 2017

Out of the box, Replicated always runs a set of preflight checks when your application is first installed or when any update is being installed. We check to make sure the server(s) and the environment running Replicated meets our minimum requirements and we offer some options to configure this to allow application developers the control to adjust the values we check for.

In Replicated 2.5.0, any application distributed on Replicated can now include additional custom preflight checks. We’ve worked to make this as flexible as possible, and are launching this with detailed documentation to help you implement.

Requirements

Custom preflight checks will only run in Replicated 2.5.0 or later. Any installation that’s running an earlier version of Replicated will simply ignore the custom preflight check and still allow it to run. To help ensure your customers are always running the most recent version of Replicated, check out the automatic updates feature launched in 2.3.0.

Overview

Preflight checks run on both the initial installation and on upgrades. They can work a little differently depending on if it’s an install or an upgrade.

Initial installation

During the initial installation, custom preflight checks are run, and they are run at the same time as the standard preflight checks. Any customer containers needed to complete preflight checks will be pulled before running preflight checks, and will be used to execute the custom checks. All checks have an optional when attribute, so you can build custom checks with the same concepts as you are familiar with from configuring your containers to start.

Upgrade Installation

When running a custom preflight check on an upgrade, the custom checks are run before the previous version is shut down.

Use Cases

Many basic use cases are still handled by the existing preflight checks. Custom preflight checks were introduced to allow you the ability to run your own application logic, in your own containers, on install and update. Custom preflight checks are very configurable, and there’s practically no limit to what you can do here, but a few examples we had are:

Check that a specific port is available on the server

If your application expect to be able to bind to port 80 and 443 on the host, a custom preflight check is a great place to ensure that these ports are available. This can even be configured to only check on initial installation, not on app upgrade because your application container will be running during update.

For example, if your application requires port 80, a simple custom preflight check to ensure that this port is available for your container to bind to might be written as:

[.pre]custom_requirements:- id: check-port-80-availablecommand:id: port_availabledata:port: '80'ip: '{{repl ThisNodePublicIPAddress }}'message: Port 80 is availabledetails: Port 80 must be available to bind toresults:- status: successmessage:default_message: Port 80 is availablecondition:status_code: 0 - status: error message: Another process is using port 80. Please stop that process before continuing. condition: status_code: 1[.pre]

Check that enough free disk space is available

If an upgraded version of your application will perform a large migration, there might be a need to ensure that enough temporary space is available to complete the migration successfully. With standard preflight checks, you can only ensure that the total amount of disk space meets a specific requirement. A custom preflight check could easily require that a server have at least 10 GB of free space before installing a specific upgrade.

For example, if you want to ensure that enough free disk space exists before installing or upgrading, and make this license configuratble. You can write a custom preflight check with:

[.pre]custom_requirements:- id: check-disk-space-available-datacommand:id: disk_space_availabledata:cluster: truetags: ["db"]dir: '{{repl ConfigItem "data_dir"}}'message: Check for free disk space in data directory.details: There must be at least {{repl LicenseFieldValue "min_size_gb"}}GB of free disk space in the data directory.results:- status: successmessage:default_message: There's enough free disk space in the {{.data_dir}} directoryargs:data_dir: '{{repl ConfigItem "data_dir"}}'condition:status_code: 0 # andbool_expr: '{{repl ParseFloat .Result | lt (Div (LicenseFieldValue "min_size_gb" | ParseFloat) 1e9) }}'- status: errormessage:default_message: The directory {{.data_dir}} only has {{.gigabytes}} available. Please make sure the directory has a minimum size of {{.min_gigabytes}}GB.args:data_dir: '{{repl ConfigItem "data_dir"}}'gigabytes: '{{repl ParseFloat .Result | HumanSize}}'min_gigabytes: '{{repl LicenseFieldValue "min_size_gb"}}'condition:status_code: 0[.pre]

Custom preflight checks are very configurable and we are happy to help implement them at any time. Reach out in Slack or email if you’d like to schedule some time to walk through how to implement them in your application.