pattern => '([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}',
});
+register_standard_option('pve-output-format', {
+ type => 'string',
+ description => 'Output format.',
+ enum => [ 'text', 'json', 'json-pretty' ],
+ optional => 1,
+ default => 'text',
+});
+
my $format_list = {};
sub register_format {
return $format_list->{$format};
}
+my $renderer_hash = {};
+
+sub register_renderer {
+ my ($name, $code) = @_;
+
+ die "renderer '$name' already registered\n"
+ if $renderer_hash->{$name};
+
+ $renderer_hash->{$name} = $code;
+}
+
+sub get_renderer {
+ my ($name) = @_;
+ return $renderer_hash->{$name};
+}
+
# register some common type for pve
register_format('string', sub {}); # allow format => 'string-list'
sub pve_verify_cidrv6 {
my ($cidr, $noerr) = @_;
- if ($cidr =~ m!^(?:$IPV6RE)(?:/(\d+))$! && ($1 > 7) && ($1 <= 120)) {
+ if ($cidr =~ m!^(?:$IPV6RE)(?:/(\d+))$! && ($1 > 7) && ($1 <= 128)) {
return $cidr;
}
die "unable to parse startup options\n";
}
+my %bwlimit_opt = (
+ optional => 1,
+ type => 'number', minimum => '0',
+ format_description => 'LIMIT',
+);
+
+my $bwlimit_format = {
+ default => {
+ %bwlimit_opt,
+ description => 'default bandwidth limit in MiB/s',
+ },
+ restore => {
+ %bwlimit_opt,
+ description => 'bandwidth limit in MiB/s for restoring guests from backups',
+ },
+ migration => {
+ %bwlimit_opt,
+ description => 'bandwidth limit in MiB/s for migrating guests',
+ },
+ clone => {
+ %bwlimit_opt,
+ description => 'bandwidth limit in MiB/s for cloning disks',
+ },
+ move => {
+ %bwlimit_opt,
+ description => 'bandwidth limit in MiB/s for moving disks',
+ },
+};
+register_format('bwlimit', $bwlimit_format);
+register_standard_option('bwlimit', {
+ description => "Set bandwidth/io limits various operations.",
+ optional => 1,
+ type => 'string',
+ format => $bwlimit_format,
+});
+
sub pve_parse_startup_order {
my ($value) = @_;
optional => 1,
description => "This provides the title of the property",
},
+ renderer => {
+ type => "string",
+ optional => 1,
+ description => "This is used to provide rendering hints to format cli command output.",
+ },
requires => {
type => [ "string", "object" ],
optional => 1,
},
},
},
+ print_width => {
+ type => "integer",
+ description => "For CLI context, this defines the maximal width to print before truncating",
+ optional => 1,
+ },
}
};
# a way to parse command line parameters, using a
# schema to configure Getopt::Long
sub get_options {
- my ($schema, $args, $arg_param, $fixed_param, $pwcallback) = @_;
+ my ($schema, $args, $arg_param, $fixed_param, $param_mapping_hash) = @_;
if (!$schema || !$schema->{properties}) {
raise("too many arguments\n", code => HTTP_BAD_REQUEST)
$list_param = $arg_param;
}
+ my @interactive = ();
my @getopt = ();
foreach my $prop (keys %{$schema->{properties}}) {
my $pd = $schema->{properties}->{$prop};
next if $list_param && $prop eq $list_param;
next if defined($fixed_param->{$prop});
- if ($prop eq 'password' && $pwcallback) {
- # we do not accept plain password on input line, instead
- # we turn this into a boolean option and ask for password below
- # using $pwcallback() (for security reasons).
- push @getopt, "$prop";
+ my $mapping = $param_mapping_hash->{$prop};
+ if ($mapping && $mapping->{interactive}) {
+ # interactive parameters such as passwords: make the argument
+ # optional and call the mapping function afterwards.
+ push @getopt, "$prop:s";
+ push @interactive, [$prop, $mapping->{func}];
} elsif ($pd->{type} eq 'boolean') {
push @getopt, "$prop:s";
} else {
raise("too many arguments\n", code => HTTP_BAD_REQUEST)
if scalar(@$args) != 0;
}
+ } else {
+ if (ref($arg_param)) {
+ foreach my $arg_name (@$arg_param) {
+ if ($arg_name eq 'extra-args') {
+ $opts->{'extra-args'} = [];
+ } else {
+ raise("not enough arguments\n", code => HTTP_BAD_REQUEST);
+ }
+ }
+ }
}
- if (my $pd = $schema->{properties}->{password}) {
- if ($pd->{type} ne 'boolean' && $pwcallback) {
- if ($opts->{password} || !$pd->{optional}) {
- $opts->{password} = &$pwcallback();
- }
+ foreach my $entry (@interactive) {
+ my ($opt, $func) = @$entry;
+ my $pd = $schema->{properties}->{$opt};
+ my $value = $opts->{$opt};
+ if (defined($value) || !$pd->{optional}) {
+ $opts->{$opt} = $func->($value);
}
}