A new Canopy version is live. This tab is still running the old one.
Ineapple logo Canopy INEAPPLE
Your edge fleet,
Orchestrated.
Every dot is a host reporting in.

Bad credentials

All access is logged and audited.

Ineapple logo
Fleet Images Network Jobs Provisioning Hardware Updates Backups
Audit Consoles Alerts Enrollment Users
Fleet
connected disk warning offline
Golden qcow2 library
ImageVersionSizeChecksumOn hostsUsed byUploaded
Build host OS image

The host runs the Ubuntu installer in a throwaway VM, then packs the result and sends it here. About 20 minutes. Nothing on the host changes.

The Ubuntu the image is built from.

Push to hosts
TemplatePorts it expectsBondsBridgesCaptured
CreatedVMSnapshotHostStatusSizeDigest
TimeActorActionTargetOutcomeDetail
Recorded sessions
StartedUserTargetTypeDurationTrafficEnded
WaveOSAdmin userAdmin passwordMachinesExpiresStatus
Device typeSerialHardware listPublic IPPrivate IPsNICsWaveFirst seenLast seenStatus
Create wave

This login goes into every host the wave builds. It is how you reach a box when the agent is the thing that failed.

Create the wave, build its ISO from the row, then boot the machines from it. Machines it admits show up under Pending hosts only when their serial is not on the Hardware list.

Export CSV Blank template
SerialHostnameSiteHardwareNetwork templateStatusNotes
0 selected
NameStatusAgentHelpers Security patchesAll patchesLast patchedLast job
Update host OS

One image for every selected host. Built by Canopy: Ubuntu, KVM, the agent and the A/B boot pieces, ready to be written straight into a slot.

After a good bootA slot that reaches Canopy is kept, and the old slot becomes the spare. Or leave it on trial and decide yourself under Actions.
Stop on first failureHalt the campaign if any host fails to fill or its trial slot never comes up.
Start campaign
Security updates onlyCVE fixes only. Never a new Ubuntu release.
Reboot when neededReboot a host if the update requires it.
Stop on first failureHalt the campaign if any host fails.

Channels

Email sending needs CANOPY_SMTP_URL in the control's .env, for example smtp://user:password@mail.example.com:587, then a control restart.

NameTypeDestinationEnabledLast error

Rules

ConditionEnabledThresholdHold time (s)

History

OpenedConditionTargetDetailStateResolved

Hosts

HostStatusAuthentication

Tokens

MintedFor hostByExpiresStatus

The legacy shared token (CANOPY_ENROLL_TOKEN in .env) is still active. Hosts that have never enrolled can use it. Once every host shows "per-host credential", remove it from .env and restart the control.

console provision
UserRoleConsoleProvisionStatusLast login

Add hardware

Only the serial is required. The hostname is what the box is called when it is admitted; leave it blank to name it from its device type and serial.

Start a VM

Table settings

Table density

Show table columns

Changes apply immediately. Extra columns scroll sideways.

Location

The street address of the site this host lives at.

Edit networks

The order IS the interface numbering: row 1 becomes GigabitEthernet1, row 2 becomes Gi2. Adding, removing or reordering renumbers the ports, which is why the VM must be shut off first. Changes apply when it starts.

Channel setup guide

  1. In Telegram, message @BotFather and send /newbot. Give the bot a name and a username ending in bot.
  2. BotFather replies with the bot token, like 7123456789:AAHrX9y…. Copy it. Treat it like a password.
  3. Open a chat with your new bot and send it any message. Bots cannot message you first, so this step is required.
  4. Find your chat id: open api.telegram.org/bot<TOKEN>/getUpdates in a browser and read "chat":{"id": …}. For a group, add the bot to the group first, the id starts with a minus.
  5. Back here: type Telegram, paste the token and the chat id, Add channel, then Send test.

If the test fails with 400 or 403, the bot was never messaged first. Send it a hello and try again.

  1. Go to api.slack.com/apps signed into your workspace. Create New App, From scratch, name it Canopy Alerts.
  2. In the app menu open Incoming Webhooks and switch the toggle on.
  3. Click Add New Webhook to Workspace and pick the channel that should receive alerts.
  4. Copy the webhook URL, it looks like hooks.slack.com/services/T…/B…/….
  5. Back here: type Slack, paste the URL, Add channel, then Send test.

The URL is a credential. Anyone holding it can post into that Slack channel. If it leaks, delete the webhook in Slack and make a new one.

  1. Email needs an SMTP relay Canopy can hand messages to. Easiest for the lab is Gmail: account Security, turn on 2-Step Verification, then create an App password.
  2. On the control server add two lines to ~/canopy/.env:
    CANOPY_SMTP_URL=smtp://you@gmail.com:app-password@smtp.gmail.com:587
    CANOPY_SMTP_FROM=you@gmail.com
  3. Restart the control: sudo systemctl restart canopy-control.
  4. Back here: type Email, enter the recipient address, Add channel, then Send test.

The From address must belong to the account you authenticate with, or receiving servers treat it as spam. Company Microsoft 365 works too, smtp.office365.com port 587, but SMTP AUTH must be enabled for that mailbox by an admin. Email is the slow channel, use it as the paper trail and Slack or Telegram as the pager.

  1. For anything that accepts an HTTPS POST: automation platforms, ticketing, your own service.
  2. Create an inbound webhook on the receiving side and copy its https:// URL.
  3. Back here: type Webhook, paste the URL, Add channel, then Send test.

Canopy sends this JSON body with each alert and each resolve:

{"source":"canopy","subject":"[Canopy] ALERT host_offline: kvm-host-2","body":"…","ts":1785419877000}

Telegram and Slack have their own types above because their APIs demand different payload shapes, a generic webhook will not reach them.

Enrollment token minted

Copy it now. It is shown only this once, expires in 24 hours, and works for exactly one host. Use it as the token argument of the agent installer.

Edit resources

Every VM has its own memory ceiling that was fixed when it booted (separate from the host's total). Memory changes under that ceiling can apply while the VM runs. Going past it, or changing CPUs, needs a shutdown and start. Routers typically apply everything at their next restart either way. The job result in Jobs spells out which happened.

512

Add bridge

Deploy
Console connecting…
This session is recorded and audited. Idle sessions close after 15 minutes. Serial needs platform console serial on the device; Screen works from first boot. Host console is ssh to the KVM host as the account you named: type its password in the terminal.

Jobs

Fleet update settings

Automatic security updatesHosts install security fixes nightly on their own. Never a reboot.