Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image_partition: add ability to skip "start" and specify relative offsets #285

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

thanhtunng
Copy link

Currently start and end value must be specified explicitly

We can ignore start value unless required by using the end of
previous partition.

The size of partition can also be easier to see if using
end value as relative offset (e.g: +10Mib, +5%). However,
the type of end value must be the same as start's

Example:

- action: image-partition
  imagename: "debian-rpi3.img"
  imagesize: 1GB
  partitiontype: msdos
  mountpoints:
    - mountpoint: /
      partition: root
    - mountpoint: /boot/firmware
      partition: firmware
      options: [ x-systemd.automount ]
  partitions:
    - name: firmware
      fs: vfat
      end: +5%
    - name: root
      fs: ext4
      start: 64MB
      end: +256MB
      flags: [ boot ]

firmware partition - start: 0% (as default), end: 5%
root partition - start: 64MB. end: 320MB

@sangorrin
Copy link
Contributor

Hi,

Just to make sure, this is not an essential feature for us.
I just thought the interface would be more user-friendly if we used relative offsets.
Perhaps there are other users interested.

Thanks,
Daniel

@evelikov
Copy link

evelikov commented Oct 26, 2021

@thanhtunng @sangorrin thanks for the neat feature - was looking to have start optional.

The MR does 3 things (see below) yet it's a single commit - do you mind splitting it up? Mind you I don't have commit access to the repo, so this is just a humble request. Thanks o/

  • makes start optional
  • adds basic validation for start and end
  • adds relative offset support for end

Vu Thanh Tung added 3 commits October 27, 2021 23:11
We can ignore start value unless required by using the end of
previous partition.

Signed-off-by: Vu Thanh Tung <tung1.vuthanh@toshiba.co.jp>
The size of partition can also be easier to see if using
end value as relative offset (e.g: +10Mib, +5%).
However, the type of end value must be the same as starts.

Signed-off-by: Vu Thanh Tung <tung1.vuthanh@toshiba.co.jp>
Signed-off-by: Vu Thanh Tung <tung1.vuthanh@toshiba.co.jp>
@thanhtunng
Copy link
Author

@evelikov thanks for your suggestion, i changed follows yours. Please let me know if you need any improvements.

@evelikov
Copy link

Looks great thank you.

In case I was ambiguous earlier - I cannot merge this MR. since I do not have commit access.

@evelikov
Copy link

Tested the MR and it seems kind of broken. So it needs extra work until it's in good state.

Example:

architecture: amd64

actions:
  - action: image-partition
    imagename: disk.img
    imagesize: 2G
    partitiontype: gpt
    partitions:
      - name: rootfs
        fs: ext4
        end: +512Mi
      - name: home
        fs: ext4
        end: 100%
    mountpoints:
      - mountpoint: /
        partition: rootfs
      - mountpoint: /home
        partition: home

Issues:

  • rootfs start/end unit mismatch - trivial fix, ignore unit when startval == 0
  • creating the home partition outright fails
$ parted -a none -s -- /dev/disk/by-fakemachine-label/fakedisk-0 mkpart home ext4 512Mi 100%
Error: You requested a partition from 537MB to 2000MB (sectors 1048576..3906249)
The closest location we can manage is 537MB to 2000MB (sectors 1048577..3906216)

case l >= 'A' && l <= 'Z', l >= 'a' && l <= 'z', l == '%':
t = append(t, l)
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop here allows for arbitrary alpha-numeric word soup. For example "A01Z99%" is considered sane by the above.
Let's use a regex akin to the one in #292.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thanhtunng Any update?


func CalculateOffset(start, end string) (string, error) {
/* Do addition if end value uses a '+' prefix */
if strings.HasPrefix(end, "+") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I would move the "HasPrefix" check in the caller.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

@thanhtunng
Copy link
Author

thanhtunng commented Jan 23, 2022

rootfs start/end unit mismatch - trivial fix, ignore unit when startval == 0

@evelikov Yeah the mismatch issue I already mentioned in commit message, anw the case startval ==0 I didnt think about, thanks~

$ parted -a none -s -- /dev/disk/by-fakemachine-label/fakedisk-0 mkpart home ext4 512Mi 100%
Error: You requested a partition from 537MB to 2000MB (sectors 1048576..3906249)
The closest location we can manage is 537MB to 2000MB (sectors 1048577..3906216)

MiB? Furthermore not sure able to use "MiB" unit unless #292 is merged

@evelikov
Copy link

evelikov commented Mar 5, 2022

You might be conflating things:
Mi/MiB handling with partitions just works in the master branch, since the raw data from the yaml is passed to directly into parted as seen in the example above. This MR breaks that functionality and I think you should look into why.

The code in #292 covers the imagesize, which is a completely orthogonal thing.

@obbardc
Copy link
Member

obbardc commented Oct 12, 2022

@thanhtunng Do you have an update about this?

@obbardc obbardc added this to the v1.1.2 milestone Oct 12, 2022
@evelikov
Copy link

evelikov commented Jan 9, 2023

@obbardc I'm keen on pushing this forward. Is there any particular changes you'd like to see (aka anything more than what I've raised already)? I'm thinking about adding some tests to the CI - the snippet above + another one with explicit start and other units.

Any pointers how to properly fix the parted error mentioned before - #285 (comment). It seems like we're either hitting a parted bug or an off-by-one error in debos.

@obbardc
Copy link
Member

obbardc commented Jan 9, 2023

Proper in-depth automated tests for both relative & non-relative cases would be great with various line endings etc. I was thinking something along the lines of manually creating a partition table and comparing that at runtime.

Happy to start small though ;-).

@obbardc
Copy link
Member

obbardc commented Jul 26, 2023

@thanhtunng @evelikov Any update here ? It'd be great to get this reworked.

@evelikov
Copy link

Nothing from me since debos maintainership has been MIA over the last 6 months or so. Will be quite busy in the upcoming 2-3 months so it's unlikely I'll have the time, sorry.

Copy link
Member

@obbardc obbardc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are missing some tests & fixing some nits. I'd be happy to merge once the above is complete.

@@ -80,6 +75,11 @@ GPT sets the partition type to Linux Swap.
For msdos partition types hex codes see: https://en.wikipedia.org/wiki/Partition_type
For gpt partition type GUIDs see: https://systemd.io/DISCOVERABLE_PARTITIONS/

- start -- offset from beginning of the disk there the partition starts.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to note why this is optional and what would happen if it isn't actually provided.

@@ -80,6 +75,11 @@ GPT sets the partition type to Linux Swap.
For msdos partition types hex codes see: https://en.wikipedia.org/wiki/Partition_type
For gpt partition type GUIDs see: https://systemd.io/DISCOVERABLE_PARTITIONS/

- start -- offset from beginning of the disk there the partition starts.

For 'start' and 'end' properties offset can be written in human readable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to duplicate this inline so that both start and end properties have this.

@@ -642,12 +643,14 @@ func (i *ImagePartitionAction) Verify(context *debos.DebosContext) error {
}

if p.Start == "" {
return fmt.Errorf("Partition %s missing start", p.Name)
p.Start = prevEnd
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to move this logic into the Run stage rather than Verify stage potentially with some comment about what is going on.

@@ -642,12 +643,14 @@ func (i *ImagePartitionAction) Verify(context *debos.DebosContext) error {
}

if p.Start == "" {
return fmt.Errorf("Partition %s missing start", p.Name)
p.Start = prevEnd
}
if p.End == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really should have a test case as well.

case l >= 'A' && l <= 'Z', l >= 'a' && l <= 'z', l == '%':
t = append(t, l)
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thanhtunng Any update?


func CalculateOffset(start, end string) (string, error) {
/* Do addition if end value uses a '+' prefix */
if strings.HasPrefix(end, "+") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree.

@@ -600,6 +646,7 @@ func (i *ImagePartitionAction) Verify(context *debos.DebosContext) error {
num := 1
prevEnd := "0%"
for idx, _ := range i.Partitions {
var err error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can remove this by having later on p.End, err := blah

@@ -649,6 +696,11 @@ func (i *ImagePartitionAction) Verify(context *debos.DebosContext) error {
return fmt.Errorf("Partition %s missing end", p.Name)
}

p.End, err = CalculateOffset(p.Start, p.End)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, check here if prefix is +

return err
}
if typ == "%" && val > 100 {
return fmt.Errorf("Size can not exceed 100%%")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: two %%

@obbardc obbardc modified the milestones: v1.1.2, v1.1.4 Jan 10, 2024
For 'start' and 'end' properties offset can be written in human readable
form -- '32MB', '1GB' or as disk percentage -- '100%'.
- end -- offset from beginning of the disk there the partition ends or
offset from beginning of where the partition starts specified with prefix "+"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather then having end be either end point on the disk or the size of the disk it would make more sense to have a seperate size property and require either end or size to be provided.

size should be in similar to the units parted accepts (https://www.gnu.org/software/parted/manual/html_node/unit.html) ideally; The image size parsing is mostly there, only % and s really sould be handled. I don't think anyone still cares about cylinders :).

same parsing should probably be use for start and end rather then the current state were we just pass on whatever the user gives to parted and hope :)..

That way it's both more clear for end-user, cleanup one of the debos oddities and more flexible then this implementation where there seems to be very specific requirements between the start and end value "types"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants