]> git.proxmox.com Git - pve-manager.git/blame - PVE/CephTools.pm
REST/RPCEnvironment's check_worker is a method now
[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);
7d4fc5ef 9use IO::Dir;
a34866f0 10
7d4fc5ef 11use PVE::Tools qw(extract_param run_command file_get_contents file_read_firstline dir_glob_regex dir_glob_foreach);
a34866f0
DM
12
13my $ccname = 'ceph'; # ceph cluster name
14my $ceph_cfgdir = "/etc/ceph";
15my $pve_ceph_cfgpath = "/etc/pve/$ccname.conf";
16my $ceph_cfgpath = "$ceph_cfgdir/$ccname.conf";
17
18my $pve_mon_key_path = "/etc/pve/priv/$ccname.mon.keyring";
19my $pve_ckeyring_path = "/etc/pve/priv/$ccname.client.admin.keyring";
20my $ceph_bootstrap_osd_keyring = "/var/lib/ceph/bootstrap-osd/$ccname.keyring";
21my $ceph_bootstrap_mds_keyring = "/var/lib/ceph/bootstrap-mds/$ccname.keyring";
22
23my $ceph_bin = "/usr/bin/ceph";
24
25my $config_hash = {
26 ccname => $ccname,
27 pve_ceph_cfgpath => $pve_ceph_cfgpath,
28 pve_mon_key_path => $pve_mon_key_path,
29 pve_ckeyring_path => $pve_ckeyring_path,
30 ceph_bootstrap_osd_keyring => $ceph_bootstrap_osd_keyring,
31 ceph_bootstrap_mds_keyring => $ceph_bootstrap_mds_keyring,
7d4fc5ef 32 long_rados_timeout => 60,
a34866f0
DM
33};
34
35sub get_config {
36 my $key = shift;
37
38 my $value = $config_hash->{$key};
39
6f8bf83d 40 die "no such ceph config '$key'" if !$value;
a34866f0
DM
41
42 return $value;
43}
44
a34866f0
DM
45sub purge_all_ceph_files {
46 # fixme: this is very dangerous - should we really support this function?
47
48 unlink $ceph_cfgpath;
49
50 unlink $pve_ceph_cfgpath;
51 unlink $pve_ckeyring_path;
52 unlink $pve_mon_key_path;
53
54 unlink $ceph_bootstrap_osd_keyring;
55 unlink $ceph_bootstrap_mds_keyring;
56
57 system("rm -rf /var/lib/ceph/mon/ceph-*");
58
59 # remove osd?
60}
61
62sub check_ceph_installed {
63 my ($noerr) = @_;
64
65 if (! -x $ceph_bin) {
66 die "ceph binaries not installed\n" if !$noerr;
67 return undef;
68 }
69
70 return 1;
71}
72
73sub check_ceph_inited {
74 my ($noerr) = @_;
75
76 return undef if !check_ceph_installed($noerr);
6f8bf83d 77
a34866f0
DM
78 if (! -f $pve_ceph_cfgpath) {
79 die "pveceph configuration not initialized\n" if !$noerr;
80 return undef;
81 }
82
83 return 1;
84}
85
86sub check_ceph_enabled {
87 my ($noerr) = @_;
88
89 return undef if !check_ceph_inited($noerr);
90
91 if (! -f $ceph_cfgpath) {
92 die "pveceph configuration not enabled\n" if !$noerr;
93 return undef;
94 }
95
96 return 1;
97}
98
99sub parse_ceph_config {
100 my ($filename) = @_;
101
102 $filename = $pve_ceph_cfgpath if !$filename;
103
104 my $cfg = {};
105
106 return $cfg if ! -f $filename;
107
108 my $fh = IO::File->new($filename, "r") ||
109 die "unable to open '$filename' - $!\n";
110
111 my $section;
112
113 while (defined(my $line = <$fh>)) {
114 $line =~ s/[;#].*$//;
115 $line =~ s/^\s+//;
116 $line =~ s/\s+$//;
117 next if !$line;
118
119 $section = $1 if $line =~ m/^\[(\S+)\]$/;
120 if (!$section) {
121 warn "no section - skip: $line\n";
122 next;
123 }
124
15a5cdd1 125 if ($line =~ m/^(.*?\S)\s*=\s*(\S.*)$/) {
a34866f0
DM
126 $cfg->{$section}->{$1} = $2;
127 }
128
129 }
130
131 return $cfg;
132}
133
134sub write_ceph_config {
135 my ($cfg) = @_;
136
137 my $out = '';
138
139 my $cond_write_sec = sub {
140 my $re = shift;
141
142 foreach my $section (keys %$cfg) {
143 next if $section !~ m/^$re$/;
144 $out .= "[$section]\n";
145 foreach my $key (sort keys %{$cfg->{$section}}) {
146 $out .= "\t $key = $cfg->{$section}->{$key}\n";
147 }
148 $out .= "\n";
149 }
150 };
151
152 &$cond_write_sec('global');
19924e77 153 &$cond_write_sec('client');
0fe9bdd5
DM
154 &$cond_write_sec('mds');
155 &$cond_write_sec('mds\..*');
a34866f0
DM
156 &$cond_write_sec('mon');
157 &$cond_write_sec('osd');
158 &$cond_write_sec('mon\..*');
159 &$cond_write_sec('osd\..*');
160
161 PVE::Tools::file_set_contents($pve_ceph_cfgpath, $out);
162}
163
164sub setup_pve_symlinks {
165 # fail if we find a real file instead of a link
166 if (-f $ceph_cfgpath) {
167 my $lnk = readlink($ceph_cfgpath);
168 die "file '$ceph_cfgpath' already exists\n"
169 if !$lnk || $lnk ne $pve_ceph_cfgpath;
170 } else {
171 symlink($pve_ceph_cfgpath, $ceph_cfgpath) ||
172 die "unable to create symlink '$ceph_cfgpath' - $!\n";
173 }
174}
175
176sub ceph_service_cmd {
2bfacbcf
AD
177 my ($action, $service) = @_;
178
1aecf972 179 if (systemd_managed()) {
2bfacbcf
AD
180
181 if ($service && $service =~ m/^(mon|osd|mds|radosgw)(\.([A-Za-z0-9]{1,32}))?$/) {
182 $service = defined($3) ? "ceph-$1\@$3" : "ceph-$1.target";
183 } else {
184 $service = "ceph.target";
185 }
186
187 PVE::Tools::run_command(['/bin/systemctl', $action, $service]);
188
189 } else {
190 # ceph daemons does not call 'setsid', so we do that ourself
6f8bf83d 191 # (fork_worker send KILL to whole process group)
2bfacbcf
AD
192 PVE::Tools::run_command(['setsid', 'service', 'ceph', '-c', $pve_ceph_cfgpath, $action, $service]);
193 }
a34866f0
DM
194}
195
1aecf972
WL
196# Ceph versions greater Hammer use 'ceph' as user and group instead
197# of 'root', and use systemd.
198sub systemd_managed {
199
200 if (-f "/lib/systemd/system/ceph-osd\@.service") {
201 return 1;
202 } else {
203 return 0;
204 }
205}
206
a34866f0 2071;