Skip to content

Commit

Permalink
Remove all existing partitions if any do not match
Browse files Browse the repository at this point in the history
[#75939098]

Signed-off-by: Maria Shaldibina <[email protected]>
  • Loading branch information
Adam Stegman authored and zaksoup committed Sep 9, 2014
1 parent 8dfb678 commit f69c0a4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 35 deletions.
51 changes: 32 additions & 19 deletions platform/disk/root_device_partitioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,31 @@ type existingPartition struct {
func (p rootDevicePartitioner) Partition(devicePath string, partitions []Partition) error {
existingPartitions, err := p.getPartitions(devicePath)
if err != nil {
return bosherr.WrapError(err, "Partitioning disk `%s'", devicePath)
return bosherr.WrapError(err, "Getting existing partitions of `%s'", devicePath)
}
p.logger.Debug(p.logTag, "Current partitions: %#v", existingPartitions)

if len(existingPartitions) == 0 {
return bosherr.New("Missing first partition on `%s'", devicePath)
}

if p.partitionsMatch(existingPartitions[1:], partitions) {
p.logger.Info(p.logTag, "Partitions already match, skipping partitioning")
return nil
}

partitionStart := existingPartitions[0].EndInBytes + 1

if len(existingPartitions) > 1 {
err = p.removePartitions(devicePath, existingPartitions[1:])
if err != nil {
return bosherr.WrapError(err, "Removing partitions from `%s'", devicePath)
}
}

for index, partition := range partitions {
partitionEnd := partitionStart + partition.SizeInBytes - 1

if len(existingPartitions) > index+1 {
existingPartition := existingPartitions[index+1]

if withinDelta(partition.SizeInBytes, existingPartition.SizeInBytes, p.deltaInBytes) {
partitionStart = existingPartition.EndInBytes + 1
p.logger.Info(p.logTag, "Skipping partition %d because it already exists", index)
continue
} else {
err = p.removePartitions(devicePath, existingPartitions[index+1:])
if err != nil {
return bosherr.WrapError(err, "Partitioning disk `%s'", devicePath)
}
existingPartitions = existingPartitions[:index+1]
}
}

p.logger.Info(p.logTag, "Creating partition %d with start %d and end %d", index, partitionStart, partitionEnd)

_, _, _, err := p.cmdRunner.RunCommand(
Expand Down Expand Up @@ -123,7 +120,7 @@ func (p rootDevicePartitioner) getPartitions(devicePath string) ([]existingParti

stdout, _, _, err := p.cmdRunner.RunCommand("parted", "-m", devicePath, "unit", "B", "print")
if err != nil {
return partitions, bosherr.WrapError(err, "Getting existing partitions of `%s'", devicePath)
return partitions, bosherr.WrapError(err, "Running parted print on `%s'", devicePath)
}

p.logger.Debug(p.logTag, "Found partitions %s", stdout)
Expand Down Expand Up @@ -178,9 +175,25 @@ func (p rootDevicePartitioner) removePartitions(devicePath string, partitions []
_, _, _, err := p.cmdRunner.RunCommand("parted", "-s", devicePath, "rm", fmt.Sprintf("%d", partition.Index))

if err != nil {
return bosherr.WrapError(err, "Removing partition from `%s'", devicePath)
return bosherr.WrapError(err, "Removing partition %d from `%s'", partition.Index, devicePath)
}
}

return nil
}

func (p rootDevicePartitioner) partitionsMatch(existingPartitions []existingPartition, partitions []Partition) bool {
if len(existingPartitions) != len(partitions) {
return false
}

for index, partition := range partitions {
existingPartition := existingPartitions[index]

if !withinDelta(partition.SizeInBytes, existingPartition.SizeInBytes, p.deltaInBytes) {
return false
}
}

return true
}
40 changes: 24 additions & 16 deletions platform/disk/root_device_partitioner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ var _ = Describe("rootDevicePartitioner", func() {

err := partitioner.Partition("/dev/sda", partitions)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("Partitioning disk `/dev/sda'"))
Expect(err.Error()).To(ContainSubstring("Getting existing partitions of `/dev/sda'"))
Expect(err.Error()).To(ContainSubstring("Running parted print on `/dev/sda'"))
Expect(err.Error()).To(ContainSubstring("fake-parted-error"))
})
})
Expand Down Expand Up @@ -127,13 +127,17 @@ var _ = Describe("rootDevicePartitioner", func() {
/dev/sda:128B:virtblk:512:512:msdos:Virtio Block Device;
1:1B:31B:31B:ext4::;
2:32B:64B:33B:ext4::;
3:65B:125B:61B:ext4::;
`,
},
)
})

It("does not partition", func() {
partitions := []Partition{{SizeInBytes: 32}}
partitions := []Partition{
{SizeInBytes: 32},
{SizeInBytes: 62},
}

err := partitioner.Partition("/dev/sda", partitions)
Expect(err).ToNot(HaveOccurred())
Expand All @@ -159,7 +163,7 @@ var _ = Describe("rootDevicePartitioner", func() {
)
})

It("recreates partitions starting from middle partition", func() {
It("recreates partitions", func() {
partitions := []Partition{
{SizeInBytes: 16},
{SizeInBytes: 16},
Expand All @@ -168,21 +172,25 @@ var _ = Describe("rootDevicePartitioner", func() {

err := partitioner.Partition("/dev/sda", partitions)
Expect(err).ToNot(HaveOccurred())
Expect(len(fakeCmdRunner.RunCommands)).To(Equal(6))
Expect(fakeCmdRunner.RunCommands[0]).To(Equal([]string{"parted", "-m", "/dev/sda", "unit", "B", "print"}))

Expect(fakeCmdRunner.RunCommands[1]).To(Equal([]string{"parted", "-s", "/dev/sda", "rm", "3"}))
Expect(fakeCmdRunner.RunCommands[2]).To(Equal([]string{"parted", "-s", "/dev/sda", "rm", "4"}))
Expect(fakeCmdRunner.RunCommands[3]).To(Equal([]string{"parted", "-s", "/dev/sda", "rm", "5"}))

Expect(fakeCmdRunner.RunCommands[4]).To(Equal([]string{"parted", "-s", "/dev/sda", "unit", "B", "mkpart", "primary", "48", "63"}))
Expect(fakeCmdRunner.RunCommands[5]).To(Equal([]string{"parted", "-s", "/dev/sda", "unit", "B", "mkpart", "primary", "64", "95"}))
Expect(len(fakeCmdRunner.RunCommands)).To(Equal(8))
Expect(fakeCmdRunner.RunCommands).To(Equal([][]string{
{"parted", "-m", "/dev/sda", "unit", "B", "print"},

{"parted", "-s", "/dev/sda", "rm", "2"},
{"parted", "-s", "/dev/sda", "rm", "3"},
{"parted", "-s", "/dev/sda", "rm", "4"},
{"parted", "-s", "/dev/sda", "rm", "5"},

{"parted", "-s", "/dev/sda", "unit", "B", "mkpart", "primary", "33", "48"},
{"parted", "-s", "/dev/sda", "unit", "B", "mkpart", "primary", "49", "64"},
{"parted", "-s", "/dev/sda", "unit", "B", "mkpart", "primary", "65", "96"},
}))
})

Context("when removing existing partition fails", func() {
BeforeEach(func() {
fakeCmdRunner.AddCmdResult(
"parted -s /dev/sda rm 3",
"parted -s /dev/sda rm 2",
fakesys.FakeCmdResult{Error: errors.New("fake-parted-error")},
)
})
Expand All @@ -196,12 +204,12 @@ var _ = Describe("rootDevicePartitioner", func() {

err := partitioner.Partition("/dev/sda", partitions)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("Removing partition from `/dev/sda'"))
Expect(err.Error()).To(ContainSubstring("Partitioning disk `/dev/sda'"))
Expect(err.Error()).To(ContainSubstring("Removing partition 2 from `/dev/sda'"))
Expect(err.Error()).To(ContainSubstring("Removing partitions from `/dev/sda'"))
Expect(len(fakeCmdRunner.RunCommands)).To(Equal(2))
Expect(fakeCmdRunner.RunCommands[0]).To(Equal([]string{"parted", "-m", "/dev/sda", "unit", "B", "print"}))

Expect(fakeCmdRunner.RunCommands[1]).To(Equal([]string{"parted", "-s", "/dev/sda", "rm", "3"}))
Expect(fakeCmdRunner.RunCommands[1]).To(Equal([]string{"parted", "-s", "/dev/sda", "rm", "2"}))
})
})
})
Expand Down

0 comments on commit f69c0a4

Please sign in to comment.