diff --git a/README.md b/README.md index 8ea3007..60d3038 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,9 @@ This set of commands is implemented and tested to some extent. The tested featur | lvs | Alpha | Basic | | | vgcreate | Alpha | Basic | | | vgremove | Alpha | Basic | | +| vgextend | Alpha | Basic | | +| vgreduce | Alpha | Basic | | +| vgchange | Alpha | Basic | | | vgrename | Alpha | Basic | | | vgs | Alpha | Basic | | | pvs | Alpha | Basic | | diff --git a/args.go b/args.go index 1e7e7c5..5df78f9 100644 --- a/args.go +++ b/args.go @@ -25,18 +25,18 @@ type args struct { typ ArgsType } -type ArgsType string +type ArgsType int8 const ( - ArgsTypeGeneric ArgsType = "generic" - ArgsTypeLVs ArgsType = "lvs" - ArgsTypePVs ArgsType = "pvs" - ArgsTypeVGs ArgsType = "vgs" - ArgsTypeLVCreate ArgsType = "lvcreate" - ArgsTypeLVChange ArgsType = "lvchange" - ArgsTypeVGCreate ArgsType = "vgcreate" - ArgsTypeVGChange ArgsType = "vgchange" - ArgsTypeLVRename ArgsType = "lvrename" + ArgsTypeGeneric ArgsType = iota + ArgsTypeLVs ArgsType = iota + ArgsTypePVs ArgsType = iota + ArgsTypeVGs ArgsType = iota + ArgsTypeLVCreate ArgsType = iota + ArgsTypeLVChange ArgsType = iota + ArgsTypeVGCreate ArgsType = iota + ArgsTypeVGChange ArgsType = iota + ArgsTypeLVRename ArgsType = iota ) func NewArgs(typ ArgsType) Arguments { diff --git a/physical_volume.go b/physical_volume.go index 026e53e..29ee445 100644 --- a/physical_volume.go +++ b/physical_volume.go @@ -97,9 +97,18 @@ func (opt PhysicalVolumeName) ApplyToVGCreateOptions(opts *VGCreateOptions) { func (opt PhysicalVolumeName) ApplyToVGExtendOptions(opts *VGExtendOptions) { opts.PhysicalVolumeNames = append(opts.PhysicalVolumeNames, opt) } +func (opt PhysicalVolumeName) ApplyToVGReduceOptions(opts *VGReduceOptions) { + opts.PhysicalVolumeNames = append(opts.PhysicalVolumeNames, opt) +} type PhysicalVolumeNames []PhysicalVolumeName +func (opt PhysicalVolumeNames) ApplyToVGReduceOptions(opts *VGReduceOptions) { + for _, name := range opt { + name.ApplyToVGReduceOptions(opts) + } +} + func (opt PhysicalVolumeNames) ApplyToVGExtendOptions(opts *VGExtendOptions) { for _, name := range opt { name.ApplyToVGExtendOptions(opts) diff --git a/remove_missing.go b/remove_missing.go new file mode 100644 index 0000000..bbda60d --- /dev/null +++ b/remove_missing.go @@ -0,0 +1,17 @@ +package lvm2go + +import "fmt" + +type RemoveMissing VolumeGroupName + +func (opt RemoveMissing) ApplyToArgs(args Arguments) error { + if opt == "" { + return nil + } + args.AddOrReplace(fmt.Sprintf("--removemissing=%s", opt)) + return nil +} + +func (opt RemoveMissing) ApplyToVGReduceOptions(opts *VGReduceOptions) { + opts.RemoveMissing = opt +} diff --git a/vgextend_test.go b/vgextend_test.go index 8ce543b..232e068 100644 --- a/vgextend_test.go +++ b/vgextend_test.go @@ -45,4 +45,17 @@ func TestVGExtend(t *testing.T) { t.Fatalf("expected 3 physical volumes, got %d", vg.PvCount) } + if err := clnt.VGReduce(ctx, infra.volumeGroup.Name, addedDevices.PhysicalVolumeNames()); err != nil { + t.Fatal(err) + } + + vg, err = clnt.VG(ctx, infra.volumeGroup.Name) + if err != nil { + t.Fatal(err) + } + + if vg.PvCount != 1 { + t.Fatalf("expected 3 physical volumes, got %d", vg.PvCount) + } + } diff --git a/vgreduce.go b/vgreduce.go index 6087687..4d77f91 100644 --- a/vgreduce.go +++ b/vgreduce.go @@ -2,13 +2,15 @@ package lvm2go import ( "context" - "errors" "fmt" ) type ( VGReduceOptions struct { VolumeGroupName + PhysicalVolumeNames + RemoveMissing + Force CommonOptions } VGReduceOption interface { @@ -32,9 +34,41 @@ func (c *client) VGReduce(ctx context.Context, opts ...VGReduceOption) error { } func (list VGReduceOptionsList) AsArgs() (Arguments, error) { - return nil, fmt.Errorf("not implemented: %w", errors.ErrUnsupported) + args := NewArgs(ArgsTypeGeneric) + options := VGReduceOptions{} + for _, opt := range list { + opt.ApplyToVGReduceOptions(&options) + } + if err := options.ApplyToArgs(args); err != nil { + return nil, err + } + return args, nil } func (opts *VGReduceOptions) ApplyToArgs(args Arguments) error { - return fmt.Errorf("not implemented: %w", errors.ErrUnsupported) + if opts.VolumeGroupName == "" { + return fmt.Errorf("VolumeGroupName is required for extension of a volume group") + } + + if len(opts.PhysicalVolumeNames) == 0 { + return fmt.Errorf("at least one PhysicalVolumeName is required for extension of a volume group") + } + + for _, arg := range []Argument{ + opts.VolumeGroupName, + opts.PhysicalVolumeNames, + opts.RemoveMissing, + opts.Force, + opts.CommonOptions, + } { + if err := arg.ApplyToArgs(args); err != nil { + return err + } + } + + return nil +} + +func (opts *VGReduceOptions) ApplyToVGReduceOptions(new *VGReduceOptions) { + *new = *opts } diff --git a/volume_group.go b/volume_group.go index bfc2fe7..aefa825 100644 --- a/volume_group.go +++ b/volume_group.go @@ -127,6 +127,9 @@ func (opt VolumeGroupName) ApplyToVGRenameOptions(opts *VGRenameOptions) { func (opt VolumeGroupName) ApplyToVGChangeOptions(opts *VGChangeOptions) { opts.VolumeGroupName = opt } +func (opt VolumeGroupName) ApplyToVGReduceOptions(opts *VGReduceOptions) { + opts.VolumeGroupName = opt +} func (opt VolumeGroupName) ApplyToLVRemoveOptions(opts *LVRemoveOptions) { opts.VolumeGroupName = opt }