Current section

Files

Jump to
nerves_system_vultr fwup-revert.conf
Raw

fwup-revert.conf

# Revert firmware for a Vultr Server Image
#
# To use:
# 1. Run `fwup -c -f fwup-revert.conf -o revert.fw` and copy revert.fw to
# the device. This is done automatically as part of the Nerves system
# build process. The file is stored in `/usr/share/fwup/revert.fw`.
# 2. On the device, run `fwup -t revert revert.fw -d $NERVES_FW_DEVPATH`. If
# it succeeds, reboot. If not, then it's possible that there isn't a previous
# firmware or the metadata about what's stored where is corrupt or out of
# sync.
#
# It is critical that this is kept in sync with the main fwup.conf.
require-fwup-version="0.19.0"
#
# Firmware metadata
#
# All of these can be overriden using environment variables of the same name.
#
# Run 'fwup -m' to query values in a .fw file.
# Use 'fw_printenv' to query values on the target.
#
# These are used by Nerves libraries to introspect.
define(NERVES_FW_PRODUCT, "Nerves Vultr Image")
define(NERVES_FW_DESCRIPTION, "")
define(NERVES_FW_VERSION, "${NERVES_SDK_VERSION}")
define(NERVES_FW_PLATFORM, "vultr")
define(NERVES_FW_ARCHITECTURE, "x86_64")
define(NERVES_FW_AUTHOR, "The Nerves Team")
define(NERVES_FW_DEVPATH, "/dev/vda")
define(NERVES_FW_APPLICATION_PART0_DEVPATH, "/dev/vda4") # Linux part number is 1-based
define(NERVES_FW_APPLICATION_PART0_FSTYPE, "ext4")
define(NERVES_FW_APPLICATION_PART0_TARGET, "/root")
define(NERVES_PROVISIONING, "${NERVES_SYSTEM}/images/fwup_include/provisioning.conf")
# Default paths if not specified via the commandline
define(ROOTFS, "${NERVES_SYSTEM}/images/rootfs.squashfs")
# This configuration file will create an image that has an MBR and the
# following 3 partitions:
#
# +----------------------------+
# | MBR w/ Grub boot code |
# +----------------------------+
# | grub.img (<256K) |
# +----------------------------+
# | Firmware configuration data|
# | (formatted as uboot env) |
# +----------------------------+
# | Boot partition (FAT32) |
# | /boot/grub/grub.cfg |
# | /boot/grub/grubenv |
# +----------------------------+
# | p2: Rootfs A (squashfs) |
# +----------------------------+
# | p3: Rootfs B (squashfs) |
# +----------------------------+
# | p4: Application (ext4) |
# +----------------------------+
define(UBOOT_ENV_OFFSET, 2048)
define(UBOOT_ENV_COUNT, 16) # 8 KB
# The boot partition contains the bootloader configuration
# 16 MB should be plenty for now.
define(BOOT_PART_OFFSET, 4096)
define(BOOT_PART_COUNT, 31232)
# Let the rootfs have room to grow up to 256 MiB
define-eval(ROOTFS_A_PART_OFFSET, "${BOOT_PART_OFFSET} + ${BOOT_PART_COUNT}")
define(ROOTFS_A_PART_COUNT, 524288)
define-eval(ROOTFS_B_PART_OFFSET, "${ROOTFS_A_PART_OFFSET} + ${ROOTFS_A_PART_COUNT}")
define(ROOTFS_B_PART_COUNT, ${ROOTFS_A_PART_COUNT})
# Application data partition (10 GiB). This can be enlarged
# to fill the entire volume.
define-eval(APP_PART_OFFSET, "${ROOTFS_B_PART_OFFSET} + ${ROOTFS_B_PART_COUNT}")
define(APP_PART_COUNT, 20971520)
# Firmware archive metadata
meta-product = ${NERVES_FW_PRODUCT}
meta-description = ${NERVES_FW_DESCRIPTION}
meta-version = ${NERVES_FW_VERSION}
meta-platform = ${NERVES_FW_PLATFORM}
meta-architecture = ${NERVES_FW_ARCHITECTURE}
meta-author = ${NERVES_FW_AUTHOR}
meta-vcs-identifier = ${NERVES_FW_VCS_IDENTIFIER}
meta-misc = ${NERVES_FW_MISC}
file-resource grubenv_a {
host-path = "${NERVES_SYSTEM}/images/grubenv_a"
}
file-resource grubenv_b {
host-path = "${NERVES_SYSTEM}/images/grubenv_b"
}
# Location where installed firmware information is stored.
# While this is called "u-boot", u-boot isn't involved in this
# setup. It just provides a convenient key/value store format.
uboot-environment uboot-env {
block-offset = ${UBOOT_ENV_OFFSET}
block-count = ${UBOOT_ENV_COUNT}
}
task revert.a {
# This task reverts to the A partition, so check that we're running on B
require-path-on-device("/", "/dev/vda3")
# Verify that partition A has the expected platform/architecture
require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
on-resource grubenv_a {
info("Reverting to partition A")
# Switch over
uboot_setenv(uboot-env, "nerves_fw_active", "a")
fat_write(${BOOT_PART_OFFSET}, "/boot/grub/grubenv")
}
}
task revert.b {
# This task reverts to the B partition, so check that we're running on A
require-path-on-device("/", "/dev/vda2")
# Verify that partition B has the expected platform/architecture
require-uboot-variable(uboot-env, "b.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
require-uboot-variable(uboot-env, "b.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
on-resource grubenv_b {
info("Reverting to partition B")
# Switch over
uboot_setenv(uboot-env, "nerves_fw_active", "b")
fat_write(${BOOT_PART_OFFSET}, "/boot/grub/grubenv")
}
}
task revert.unexpected.a {
require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
on-init {
# Case where A is good, and the desire is to go to B.
error("It doesn't look like there's anything to revert to in partition B.")
}
}
task revert.unexpected.b {
require-uboot-variable(uboot-env, "b.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
require-uboot-variable(uboot-env, "b.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
on-init {
# Case where B is good, and the desire is to go to A.
error("It doesn't look like there's anything to revert to in partition A.")
}
}
task revert.wrongplatform {
on-init {
error("Expecting platform=${NERVES_FW_PLATFORM} and architecture=${NERVES_FW_ARCHITECTURE}")
}
}
# Run "fwup /usr/share/fwup/revert.fw -t status -d /dev/vda -q -U" to check the status.
task status.aa {
require-path-on-device("/", "/dev/vda2")
require-uboot-variable(uboot-env, "nerves_fw_active", "a")
on-init { info("a") }
}
task status.ab {
require-path-on-device("/", "/dev/vda2")
require-uboot-variable(uboot-env, "nerves_fw_active", "b")
on-init { info("a->b") }
}
task status.bb {
require-path-on-device("/", "/dev/vda3")
require-uboot-variable(uboot-env, "nerves_fw_active", "b")
on-init { info("b") }
}
task status.ba {
require-path-on-device("/", "/dev/vda3")
require-uboot-variable(uboot-env, "nerves_fw_active", "a")
on-init { info("b->a") }
}
task status.fail {
on-init { error("fail") }
}