-
Notifications
You must be signed in to change notification settings - Fork 241
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
disk: call sfdisk directly to expand partition
growpart is a shell script, and we don't have shell now in our image. Fixes: af7a885
- Loading branch information
Showing
7 changed files
with
145 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package sfdisk | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"os/exec" | ||
|
||
utilsos "github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/utils/os" | ||
|
||
"golang.org/x/sys/unix" | ||
"k8s.io/klog/v2" | ||
) | ||
|
||
func ExpandPartition(ctx context.Context, disk, partition string) error { | ||
logger := klog.FromContext(ctx) | ||
fd, err := unix.Open(disk, unix.O_RDONLY, 0) | ||
if err != nil { | ||
return err | ||
} | ||
defer func() { | ||
if err := unix.Close(fd); err != nil { | ||
logger.Error(err, "failed to close", "fd", fd) | ||
} | ||
}() | ||
|
||
err = unix.Flock(fd, unix.LOCK_EX) // as suggested in the man sfdisk(8) | ||
if err != nil { | ||
return fmt.Errorf("failed to lock %s exclusively: %v", disk, err) | ||
} | ||
defer func() { | ||
if err := unix.Flock(fd, unix.LOCK_UN); err != nil { | ||
logger.Error(err, "failed to unlock", "fd", fd) | ||
} | ||
}() | ||
|
||
dump, err := exec.CommandContext(ctx, "sfdisk", "--dump", disk).Output() | ||
if err != nil { | ||
return fmt.Errorf("failed to dump current partition table of %s: %v", disk, utilsos.ErrWithStderr(err)) | ||
} | ||
dumpStr := string(dump) | ||
logger.V(4).Info("sfdisk dump before expansion", "dump", dumpStr) | ||
|
||
// Don't cancel this, we don't want to corrupt the partition table | ||
cmd := exec.Command("sfdisk", disk, "-N", partition) | ||
cmd.Stdin = bytes.NewReader([]byte(",+")) // enlarge the partition as much as possible | ||
result, err := cmd.Output() | ||
if err != nil { | ||
return fmt.Errorf("failed to expand partition %s on %s: %v\noriginal table looked like:\n%s", partition, disk, utilsos.ErrWithStderr(err), dumpStr) | ||
} | ||
logger.V(3).Info("sfdisk success", "output", string(result)) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package sfdisk | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"errors" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
"testing" | ||
|
||
utilsos "github.com/kubernetes-sigs/alibaba-cloud-csi-driver/pkg/utils/os" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestExpandPartition(t *testing.T) { | ||
path, err := exec.LookPath("sfdisk") | ||
if errors.Is(err, exec.ErrNotFound) { | ||
t.Skip("sfdisk not found") | ||
} | ||
assert.NoError(t, err) | ||
t.Logf("sfdisk found at: %s", path) | ||
|
||
testImage := t.TempDir() + "/test.img" | ||
_, err = os.Create(testImage) | ||
assert.NoError(t, err) | ||
assert.NoError(t, os.Truncate(testImage, 1<<23)) // 8MB | ||
|
||
cmd := exec.Command("sfdisk", testImage) | ||
cmd.Stdin = bytes.NewReader([]byte("label: gpt\n,\n")) // create a single partition | ||
result, err := cmd.Output() | ||
assert.NoError(t, utilsos.ErrWithStderr(err)) | ||
t.Logf("create partition success: %s", string(result)) | ||
|
||
assert.NoError(t, os.Truncate(testImage, 1<<24)) // expand to 16MB | ||
assert.NoError(t, ExpandPartition(context.Background(), testImage, "1")) | ||
|
||
dump, err := exec.Command("sfdisk", "--dump", testImage).Output() | ||
assert.NoError(t, utilsos.ErrWithStderr(err)) | ||
assert.Contains(t, strings.ReplaceAll(string(dump), " ", ""), "test.img1:start=2048,size=30687") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package os | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"os/exec" | ||
) | ||
|
||
type ExitErrorWithStderr struct { | ||
*exec.ExitError | ||
} | ||
|
||
func (err ExitErrorWithStderr) Error() string { | ||
return err.ExitError.Error() + ", with stderr: " + string(bytes.TrimSpace(err.Stderr)) | ||
} | ||
|
||
func ErrWithStderr(err error) error { | ||
var exitErr *exec.ExitError | ||
if errors.As(err, &exitErr) && len(exitErr.Stderr) > 0 { | ||
return ExitErrorWithStderr{exitErr} | ||
} | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package os | ||
|
||
import ( | ||
"os/exec" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestErrWithStderr(t *testing.T) { | ||
_, err := exec.Command("sh", "-c", "echo 'test error' 1>&2; exit 2").Output() | ||
assert.Error(t, err) | ||
assert.EqualError(t, ErrWithStderr(err), "exit status 2, with stderr: test error") | ||
} | ||
|
||
func TestErrWithStderrNoChange(t *testing.T) { | ||
err := exec.ErrNotFound | ||
assert.Equal(t, ErrWithStderr(err), err) | ||
} |