mirror of
				https://git.proxmox.com/git/pve-manager
				synced 2025-11-04 07:12:22 +00:00 
			
		
		
		
	and include a call to $type metadata to include the version Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
		
			
				
	
	
		
			233 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
package PVE::API2::Ceph::MDS;
 | 
						|
 | 
						|
use strict;
 | 
						|
use warnings;
 | 
						|
 | 
						|
use PVE::Ceph::Tools;
 | 
						|
use PVE::Ceph::Services;
 | 
						|
use PVE::Cluster qw(cfs_read_file cfs_write_file);
 | 
						|
use PVE::INotify;
 | 
						|
use PVE::JSONSchema qw(get_standard_option);
 | 
						|
use PVE::RADOS;
 | 
						|
use PVE::RESTHandler;
 | 
						|
use PVE::RPCEnvironment;
 | 
						|
 | 
						|
use base qw(PVE::RESTHandler);
 | 
						|
 | 
						|
__PACKAGE__->register_method ({
 | 
						|
    name => 'index',
 | 
						|
    path => '',
 | 
						|
    method => 'GET',
 | 
						|
    description => "MDS directory index.",
 | 
						|
    permissions => {
 | 
						|
	check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1],
 | 
						|
    },
 | 
						|
    proxyto => 'node',
 | 
						|
    protected => 1,
 | 
						|
    parameters => {
 | 
						|
	additionalProperties => 0,
 | 
						|
	properties => {
 | 
						|
	    node => get_standard_option('pve-node'),
 | 
						|
	},
 | 
						|
    },
 | 
						|
    returns => {
 | 
						|
	type => 'array',
 | 
						|
	items => {
 | 
						|
	    type => "object",
 | 
						|
	    properties => {
 | 
						|
		name => {
 | 
						|
		    description => "The name (ID) for the MDS",
 | 
						|
		},
 | 
						|
		addr => {
 | 
						|
		    type => 'string',
 | 
						|
		    optional => 1,
 | 
						|
		},
 | 
						|
		host => {
 | 
						|
		    type => 'string',
 | 
						|
		    optional => 1,
 | 
						|
		},
 | 
						|
		state => {
 | 
						|
		    type => 'string',
 | 
						|
		    description => 'State of the MDS',
 | 
						|
		},
 | 
						|
		standby_replay => {
 | 
						|
		    type => 'boolean',
 | 
						|
		    optional => 1,
 | 
						|
		    description => 'If true, the standby MDS is polling the active MDS for faster recovery (hot standby).',
 | 
						|
		},
 | 
						|
		rank => {
 | 
						|
		    type => 'integer',
 | 
						|
		    optional => 1,
 | 
						|
		},
 | 
						|
	    },
 | 
						|
	},
 | 
						|
	links => [ { rel => 'child', href => "{name}" } ],
 | 
						|
    },
 | 
						|
    code => sub {
 | 
						|
	my ($param) = @_;
 | 
						|
 | 
						|
	PVE::Ceph::Tools::check_ceph_inited();
 | 
						|
 | 
						|
	my $res = [];
 | 
						|
 | 
						|
	my $cfg = cfs_read_file('ceph.conf');
 | 
						|
	my $rados = PVE::RADOS->new();
 | 
						|
 | 
						|
	my $mds_hash = PVE::Ceph::Services::get_services_info("mds", $cfg, $rados);
 | 
						|
 | 
						|
	my $mds_state = PVE::Ceph::Services::get_cluster_mds_state($rados);
 | 
						|
	foreach my $name (keys %$mds_state) {
 | 
						|
	    my $d = $mds_state->{$name};
 | 
						|
	    # just overwrite, this always provides more info
 | 
						|
	    $mds_hash->{$name}->{$_} = $d->{$_} for keys %$d;
 | 
						|
	}
 | 
						|
 | 
						|
	return PVE::RESTHandler::hash_to_array($mds_hash, 'name');
 | 
						|
    }
 | 
						|
});
 | 
						|
 | 
						|
__PACKAGE__->register_method ({
 | 
						|
    name => 'createmds',
 | 
						|
    path => '{name}',
 | 
						|
    method => 'POST',
 | 
						|
    description => "Create Ceph Metadata Server (MDS)",
 | 
						|
    proxyto => 'node',
 | 
						|
    protected => 1,
 | 
						|
    permissions => {
 | 
						|
	check => ['perm', '/', [ 'Sys.Modify' ]],
 | 
						|
    },
 | 
						|
    parameters => {
 | 
						|
	additionalProperties => 0,
 | 
						|
	properties => {
 | 
						|
	    node => get_standard_option('pve-node'),
 | 
						|
	    name => {
 | 
						|
		type => 'string',
 | 
						|
		optional => 1,
 | 
						|
		default => 'nodename',
 | 
						|
		pattern => '[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?',
 | 
						|
		description => "The ID for the mds, when omitted the same as the nodename",
 | 
						|
	    },
 | 
						|
	    hotstandby => {
 | 
						|
		type => 'boolean',
 | 
						|
		optional => 1,
 | 
						|
		default => '0',
 | 
						|
		description => "Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. ".
 | 
						|
		    "Faster switch on MDS failure, but needs more idle resources.",
 | 
						|
	    },
 | 
						|
	},
 | 
						|
    },
 | 
						|
    returns => { type => 'string' },
 | 
						|
    code => sub {
 | 
						|
	my ($param) = @_;
 | 
						|
 | 
						|
	PVE::Ceph::Tools::check_ceph_installed('ceph_mds');
 | 
						|
 | 
						|
	PVE::Ceph::Tools::check_ceph_inited();
 | 
						|
 | 
						|
	my $rpcenv = PVE::RPCEnvironment::get();
 | 
						|
	my $authuser = $rpcenv->get_user();
 | 
						|
 | 
						|
	my $nodename = $param->{node};
 | 
						|
	$nodename = INotify::nodename() if $nodename eq 'localhost';
 | 
						|
 | 
						|
	my $mds_id = $param->{name} // $nodename;
 | 
						|
 | 
						|
	my $worker = sub {
 | 
						|
	    my $timeout = PVE::Ceph::Tools::get_config('long_rados_timeout');
 | 
						|
	    my $rados = PVE::RADOS->new(timeout => $timeout);
 | 
						|
 | 
						|
	    my $cfg = cfs_read_file('ceph.conf');
 | 
						|
 | 
						|
	    my $section = "mds.$mds_id";
 | 
						|
 | 
						|
	    if (defined($cfg->{$section})) {
 | 
						|
		die "MDS '$mds_id' already referenced in ceph config, abort!\n"
 | 
						|
	    }
 | 
						|
 | 
						|
	    if (!defined($cfg->{mds}->{keyring})) {
 | 
						|
		# $id isn't a perl variable but a ceph metavariable
 | 
						|
		my $keyring = '/var/lib/ceph/mds/ceph-$id/keyring';
 | 
						|
 | 
						|
		$cfg->{mds}->{keyring} = $keyring;
 | 
						|
	    }
 | 
						|
 | 
						|
	    $cfg->{$section}->{host} = $nodename;
 | 
						|
	    $cfg->{$section}->{"mds standby for name"} = 'pve';
 | 
						|
 | 
						|
	    if ($param->{hotstandby}) {
 | 
						|
		$cfg->{$section}->{"mds standby replay"} = 'true';
 | 
						|
	    }
 | 
						|
 | 
						|
	    cfs_write_file('ceph.conf', $cfg);
 | 
						|
 | 
						|
	    eval { PVE::Ceph::Services::create_mds($mds_id, $rados) };
 | 
						|
	    if (my $err = $@) {
 | 
						|
		# we abort early if the section is defined, so we know that we
 | 
						|
		# wrote it at this point. Do not auto remove the service, could
 | 
						|
		# do real harm for previously manual setup MDS
 | 
						|
		warn "Encountered error, remove '$section' from ceph.conf\n";
 | 
						|
		my $cfg = cfs_read_file('ceph.conf');
 | 
						|
		delete $cfg->{$section};
 | 
						|
		cfs_write_file('ceph.conf', $cfg);
 | 
						|
 | 
						|
		die "$err\n";
 | 
						|
	    }
 | 
						|
	};
 | 
						|
 | 
						|
	return $rpcenv->fork_worker('cephcreatemds', "mds.$mds_id", $authuser, $worker);
 | 
						|
    }
 | 
						|
});
 | 
						|
 | 
						|
__PACKAGE__->register_method ({
 | 
						|
    name => 'destroymds',
 | 
						|
    path => '{name}',
 | 
						|
    method => 'DELETE',
 | 
						|
    description => "Destroy Ceph Metadata Server",
 | 
						|
    proxyto => 'node',
 | 
						|
    protected => 1,
 | 
						|
    permissions => {
 | 
						|
	check => ['perm', '/', [ 'Sys.Modify' ]],
 | 
						|
    },
 | 
						|
    parameters => {
 | 
						|
	additionalProperties => 0,
 | 
						|
	properties => {
 | 
						|
	    node => get_standard_option('pve-node'),
 | 
						|
	    name => {
 | 
						|
		description => 'The name (ID) of the mds',
 | 
						|
		type => 'string',
 | 
						|
		pattern => '[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?',
 | 
						|
	    },
 | 
						|
	},
 | 
						|
    },
 | 
						|
    returns => { type => 'string' },
 | 
						|
    code => sub {
 | 
						|
	my ($param) = @_;
 | 
						|
 | 
						|
	my $rpcenv = PVE::RPCEnvironment::get();
 | 
						|
 | 
						|
	my $authuser = $rpcenv->get_user();
 | 
						|
 | 
						|
	PVE::Ceph::Tools::check_ceph_inited();
 | 
						|
 | 
						|
	my $mds_id = $param->{name};
 | 
						|
 | 
						|
	my $worker = sub {
 | 
						|
	    my $timeout = PVE::Ceph::Tools::get_config('long_rados_timeout');
 | 
						|
	    my $rados = PVE::RADOS->new(timeout => $timeout);
 | 
						|
 | 
						|
	    my $cfg = cfs_read_file('ceph.conf');
 | 
						|
 | 
						|
	    if (defined($cfg->{"mds.$mds_id"})) {
 | 
						|
		delete $cfg->{"mds.$mds_id"};
 | 
						|
		cfs_write_file('ceph.conf', $cfg);
 | 
						|
	    }
 | 
						|
 | 
						|
	    PVE::Ceph::Services::destroy_mds($mds_id, $rados);
 | 
						|
	};
 | 
						|
 | 
						|
	return $rpcenv->fork_worker('cephdestroymds', "mds.$mds_id",  $authuser, $worker);
 | 
						|
    }
 | 
						|
});
 | 
						|
 | 
						|
1;
 |