all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Aaron Lauterer <a.lauterer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH manager 3/5] api ceph osd: add volume details endpoint
Date: Fri,  1 Jul 2022 16:16:40 +0200	[thread overview]
Message-ID: <20220701141642.2743824-4-a.lauterer@proxmox.com> (raw)
In-Reply-To: <20220701141642.2743824-1-a.lauterer@proxmox.com>

This endpoint returns the following infos for an volume:
* creation time
* lv name
* lv path
* lv size
* lv uuid
* vg name

Possible volumes are:
* block (default value if not provided)
* db
* wal

'ceph-volume' is used to gather the infos, except for the creation time
of the LV which is retrieved via 'lvs'.

Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
---

While Ceph itself does not store any information about the creation time
of an OSD, I think we can get close to it by using the information
stored in the LVs.

 PVE/API2/Ceph/OSD.pm | 109 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/PVE/API2/Ceph/OSD.pm b/PVE/API2/Ceph/OSD.pm
index 078a8c81..c9ec3222 100644
--- a/PVE/API2/Ceph/OSD.pm
+++ b/PVE/API2/Ceph/OSD.pm
@@ -5,6 +5,7 @@ use warnings;
 
 use Cwd qw(abs_path);
 use IO::File;
+use JSON;
 use UUID;
 
 use PVE::Ceph::Tools;
@@ -697,6 +698,114 @@ __PACKAGE__->register_method ({
 	return $data;
     }});
 
+__PACKAGE__->register_method ({
+    name => 'osdvolume',
+    path => '{osdid}/volume',
+    method => 'GET',
+    description => "Get OSD volume details",
+    proxyto => 'node',
+    protected => 1,
+    permissions => {
+	check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    node => get_standard_option('pve-node'),
+	    osdid => {
+		description => 'OSD ID',
+		type => 'integer',
+	    },
+	    type => {
+		description => 'OSD device type',
+		type => 'string',
+		enum => ['block', 'db', 'wal'],
+		default => 'block',
+		optional => 1,
+	    },
+	},
+    },
+    returns => {
+	type => 'object',
+	properties => {
+	    creation_time => {
+		type => 'string',
+		description => "Creation time as reported by 'lvs'.",
+	    },
+	    lv_name => {
+		type => 'string',
+		description => 'Name of the logical volume (LV).',
+	    },
+	    lv_path => {
+		type => 'string',
+		description => 'Path to the logical volume (LV).',
+	    },
+	    lv_size => {
+		type => 'integer',
+		description => 'Size of the logical volume (LV).',
+	    },
+	    lv_uuid => {
+		type => 'string',
+		description => 'UUID of the logical volume (LV).',
+	    },
+	    vg_name => {
+		type => 'string',
+		description => 'Name of the volume group (VG).',
+	    },
+	},
+    },
+    code => sub {
+	my ($param) = @_;
+
+	PVE::Ceph::Tools::check_ceph_inited();
+
+	my $osdid = $param->{osdid};
+	my $type = $param->{type} // 'block';
+
+	my $raw = '';
+	my $parser = sub { $raw .= shift };
+	my $cmd = ['/usr/sbin/ceph-volume', 'lvm', 'list', '--format', 'json'];
+	eval { run_command($cmd, errmsg => 'ceph volume error', outfunc => $parser) };
+	die $@ if $@;
+
+	my $result;
+	if ($raw =~ m/^(\{.*\})$/s) { #untaint
+	    $result = JSON::decode_json($1);
+	} else {
+	    die "got unexpected data from ceph-volume: '${raw}'\n";
+	}
+	die "OSD '${osdid}' not found in 'ceph-volume lvm list' on node '${nodename}'\n"
+	    if !$result->{$osdid};
+
+	my $volume_data = {};
+	%{$volume_data} = map { $_->{type} => $_ } @{$result->{$osdid}};
+	die "volume type '${type}' not found for OSD ${osdid}\n" if !$volume_data->{$type};
+
+	my $volume = $volume_data->{$type};
+
+	$raw = '';
+	$cmd = ['/sbin/lvs', $volume->{lv_path}, '--reportformat', 'json', '-o', 'lv_time'];
+	eval { run_command($cmd, errmsg => 'lvs error', outfunc => $parser) };
+	die $@ if $@;
+
+	if ($raw =~ m/(\{.*\})$/s) { #untaint, lvs has whitespace at beginning
+	    $result = JSON::decode_json($1);
+	} else {
+	    die "got unexpected data from lvs: '${raw}'\n";
+	}
+	my $data = {};
+
+	my $keys = [ 'lv_name', 'lv_path', 'lv_uuid', 'vg_name' ];
+	for my $key (@$keys) {
+	    $data->{$key} = $volume->{$key};
+	}
+	$data->{lv_size} = int($volume->{lv_size});
+
+	$data->{creation_time} = @{$result->{report}}[0]->{lv}[0]->{lv_time};
+
+	return $data;
+    }});
+
 # Check if $osdid belongs to $nodename
 # $tree ... rados osd tree (passing the tree makes it easy to test)
 sub osd_belongs_to_node {
-- 
2.30.2





  parent reply	other threads:[~2022-07-01 14:16 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-01 14:16 [pve-devel] [PATCH widget-toolkit/manager 0/5] Ceph OSD: add detail infos Aaron Lauterer
2022-07-01 14:16 ` [pve-devel] [PATCH widget-toolkit 1/5] ObjectGrid: optionally show loading on reload Aaron Lauterer
2022-07-05  9:32   ` Thomas Lamprecht
2022-07-01 14:16 ` [pve-devel] [PATCH manager 2/5] api ceph osd: add OSD details endpoint Aaron Lauterer
2022-07-01 14:16 ` Aaron Lauterer [this message]
2022-07-05  9:58   ` [pve-devel] [PATCH manager 3/5] api ceph osd: add volume " Thomas Lamprecht
2022-07-05 14:19     ` Aaron Lauterer
2022-07-06  6:37       ` Thomas Lamprecht
2022-07-01 14:16 ` [pve-devel] [PATCH manager 4/5] ui utils: add renderer for ceph osd addresses Aaron Lauterer
2022-07-01 14:16 ` [pve-devel] [PATCH manager 5/5] ui: osd: add details window Aaron Lauterer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220701141642.2743824-4-a.lauterer@proxmox.com \
    --to=a.lauterer@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal