Skip to content

Instantly share code, notes, and snippets.

@joseivanlopez
Last active July 11, 2024 14:51
Show Gist options
  • Save joseivanlopez/6015d1492c7856b1d48c1c9a28970f69 to your computer and use it in GitHub Desktop.
Save joseivanlopez/6015d1492c7856b1d48c1c9a28970f69 to your computer and use it in GitHub Desktop.

Reevalute the storage guided settings

The storage section of the Agama settings has two different parts: the specification of the devices (e.g., drives, volumeGroups, etc) and the so called guided settings:

"storage": {
  "drives": [],
  "volumeGroups": [],
  "mdRaids": [],
  "guided": {}
}

For each type of device (e.g., drives, volumeGroups) the settings allows configuring the volumes (partitions or logical volumes) to create, reuse and delete:

"storage": {
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": [
        {
          "search": { "name": "/dev/vda1" },
          "delete": true
        },
        {
          "search": { "name": "/dev/vda2" },
          "mount": { "path": "/boot/efi" }
        },
        {
          "mount": { "path": "/" },
          "filesystem": "btrfs",
          "size": "10 GiB"
        },
        {
          "mount": "swap",
          "filesystem": "swap",
          "size": "auto"
        }
      ]
    }
  ]
}

The guided section offers its own way to create, reuse and delete devices. For example, the config above can be replicated in the guided section by:

"storage": {
  "guided": {
    "target": { "disk": "/dev/vda" },
    "space": {
      "policy": "custom",
      "actions": [ { "forceDelete": "/dev/vda1" } ]
    },
    "volumes": [
      {
        "target": { "filesystem": "/dev/vda2" },
        "mount": { "path": "/boot/efi" },
      },
      {
        "target": "default",
        "mount": { "path": "/" },
        "filesystem": "btrfs",
        "size": "10 GiB"
      },
      {
        "target": "default",
        "mount": "swap",
        "filesystem": "swap",
        "size": "auto"
      }
    ]
  }
}

When defining the new storage settings it was decided to include the guided key, which contains the current proposal settings that Agama is able to manage. Now Agama is going to start supporting the new settings, so the need of having a guided section is going to be reevaluated.

Problems with the guided section

Offering both the storage settings and a guided section presents some trouble:

  • The guided section could indicate some settings that conflicts with the rest of settings.
  • The precedence between guided settings and the rest of settings has to be defined.
  • Having 2 different ways for defining equivalent scenarios could be confusing for users.

Nevertheless, the guided section offers some features that are not supported by the new settings yet.

Let's describe two possible alternatives to overcome those problems.

Option 1: Only offer an extended storage settings

"storage": {
  "boot": {
    "configure": true,
    "device": "/dev/vdb"
  },
  "encrypt": {
    "method": "luks2",
    "key": "notsecret",
    "pbkd": "argon2i"
  },
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": [
        { "search": "all", "resize": "onDemand" }
      ]
    }
  ],
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] },
      "logicalVolumes": ["default"]
    }
  ]
}

Option 2: Offer either the extended storage settings or the guided settings

  • Extend the storage settings to support the missing guided features (like option 1).
  • The storage settings cannot be used if guided is used.
"storage": {
  "drives": [

  ],
  "volumeGroups": [

  ]
}
"storage": {
  "guided": {

  }
}

Extending the storage settings

Missing guided features:

  • Feature 1: Create a LVM volume group without indicating specific partitions but only the candidate devices in which to create the physical volumes.
  • Feature 2: Automatically create the default volumes defined by the product (e.g., root, home, swap).
  • Feature 3: Automatically complete the given volumes with the mandatory volumes defined by the product (e.g., root and swap).
  • Feature 4: Define how to find free space in the used devices.
  • Feature 5: Define encryption settings for all the new created partitions.
  • Feature 6: Automatically create or reuse the boot partition.

The following guided settings contains all the features that cannot be expressed by the rest of the settings yet:

"storage": {
  "guided": {
    "target": { "newLvmVg": ["/dev/vda"] },
    "space": { "policy": "resize" },
    "encryption": { "password": "notsecret" },
    "boot": {
      "configure": true,
      "device": "/dev/vdb"
    },
    "volumes": []
  }
}

Feature 1: Create a LVM volume group over candidate devices

Solution: making the physicalVolumes key to accept TargetDevices schema:

VolumeGroup
  search: [<Search>]
  alias [<string>]
  name [<string>]
  peSize [<number>]
  physicalVolumes [<string[]|Search|TargetDevices>]
  logicalVolumes [<LogicalVolume[]>]
  delete [<boolean=false>]

TargetDevices
  target: <string[]>

For example:

"storage": {
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] }
    }
  ]
}

Feature 2: Automatically create the default volumes

Solution: adding a default volumes shortcut to partitions and logicalVolumes. It automatically adds the default volumes defined by the product (e.g., /, swap and /home).

Drive
  search: [<Search>]
  alias [<string>]
  encrypt [<EncryptAction>]
  format [<FormatAction>]
  mount [<MountAction>]
  ptableType [<string>]
  partitions [<Partition[]|"default">]

VolumeGroup
  search: [<Search>]
  alias [<string>]
  name [<string>]
  peSize [<number>]
  physicalVolumes [<<string|Search>[]>]
  logicalVolumes [<LogicalVolume[]|"default">]
  delete [<boolean=false>]

For example:

"storage": {
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] },
      "logicalVolumes": ["default"]
    }
  ]
}

Defining other volumes manually is still possible:

"storage": {
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] },
      "logicalVolumes": [
        "default",
        {
          "mount": { "path": "/" },
          "size": "10 GiB"
        }
      ]
    }
  ]
}

Note that the root volume only indicates its size. The rest of attributes are inferred from the product.

Feature 3: Automatically create the mandatory volumes

Solution: adding a mandatory volumes shortcut to partitions and logicalVolumes. It automatically adds the mandatory volumes defined by the product (e.g., / and swap).

Drive
  search: [<Search>]
  alias [<string>]
  encrypt [<EncryptAction>]
  format [<FormatAction>]
  mount [<MountAction>]
  ptableType [<string>]
  partitions [<Partition[]|"default"|"mandatory">]

VolumeGroup
  search: [<Search>]
  alias [<string>]
  name [<string>]
  peSize [<number>]
  physicalVolumes [<<string|Search>[]>]
  logicalVolumes [<LogicalVolume[]|"default"|"mandatory">]
  delete [<boolean=false>]

For example:

"storage": {
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] },
      "logicalVolumes": ["mandatory"]
    }
  ]
}

Definining more volumes is also possible, similarly to defaults.

Feature 4: Define how to make free space in the used devices

Solution:

  • For custom policy, adding the resize key and extending the delete key.
  • For delete and resize policies, using a space section similar to the section from guided.
Partition
  search [Search]
  alias [<string>]
  id [<string>]
  type [<string>]
  size [<Size>]
  encrypt [EncryptAction]
  format [<FormatAction>]
  mount [<MountAction>]
  delete [<boolean=false|"onDemand">]
  resize [<Size|"onDemand">]

LogicalVolume
  search [<Search>]
  alias [<string>]
  name [<string>]
  size [<Size>]
  pool [<boolean>]
  used_pool [<string>]
  stripes [<number>]
  strip_size [<number>]
  encrypt [<EncryptAction>]
  format [<FormatAction>]
  mount [<MountAction>]
  delete [<boolean=false|"onDemand">]
  resize [<Size|"onDemand">]

For example:

"storage": {
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": [
        { "search": "all", "resize": "onDemand" }
      ]
    }
  ],
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] },
      "logicalVolumes": ["default"]
    }
  ]
}

It allows combining both resize or delete on demand:

"storage": {
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": [
        { "search": "all", "resize": "onDemand", "delete": "onDemand" }
      ]
    }
  ]
}

If making space is needed, then Agama will start resizing partitions. If that is not enough, then it will delete as much partitions as needed.

And for general policies:

"storage": {
  "space": "resize",
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": ["default"]
    }
  ]
}

Feature 5: Define encryption settings for new partitions

Solution: add a generic encrypt section. All new partitions will be encrypted by default.

"storage": {
  "encrypt": {
    "method": "luks2",
    "key": "notsecret",
    "pbkd": "argon2i"
  },
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": [
        { "search": "all", "resize": "onDemand" },
        "default"
      ]
    }
  ]
}

Feature 6: Automatically create or reuse the boot partition

Solution: add a generic boot section.

"storage": {
  "boot": {
    "configure": true,
    "device": "/dev/vdb"
  },
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": [
        { "search": "all", "resize": "onDemand" }
      ]
    }
  ],
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] },
      "logicalVolumes": ["default"]
    }
  ]
}

If a boot volume is manually defined, then the boot section is ignored:

"storage": {
  "boot": {
    "configure": true,
    "device": "/dev/vdb"
  },
  "drives": [
    {
      "search": { "name": "/dev/vda" },
      "partitions": [
        { "search": "all", "resize": "onDemand" },
        {
          "mount": { "path": "/boot/efi" },
          "size": "500 MiB",
          "filesystem": "fat"
        }
      ]
    }
  ],
  "volumeGroups": [
    {
      "physicalVolumes": { "target": ["/dev/vda"] },
      "logicalVolumes": ["default"]
    }
  ]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment