]>
git.proxmox.com Git - pve-storage.git/blob - PVE/API2/Storage/Config.pm
1 package PVE
::API2
::Storage
::Config
;
7 use PVE
::Cluster
qw(cfs_read_file cfs_write_file);
9 use HTTP
::Status
qw(:constants);
10 use Storable
qw(dclone);
11 use PVE
::JSONSchema
qw(get_standard_option);
13 use Data
::Dumper
; # fixme: remove
17 use base
qw(PVE::RESTHandler);
19 my @ctypes = qw(images vztmpl iso backup);
21 my $storage_type_enum = ['dir', 'nfs', 'lvm', 'iscsi'];
23 my $api_storage_config = sub {
24 my ($cfg, $storeid) = @_;
26 my $scfg = dclone
(PVE
::Storage
::storage_config
($cfg, $storeid));
27 $scfg->{storage
} = $storeid;
28 delete $scfg->{priority
};
29 $scfg->{digest
} = $cfg->{digest
};
30 $scfg->{content
} = PVE
::Storage
::content_hash_to_string
($scfg->{content
});
33 $scfg->{nodes
} = join(',', keys(%{$scfg->{nodes
}}));
39 __PACKAGE__-
>register_method ({
43 description
=> "Storage index.",
45 additionalProperties
=> 0,
48 description
=> "Only list storage of specific type",
50 enum
=> $storage_type_enum,
60 properties
=> { storage
=> { type
=> 'string'} },
62 links
=> [ { rel
=> 'child', href
=> "{storage}" } ],
67 my $cfg = cfs_read_file
("storage.cfg");
69 my @sids = PVE
::Storage
::storage_ids
($cfg);
72 foreach my $storeid (@sids) {
73 my $scfg = &$api_storage_config($cfg, $storeid);
74 next if $param->{type
} && $param->{type
} ne $scfg->{type
};
81 __PACKAGE__-
>register_method ({
85 description
=> "Read storage configuration.",
87 additionalProperties
=> 0,
89 storage
=> get_standard_option
('pve-storage-id'),
96 my $cfg = cfs_read_file
("storage.cfg");
98 return &$api_storage_config($cfg, $param->{storage
});
101 __PACKAGE__-
>register_method ({
106 description
=> "Create a new storage.",
108 additionalProperties
=> 0,
110 storage
=> get_standard_option
('pve-storage-id'),
111 nodes
=> get_standard_option
('pve-node-list', { optional
=> 1 }),
114 enum
=> $storage_type_enum,
117 type
=> 'string', format
=> 'pve-storage-path',
121 type
=> 'string', format
=> 'pve-storage-path',
125 type
=> 'string', format
=> 'pve-storage-server',
129 type
=> 'string', format
=> 'pve-storage-options',
137 type
=> 'string', format
=> 'pve-storage-vgname',
141 type
=> 'string', format
=> 'pve-volume-id',
145 type
=> 'string', format
=> 'pve-storage-portal-dns',
149 type
=> 'string', format
=> 'pve-storage-content-list',
161 type
=> 'string', format
=> 'pve-storage-format',
166 returns
=> { type
=> 'null' },
170 my $type = $param->{type
};
171 delete $param->{type
};
173 my $storeid = $param->{storage
};
174 delete $param->{storage
};
176 if ($param->{portal
}) {
177 $param->{portal
} = PVE
::Storage
::resolv_portal
($param->{portal
});
180 my $opts = PVE
::Storage
::parse_options
($storeid, $type, $param, 1);
182 PVE
::Storage
::lock_storage_config
(
185 my $cfg = cfs_read_file
('storage.cfg');
187 if (my $scfg = PVE
::Storage
::storage_config
($cfg, $storeid, 1)) {
188 die "storage ID '$storeid' already defined\n";
191 $cfg->{ids
}->{$storeid} = $opts;
193 if ($type eq 'lvm' && $opts->{base
}) {
195 my ($baseid, $volname) = PVE
::Storage
::parse_volume_id
($opts->{base
});
197 my $basecfg = PVE
::Storage
::storage_config
($cfg, $baseid, 1);
198 die "base storage ID '$baseid' does not exist\n" if !$basecfg;
200 # we only support iscsi for now
201 if (!($basecfg->{type
} eq 'iscsi')) {
202 die "unsupported base type '$basecfg->{type}'";
205 my $path = PVE
::Storage
::path
($cfg, $opts->{base
});
207 PVE
::Storage
::activate_storage
($cfg, $baseid);
209 PVE
::Storage
::lvm_create_volume_group
($path, $opts->{vgname
}, $opts->{shared
});
212 # try to activate if enabled on local node,
213 # we only do this to detect errors/problems sooner
214 if (PVE
::Storage
::storage_check_enabled
($cfg, $storeid, undef, 1)) {
215 PVE
::Storage
::activate_storage
($cfg, $storeid);
218 cfs_write_file
('storage.cfg', $cfg);
220 }, "create storage failed");
224 __PACKAGE__-
>register_method ({
229 description
=> "Update storage configuration.",
231 additionalProperties
=> 0,
233 storage
=> get_standard_option
('pve-storage-id'),
234 nodes
=> get_standard_option
('pve-node-list', { optional
=> 1 }),
236 type
=> 'string', format
=> 'pve-storage-content-list',
240 type
=> 'string', format
=> 'pve-storage-format',
252 type
=> 'string', format
=> 'pve-storage-options',
257 description
=> 'Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.',
263 returns
=> { type
=> 'null' },
267 my $storeid = $param->{storage
};
268 delete($param->{storage
});
270 my $digest = $param->{digest
};
271 delete($param->{digest
});
273 PVE
::Storage
::lock_storage_config
(
276 my $cfg = cfs_read_file
('storage.cfg');
278 PVE
::Storage
::assert_if_modified
($cfg, $digest);
280 my $scfg = PVE
::Storage
::storage_config
($cfg, $storeid);
282 my $opts = PVE
::Storage
::parse_options
($storeid, $scfg->{type
}, $param);
284 foreach my $k (%$opts) {
285 $scfg->{$k} = $opts->{$k};
288 cfs_write_file
('storage.cfg', $cfg);
290 }, "update storage failed");
295 __PACKAGE__-
>register_method ({
298 path
=> '{storage}', # /storage/config/{storage}
300 description
=> "Delete storage configuration.",
302 additionalProperties
=> 0,
304 storage
=> get_standard_option
('pve-storage-id'),
307 returns
=> { type
=> 'null' },
311 my $storeid = $param->{storage
};
312 delete($param->{storage
});
314 PVE
::Storage
::lock_storage_config
(
317 my $cfg = cfs_read_file
('storage.cfg');
319 die "can't remove storage - storage is used as base of another storage\n"
320 if PVE
::Storage
::storage_is_used
($cfg, $storeid);
322 delete ($cfg->{ids
}->{$storeid});
324 cfs_write_file
('storage.cfg', $cfg);
326 }, "delete storage failed");