1 package PVE
::API2
::Pool
;
5 use PVE
::Exception
qw(raise_param_exc);
7 use PVE
::Cluster qw
(cfs_read_file cfs_write_file
);
8 use PVE
::AccessControl
;
13 use Data
::Dumper
; # fixme: remove
18 use base
qw(PVE::RESTHandler);
20 __PACKAGE__-
>register_method ({
24 description
=> "Pool index.",
26 description
=> "List all pools where you have Pool.Allocate or VM.Allocate permissions on /pool/<pool>.",
30 additionalProperties
=> 0,
38 poolid
=> { type
=> 'string' },
41 links
=> [ { rel
=> 'child', href
=> "{poolid}" } ],
46 my $rpcenv = PVE
::RPCEnvironment
::get
();
47 my $authuser = $rpcenv->get_user();
51 my $usercfg = $rpcenv->{user_cfg
};
53 foreach my $pool (keys %{$usercfg->{pools
}}) {
54 next if !$rpcenv->check_any($authuser, "/pool/$pool", [ 'Pool.Allocate', 'VM.Allocate' ], 1);
56 my $entry = { poolid
=> $pool };
57 my $data = $usercfg->{pools
}->{$pool};
58 $entry->{comment
} = $data->{comment
} if defined($data->{comment
});
65 __PACKAGE__-
>register_method ({
66 name
=> 'create_pool',
71 check
=> ['perm', '/pool/{poolid}', ['Pool.Allocate']],
73 description
=> "Create new pool.",
75 additionalProperties
=> 0,
77 poolid
=> { type
=> 'string', format
=> 'pve-poolid' },
78 comment
=> { type
=> 'string', optional
=> 1 },
81 returns
=> { type
=> 'null' },
85 PVE
::AccessControl
::lock_user_config
(
88 my $usercfg = cfs_read_file
("user.cfg");
90 my $pool = $param->{poolid
};
92 die "pool '$pool' already exists\n"
93 if $usercfg->{pools
}->{$pool};
95 $usercfg->{pools
}->{$pool} = { vms
=> {}, storage
=> {} };
97 $usercfg->{pools
}->{$pool}->{comment
} = $param->{comment
} if $param->{comment
};
99 cfs_write_file
("user.cfg", $usercfg);
100 }, "create pool failed");
105 __PACKAGE__-
>register_method ({
106 name
=> 'update_pool',
111 description
=> "You also need the right to modify permissions on any object you add/delete.",
112 check
=> ['perm', '/pool/{poolid}', ['Pool.Allocate']],
114 description
=> "Update pool data.",
116 additionalProperties
=> 0,
118 poolid
=> { type
=> 'string', format
=> 'pve-poolid' },
119 comment
=> { type
=> 'string', optional
=> 1 },
121 description
=> "List of virtual machines.",
122 type
=> 'string', format
=> 'pve-vmid-list',
126 description
=> "List of storage IDs.",
127 type
=> 'string', format
=> 'pve-storage-id-list',
131 description
=> "Remove vms/storage (instead of adding it).",
137 returns
=> { type
=> 'null' },
141 my $rpcenv = PVE
::RPCEnvironment
::get
();
142 my $authuser = $rpcenv->get_user();
144 PVE
::AccessControl
::lock_user_config
(
147 my $usercfg = cfs_read_file
("user.cfg");
149 my $pool = $param->{poolid
};
151 my $data = $usercfg->{pools
}->{$pool};
153 die "pool '$pool' does not exist\n"
156 $data->{comment
} = $param->{comment
} if defined($param->{comment
});
158 if (defined($param->{vms
})) {
159 foreach my $vmid (PVE
::Tools
::split_list
($param->{vms
})) {
160 $rpcenv->check_perm_modify($authuser, "/vms/$vmid");
161 if ($param->{delete}) {
162 die "VM $vmid is not a pool member\n"
163 if !$data->{vms
}->{$vmid};
164 delete $data->{vms
}->{$vmid};
165 delete $usercfg->{vms
}->{$vmid};
167 die "VM $vmid is already a pool member\n"
168 if $data->{vms
}->{$vmid};
169 die "VM $vmid belongs to pool '$usercfg->{vms}->{$vmid}'\n"
170 if $usercfg->{vms
}->{$vmid};
172 $data->{vms
}->{$vmid} = 1;
173 $usercfg->{vms
}->{$vmid} = $pool;
178 if (defined($param->{storage
})) {
179 foreach my $storeid (PVE
::Tools
::split_list
($param->{storage
})) {
180 $rpcenv->check_perm_modify($authuser, "/storage/$storeid");
181 if ($param->{delete}) {
182 die "Storage '$storeid' is not a pool member\n"
183 if !$data->{storage
}->{$storeid};
184 delete $data->{storage
}->{$storeid};
186 die "Storage '$storeid' is already a pool member\n"
187 if $data->{storage
}->{$storeid};
189 $data->{storage
}->{$storeid} = 1;
194 cfs_write_file
("user.cfg", $usercfg);
195 }, "update pools failed");
200 __PACKAGE__-
>register_method ({
205 check
=> ['perm', '/pool/{poolid}', ['Pool.Allocate']],
207 description
=> "Get pool configuration.",
209 additionalProperties
=> 0,
211 poolid
=> {type
=> 'string', format
=> 'pve-poolid' },
216 additionalProperties
=> 0,
218 comment
=> { type
=> 'string', optional
=> 1 },
223 additionalProperties
=> 1,
225 type
=> { type
=> 'string', enum
=> ['qemu', 'lxc', 'openvz', 'storage'] },
226 id
=> { type
=> 'string' },
227 node
=> { type
=> 'string' },
228 vmid
=> { type
=> 'integer', optional
=> 1 },
229 storage
=> { type
=> 'string', optional
=> 1 },
238 my $usercfg = cfs_read_file
("user.cfg");
240 my $vmlist = PVE
::Cluster
::get_vmlist
() || {};
241 my $idlist = $vmlist->{ids
} || {};
243 my $rrd = PVE
::Cluster
::rrd_dump
();
245 my $pool = $param->{poolid
};
247 my $data = $usercfg->{pools
}->{$pool};
249 die "pool '$pool' does not exist\n"
254 foreach my $vmid (keys %{$data->{vms
}}) {
255 my $vmdata = $idlist->{$vmid};
257 my $entry = PVE
::API2Tools
::extract_vm_stats
($vmid, $vmdata, $rrd);
258 push @$members, $entry;
261 my $nodename = PVE
::INotify
::nodename
();
262 my $cfg = PVE
::Storage
::config
();
263 foreach my $storeid (keys %{$data->{storage
}}) {
264 my $scfg = PVE
::Storage
::storage_config
($cfg, $storeid, 1);
267 my $node = $nodename;
268 if ($scfg->{nodes
}) {
269 if (!$scfg->{nodes
}->{$node}) {
270 foreach my $n (sort keys(%{$scfg->{nodes
}})) {
277 my $entry = PVE
::API2Tools
::extract_storage_stats
($storeid, $scfg, $node, $rrd);
278 push @$members, $entry;
281 my $res = { members
=> $members };
282 $res->{comment
} = $data->{comment
} if defined($data->{comment
});
288 __PACKAGE__-
>register_method ({
289 name
=> 'delete_pool',
294 description
=> "You can only delete empty pools (no members).",
295 check
=> ['perm', '/pool/{poolid}', ['Pool.Allocate']],
297 description
=> "Delete pool.",
299 additionalProperties
=> 0,
301 poolid
=> { type
=> 'string', format
=> 'pve-poolid' },
304 returns
=> { type
=> 'null' },
308 my $rpcenv = PVE
::RPCEnvironment
::get
();
309 my $authuser = $rpcenv->get_user();
311 PVE
::AccessControl
::lock_user_config
(
314 my $vmlist = PVE
::Cluster
::get_vmlist
() || {};
315 my $idlist = $vmlist->{ids
} || {};
317 my $storecfg = PVE
::Storage
::config
();
319 my $usercfg = cfs_read_file
("user.cfg");
321 my $pool = $param->{poolid
};
323 my $data = $usercfg->{pools
}->{$pool};
325 die "pool '$pool' does not exist\n"
328 foreach my $vmid (keys %{$data->{vms
}}) {
329 next if !$idlist->{$vmid};
330 die "pool '$pool' is not empty (contains VM $vmid)\n";
333 foreach my $storeid (keys %{$data->{storage
}}) {
334 next if !PVE
::Storage
::storage_config
($storecfg, $storeid, 1);
335 die "pool '$pool' is not empty (contains storage '$storeid')\n";
338 delete ($usercfg->{pools
}->{$pool});
340 PVE
::AccessControl
::delete_pool_acl
($pool, $usercfg);
342 cfs_write_file
("user.cfg", $usercfg);
343 }, "delete pool failed");