]> git.proxmox.com Git - pve-manager.git/blame - PVE/CephTools.pm
split out ceph code into PVE::CephTools
[pve-manager.git] / PVE / CephTools.pm
CommitLineData
a34866f0
DM
1package PVE::CephTools;
2
3use strict;
4use warnings;
5use File::Basename;
6use File::Path;
7use POSIX qw (LONG_MAX);
8use Cwd qw(abs_path);
9
10use PVE::Tools;
11
12my $ccname = 'ceph'; # ceph cluster name
13my $ceph_cfgdir = "/etc/ceph";
14my $pve_ceph_cfgpath = "/etc/pve/$ccname.conf";
15my $ceph_cfgpath = "$ceph_cfgdir/$ccname.conf";
16
17my $pve_mon_key_path = "/etc/pve/priv/$ccname.mon.keyring";
18my $pve_ckeyring_path = "/etc/pve/priv/$ccname.client.admin.keyring";
19my $ceph_bootstrap_osd_keyring = "/var/lib/ceph/bootstrap-osd/$ccname.keyring";
20my $ceph_bootstrap_mds_keyring = "/var/lib/ceph/bootstrap-mds/$ccname.keyring";
21
22my $ceph_bin = "/usr/bin/ceph";
23
24my $config_hash = {
25 ccname => $ccname,
26 pve_ceph_cfgpath => $pve_ceph_cfgpath,
27 pve_mon_key_path => $pve_mon_key_path,
28 pve_ckeyring_path => $pve_ckeyring_path,
29 ceph_bootstrap_osd_keyring => $ceph_bootstrap_osd_keyring,
30 ceph_bootstrap_mds_keyring => $ceph_bootstrap_mds_keyring,
31};
32
33sub get_config {
34 my $key = shift;
35
36 my $value = $config_hash->{$key};
37
38 die "no such ceph config '$key'" if !$value;
39
40 return $value;
41}
42
43sub verify_blockdev_path {
44 my ($path) = @_;
45
46 $path = abs_path($path);
47
48 die "got unusual device path '$path'\n" if $path !~ m|^/dev/(.*)$|;
49
50 $path = "/dev/$1"; # untaint
51
52 die "no such block device '$path'\n"
53 if ! -b $path;
54
55 return $path;
56};
57
58sub purge_all_ceph_files {
59 # fixme: this is very dangerous - should we really support this function?
60
61 unlink $ceph_cfgpath;
62
63 unlink $pve_ceph_cfgpath;
64 unlink $pve_ckeyring_path;
65 unlink $pve_mon_key_path;
66
67 unlink $ceph_bootstrap_osd_keyring;
68 unlink $ceph_bootstrap_mds_keyring;
69
70 system("rm -rf /var/lib/ceph/mon/ceph-*");
71
72 # remove osd?
73}
74
75sub check_ceph_installed {
76 my ($noerr) = @_;
77
78 if (! -x $ceph_bin) {
79 die "ceph binaries not installed\n" if !$noerr;
80 return undef;
81 }
82
83 return 1;
84}
85
86sub check_ceph_inited {
87 my ($noerr) = @_;
88
89 return undef if !check_ceph_installed($noerr);
90
91 if (! -f $pve_ceph_cfgpath) {
92 die "pveceph configuration not initialized\n" if !$noerr;
93 return undef;
94 }
95
96 return 1;
97}
98
99sub check_ceph_enabled {
100 my ($noerr) = @_;
101
102 return undef if !check_ceph_inited($noerr);
103
104 if (! -f $ceph_cfgpath) {
105 die "pveceph configuration not enabled\n" if !$noerr;
106 return undef;
107 }
108
109 return 1;
110}
111
112sub parse_ceph_config {
113 my ($filename) = @_;
114
115 $filename = $pve_ceph_cfgpath if !$filename;
116
117 my $cfg = {};
118
119 return $cfg if ! -f $filename;
120
121 my $fh = IO::File->new($filename, "r") ||
122 die "unable to open '$filename' - $!\n";
123
124 my $section;
125
126 while (defined(my $line = <$fh>)) {
127 $line =~ s/[;#].*$//;
128 $line =~ s/^\s+//;
129 $line =~ s/\s+$//;
130 next if !$line;
131
132 $section = $1 if $line =~ m/^\[(\S+)\]$/;
133 if (!$section) {
134 warn "no section - skip: $line\n";
135 next;
136 }
137
138 if ($line =~ m/^(.*\S)\s*=\s*(\S.*)$/) {
139 $cfg->{$section}->{$1} = $2;
140 }
141
142 }
143
144 return $cfg;
145}
146
147sub write_ceph_config {
148 my ($cfg) = @_;
149
150 my $out = '';
151
152 my $cond_write_sec = sub {
153 my $re = shift;
154
155 foreach my $section (keys %$cfg) {
156 next if $section !~ m/^$re$/;
157 $out .= "[$section]\n";
158 foreach my $key (sort keys %{$cfg->{$section}}) {
159 $out .= "\t $key = $cfg->{$section}->{$key}\n";
160 }
161 $out .= "\n";
162 }
163 };
164
165 &$cond_write_sec('global');
166 &$cond_write_sec('mon');
167 &$cond_write_sec('osd');
168 &$cond_write_sec('mon\..*');
169 &$cond_write_sec('osd\..*');
170
171 PVE::Tools::file_set_contents($pve_ceph_cfgpath, $out);
172}
173
174sub setup_pve_symlinks {
175 # fail if we find a real file instead of a link
176 if (-f $ceph_cfgpath) {
177 my $lnk = readlink($ceph_cfgpath);
178 die "file '$ceph_cfgpath' already exists\n"
179 if !$lnk || $lnk ne $pve_ceph_cfgpath;
180 } else {
181 symlink($pve_ceph_cfgpath, $ceph_cfgpath) ||
182 die "unable to create symlink '$ceph_cfgpath' - $!\n";
183 }
184}
185
186sub ceph_service_cmd {
187 PVE::Tools::run_command(['service', 'ceph', '-c', $pve_ceph_cfgpath, @_]);
188}
189
1901;