]> git.proxmox.com Git - pve-storage.git/blob - PVE/Storage/SheepdogPlugin.pm
sheepdogplugin: volume_size_info
[pve-storage.git] / PVE / Storage / SheepdogPlugin.pm
1 package PVE::Storage::SheepdogPlugin;
2
3 use strict;
4 use warnings;
5 use IO::File;
6 use PVE::Tools qw(run_command trim);
7 use PVE::Storage::Plugin;
8 use PVE::JSONSchema qw(get_standard_option);
9
10 use base qw(PVE::Storage::Plugin);
11
12 my $collie_cmd = sub {
13 my ($scfg, $class, $op, @options) = @_;
14
15 my $portal = $scfg->{portal};
16 my ($server, $port) = split(':', $portal);
17 my $cmd = ['/usr/sbin/collie', $class, $op, '-a', $server];
18 push @$cmd, '-p', $port if $port;
19
20 push @$cmd, @options if scalar(@options);
21
22 return $cmd;
23 };
24
25 sub sheepdog_ls {
26 my ($scfg, $storeid) = @_;
27
28 my $cmd = &$collie_cmd($scfg, 'vdi', 'list', '-r');
29
30 my $list = {};
31
32 run_command($cmd, outfunc => sub {
33 my $line = shift;
34 $line = trim($line);
35 if ($line =~ /= (vm-(\d+)-\S+)\s+(\d+)\s+(\d+)\s(\d+)\s(\d+)\s/) {
36 my $image = $1;
37 my $owner = $2;
38 my $size = $4;
39
40 $list->{$storeid}->{$image} = {
41 name => $image,
42 size => $size,
43 vmid => $owner
44 };
45 }
46 });
47
48 return $list;
49 }
50
51 # Configuration
52
53
54 sub type {
55 return 'sheepdog';
56 }
57
58 sub plugindata {
59 return {
60 content => [ {images => 1}, { images => 1 }],
61 };
62 }
63
64
65 sub options {
66 return {
67 portal => { fixed => 1 },
68 content => { optional => 1 },
69 };
70 }
71
72 # Storage implementation
73
74 sub parse_volname {
75 my ($class, $volname) = @_;
76
77 if ($volname =~ m/^(vm-(\d+)-\S+)$/) {
78 return ('images', $1, $2);
79 }
80
81 die "unable to parse rbd volume name '$volname'\n";
82 }
83
84 sub path {
85 my ($class, $scfg, $volname, $storeid) = @_;
86
87 my ($vtype, $name, $vmid) = $class->parse_volname($volname);
88
89 my $portal = $scfg->{portal};
90 my ($server, $port) = split(':', $portal);
91 $port = 7000 if !$port;
92
93 my $path = "sheepdog:$server:$port:$name";
94
95 return ($path, $vmid, $vtype);
96 }
97
98 sub alloc_image {
99 my ($class, $storeid, $scfg, $vmid, $fmt, $name, $size) = @_;
100
101
102 die "illegal name '$name' - sould be 'vm-$vmid-*'\n"
103 if $name && $name !~ m/^vm-$vmid-/;
104
105 if (!$name) {
106 my $sheepdog = sheepdog_ls($scfg, $storeid);
107
108 for (my $i = 1; $i < 100; $i++) {
109 my $tn = "vm-$vmid-disk-$i";
110 if (!defined ($sheepdog->{$storeid}->{$tn})) {
111 $name = $tn;
112 last;
113 }
114 }
115 }
116
117 die "unable to allocate an image name for VM $vmid in storage '$storeid'\n"
118 if !$name;
119
120 my $cmd = &$collie_cmd($scfg, 'vdi', 'create', $name , "${size}KB");
121
122 run_command($cmd, errmsg => "sheepdog create $name' error");
123
124 return $name;
125 }
126
127 sub free_image {
128 my ($class, $storeid, $scfg, $volname) = @_;
129
130 my $cmd = &$collie_cmd($scfg, 'vdi', 'delete' , $volname);
131
132 run_command($cmd, errmsg => "sheepdog delete $volname' error");
133
134 return undef;
135 }
136
137 sub list_images {
138 my ($class, $storeid, $scfg, $vmid, $vollist, $cache) = @_;
139
140 $cache->{sheepdog} = sheepdog_ls($scfg, $storeid) if !$cache->{sheepdog};
141 my $res = [];
142
143 if (my $dat = $cache->{sheepdog}->{$storeid}) {
144 foreach my $image (keys %$dat) {
145
146 my $volname = $dat->{$image}->{name};
147
148 my $volid = "$storeid:$volname";
149
150 my $owner = $dat->{$volname}->{vmid};
151 if ($vollist) {
152 my $found = grep { $_ eq $volid } @$vollist;
153 next if !$found;
154 } else {
155 next if defined ($vmid) && ($owner ne $vmid);
156 }
157
158 my $info = $dat->{$volname};
159 $info->{volid} = $volid;
160 $info->{format} = 'raw';
161 push @$res, $info;
162 }
163 }
164
165 return $res;
166 }
167
168
169 sub status {
170 my ($class, $storeid, $scfg, $cache) = @_;
171
172 my $total = 0;
173 my $free = 0;
174 my $used = 0;
175 my $active = 1;
176
177 my $cmd = &$collie_cmd($scfg, 'node', 'info' , '-r');
178
179 my $parser = sub {
180 my $line = shift;
181 if ($line =~ m/^Total\s(\d+)\s(\d+)\s/) {
182 $total = $1;
183 $used = $2;
184 $free = $total - $used;
185 }
186 };
187
188 run_command($cmd, outfunc => $parser, errmsg => "sheepdog node info error");
189
190 return ($total,$free,$used,$active);
191
192 return undef;
193 }
194
195 sub activate_storage {
196 my ($class, $storeid, $scfg, $cache) = @_;
197 return 1;
198 }
199
200 sub deactivate_storage {
201 my ($class, $storeid, $scfg, $cache) = @_;
202 return 1;
203 }
204
205 sub activate_volume {
206 my ($class, $storeid, $scfg, $volname, $exclusive, $cache) = @_;
207 return 1;
208 }
209
210 sub deactivate_volume {
211 my ($class, $storeid, $scfg, $volname, $exclusive, $cache) = @_;
212 return 1;
213 }
214
215 sub volume_size_info {
216 my ($class, $scfg, $storeid, $volname, $timeout) = @_;
217
218 return undef;
219 }
220
221 1;