Empty MAAS_RESOURCES_FILE when using custom storage layouts

Hi everyone. I’m trying to commission some machines with a custom storage layout, but my script is getting an empty MAAS_RESOURCES_FILE; however, when I check 20-maas-03-machine-resources, there’s a ton of JSON being emitted (and 20-maas-03-machine-resources passes with a checkmark)

My script looks like this:

#!/usr/bin/env python3
#
# 45-custom-storage-layout - compute nodes
#
# --- Start MAAS 1.0 script metadata ---
# name: 45-custom-storage-layout
# title: Compute Cluster Layout
# description: smallest volume gets / and /boot/efi, the other volumes become scratch volumes; if there is only 1 volume, colocate everyone there
# script_type: commissioning
# timeout: 60
# --- End MAAS 1.0 script metadata ---

import json
import logging
import os
import sys
from pathlib import Path

## check for MAAS_STORAGE_CONFIG_FILE and MAAS_RESOURCES_FILE
required_env_vars = ["MAAS_STORAGE_CONFIG_FILE", "MAAS_RESOURCES_FILE"]
for required_var in required_env_vars:
    try:
        _ = os.environ[required_var]
    except KeyError as e:
        print(f"{required_var} must be set, bailing")
        sys.exit(-1)

storage = {'layout': {}, 'mounts': {}}

def dlog(msg):
    logging.log(logging.DEBUG, msg)

dlog("here's the environment:")
for name, value in os.environ.items():
    dlog("{0}: {1}".format(name, value))

dlog("reading MAAS_RESOURCES_FILE")
resources_file_path = os.environ['MAAS_RESOURCES_FILE']
try:
    txt = Path(resources_file_path).read_text()
    machine_resources = json.loads(txt)
except OSError as e:
    sys.exit(f"Failed to read {resources_file_path}: {e}")
except json.JSONDecodeError as e:
    print("File we couldn't parse:")
    print(txt)
    sys.exit(f"Failed to parse {resources_file_path}: {e}")

layout = {}
dlog("finding smallest disk")
smallest_disk = None
smallest_disk_size = float('inf')
for d in machine_resources['resources']['storage']['disks']:
    if d['size'] < smallest_disk_size:
            smallest_disk = d['id']
            smallest_disk_size = d['size']
dlog(f"smallest disk is {smallest_disk}")

dlog("setting up boot layout")
storage['mounts'] = {
    "/": {
        "device": f"{smallest_disk}2",
        "options": "noatime"
    },
    "/boot/efi": {
        "device": f"{smallest_disk}1"
    }
}
storage['layout'][smallest_disk] = {
    "type":"disk",
    "ptable": "gpt",
    "boot": True,
    "partitions": [
            {
                "name": f"{smallest_disk}1",
                "fs": "fat32",
                "size": "4G",
                "bootable": True
            },
            {

                "name": f"{smallest_disk}2",
                "fs": "xfs",
                "size": "50G"
            },
    ]
}

single_disk_in_machine = len(machine_resources['resources']['storage']['disks']) == 1

# if there's only 1 disk, we want to put scratch on that; otherwise we want to create scratch partitions on the other disks
if single_disk_in_machine:
    scratch_size = int(smallest_disk_size/1000/1000/1000) - 50 - 4
    # MaaS seems to want this to be gigabytes with a G appended, not number of bytes.
    scratch_size = f"{scratch_size}G"
    print("there's a single disk in this machine colocating /scratch with the OS")
    print(f"size of scratch is going to be {scratch_size}")
    scratch_disks = [{"id": smallest_disk,
                      "size": scratch_size}]
else:
    print("We can use whole disks for scratch!")
    scratch_disks = [{"id": d['id'], "size": f"{int(d['size']/1000/1000/1000)-1}G"} for d in machine_resources['resources']['storage']['disks'] if d['id'] is not smallest_disk]

dlog(f"setting up scratch disks {scratch_disks}")
for idx, disk in enumerate(scratch_disks):
    dlog(disk)
    if single_disk_in_machine:
        # partitions is a list of partition objects, mounts is one big object with keys that are the mountpoints
        storage['layout']['sda']['partitions'].append({"name": "sda3", "size": str(disk['size']), "fs": "xfs"})
        mount_device = "sda3"
    else:
        storage['layout'][disk['id']] = {
            "type": "disk",
            "ptable":"gpt",
            "boot": False,
            "partitions": [{
                "name": f"{disk['id']}1",
                "fs":"xfs",
                "size": str(disk['size'])
            }]
        }
        # if there's only 1 scratch mount, call it /scratch instead of /scratch0
        if idx == 0:
            idx = ''
        mount_device = f"{disk['id']}1"
    storage['mounts'].update({ f"/scratch{idx}": { "device": mount_device, "options": "noatime"} })

dlog("writing MAAS_STORAGE_CONFIG_FILE")
with open(os.environ["MAAS_STORAGE_CONFIG_FILE"], 'w') as fd:
    dlog("dumping json to disk")
    json.dump(storage, fd)
    print(json.dumps(storage, sort_keys=True, indent=4))

The layout script output is:

File we couldn't parse:

Failed to parse /tmp/tmpt6xh1jyw: Expecting value: line 1 column 1 (char 0)

Do you have any ideas of what else I can check to troubleshoot this? Happy to attach the combined results from 20-maas-03-machine-resources, but it’s a blob of 4kloc of json.