mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
fix(hostman): use losetup --json to match device (#21276)
This commit is contained in:
@@ -67,19 +67,12 @@ func parseDevice(line string) (Device, error) {
|
||||
if len(fields) == 0 {
|
||||
return Device{}, fmt.Errorf("Invalid line: %q", line)
|
||||
}
|
||||
sizeLimit := false
|
||||
ro := false
|
||||
if fields[2] != "0" {
|
||||
sizeLimit = true
|
||||
}
|
||||
if fields[3] != "0" {
|
||||
ro = true
|
||||
if len(fields) < 2 {
|
||||
return Device{}, fmt.Errorf("Invalid line: %q", line)
|
||||
}
|
||||
return Device{
|
||||
Name: fields[0],
|
||||
BackFile: fields[1],
|
||||
SizeLimit: sizeLimit,
|
||||
ReadOnly: ro,
|
||||
Name: fields[0],
|
||||
BackFile: strings.Join(fields[1:], " "),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ import (
|
||||
|
||||
var (
|
||||
losetupOutput string = `
|
||||
NAME BACK-FILE SIZELIMIT RO
|
||||
/dev/loop0 /disks/2b917686-2ace-4a57-a4af-44ece2303dd2 0 0
|
||||
/dev/loop1 /disks/033d6bc0-4ce4-48c4-89d3-125077bcc28e 0 1
|
||||
NAME BACK-FILE
|
||||
/dev/loop0 /disks/2b917686-2ace-4a57-a4af-44ece2303dd2 (deleted)
|
||||
/dev/loop1 /disks/033d6bc0-4ce4-48c4-89d3-125077bcc28e
|
||||
`
|
||||
)
|
||||
|
||||
@@ -42,17 +42,13 @@ func Test_parseDevices(t *testing.T) {
|
||||
args: args{losetupOutput},
|
||||
want: &Devices{
|
||||
[]Device{
|
||||
Device{
|
||||
Name: "/dev/loop0",
|
||||
BackFile: "/disks/2b917686-2ace-4a57-a4af-44ece2303dd2",
|
||||
SizeLimit: false,
|
||||
ReadOnly: false,
|
||||
{
|
||||
Name: "/dev/loop0",
|
||||
BackFile: "/disks/2b917686-2ace-4a57-a4af-44ece2303dd2 (deleted)",
|
||||
},
|
||||
Device{
|
||||
Name: "/dev/loop1",
|
||||
BackFile: "/disks/033d6bc0-4ce4-48c4-89d3-125077bcc28e",
|
||||
SizeLimit: false,
|
||||
ReadOnly: true,
|
||||
{
|
||||
Name: "/dev/loop1",
|
||||
BackFile: "/disks/033d6bc0-4ce4-48c4-89d3-125077bcc28e",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -72,8 +72,37 @@ func NewLosetupCommand() *LosetupCommand {
|
||||
}
|
||||
}
|
||||
|
||||
func parseJsonOutput(content string) (*Devices, error) {
|
||||
obj, err := jsonutils.ParseString(content)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "parse json: %s", content)
|
||||
}
|
||||
devs := new(Devices)
|
||||
if err := obj.Unmarshal(devs); err != nil {
|
||||
return nil, errors.Wrapf(err, "unmarshal json: %s", content)
|
||||
}
|
||||
return devs, nil
|
||||
}
|
||||
|
||||
func ListDevices() (*Devices, error) {
|
||||
cmd, err := NewLosetupCommand().AddArgs("-l", "-O", "NAME,BACK-FILE,SIZELIMIT,RO").Run()
|
||||
cmd, err := NewLosetupCommand().AddArgs("--json").Run()
|
||||
errs := make([]error, 0)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrap(err, "list by json"))
|
||||
devs, err2 := listDevicesOldVersion()
|
||||
if err2 != nil {
|
||||
errs = append(errs, errors.Wrap(err, "list by using old way"))
|
||||
} else {
|
||||
return devs, nil
|
||||
}
|
||||
return nil, errors.NewAggregate(errs)
|
||||
}
|
||||
output := cmd.Output()
|
||||
return parseJsonOutput(output)
|
||||
}
|
||||
|
||||
func listDevicesOldVersion() (*Devices, error) {
|
||||
cmd, err := NewLosetupCommand().AddArgs("-l", "-O", "NAME,BACK-FILE").Run()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -156,13 +185,13 @@ func DetachDevice(devPath string) error {
|
||||
return errors.Wrapf(err, "detach device")
|
||||
}
|
||||
// recheck
|
||||
dev, err = getDev()
|
||||
/*dev, err = getDev()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "get device by %s for rechecking", devPath)
|
||||
}
|
||||
if dev != nil {
|
||||
return errors.Errorf("device %s still exists, %s", devPath, jsonutils.Marshal(dev))
|
||||
}
|
||||
}*/
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package losetup
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_parseJsonOutput(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
content string
|
||||
want *Devices
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "normal input",
|
||||
content: `{
|
||||
"loopdevices": [
|
||||
{
|
||||
"name": "/dev/loop1",
|
||||
"sizelimit": 0,
|
||||
"offset": 0,
|
||||
"autoclear": true,
|
||||
"ro": false,
|
||||
"back-file": "/opt/cloud/workspace/disks/recycle_bin/20240911160650/194767a9-556f-4072-8a20-7ab1086f22ff.1726070810",
|
||||
"dio": false,
|
||||
"log-sec": 512
|
||||
},{
|
||||
"name": "/dev/loop57",
|
||||
"sizelimit": 0,
|
||||
"offset": 0,
|
||||
"autoclear": false,
|
||||
"ro": false,
|
||||
"back-file": "/opt/cloud/workspace/disks/2c10325f-7109-4cf0-8a9f-4c3724920245 (deleted)",
|
||||
"dio": false,
|
||||
"log-sec": 512
|
||||
}]}`,
|
||||
want: &Devices{
|
||||
LoopDevs: []Device{
|
||||
{
|
||||
Name: "/dev/loop1",
|
||||
BackFile: "/opt/cloud/workspace/disks/recycle_bin/20240911160650/194767a9-556f-4072-8a20-7ab1086f22ff.1726070810",
|
||||
SizeLimit: false,
|
||||
ReadOnly: false,
|
||||
},
|
||||
{
|
||||
Name: "/dev/loop57",
|
||||
BackFile: "/opt/cloud/workspace/disks/2c10325f-7109-4cf0-8a9f-4c3724920245 (deleted)",
|
||||
SizeLimit: false,
|
||||
ReadOnly: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := parseJsonOutput(tt.content)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("parseJsonOutput() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("parseJsonOutput() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user