Provides the basic functionality to provide a wake on LAN feature implementation to start nodes in a cluster from other nodes.
Signed-off-by: Christian Ebner <[email protected]> --- Changes to v4: * Changed description to the suggested one * Directly use IPPROTO_UDP instead of calling getprotobyname('udp') * Changed the error handling * Slight code reformatting PVE/API2/Nodes.pm | 47 +++++++++++++++++++++++++++++++++++++++++++++++ PVE/NodeConfig.pm | 6 ++++++ 2 files changed, 53 insertions(+) diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm index dd5471f8..7f829b29 100644 --- a/PVE/API2/Nodes.pm +++ b/PVE/API2/Nodes.pm @@ -48,6 +48,7 @@ use Digest::MD5; use Digest::SHA; use PVE::API2::Disks; use JSON; +use Socket; use base qw(PVE::RESTHandler); @@ -168,6 +169,7 @@ __PACKAGE__->register_method ({ { name => 'version' }, { name => 'syslog' }, { name => 'status' }, + { name => 'wakeonlan' }, { name => 'subscription' }, { name => 'report' }, { name => 'tasks' }, @@ -466,6 +468,51 @@ __PACKAGE__->register_method({ return undef; }}); +__PACKAGE__->register_method({ + name => 'wakeonlan', + path => 'wakeonlan', + method => 'POST', + permissions => { + check => ['perm', '/nodes/{node}', [ 'Sys.PowerMgmt' ]], + }, + protected => 1, + description => "Try to wake a node via 'wake on LAN' network packet.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node', { + description => 'target node for wake on LAN packet', + }), + }, + }, + returns => { type => "null" }, + code => sub { + my ($param) = @_; + + my $config = PVE::NodeConfig::load_config($param->{node}); + my $mac_addr = $config->{wakeonlan}; + if (!defined($mac_addr)) { + die "No wake on LAN MAC address defined for '$param->{node}'!\n"; + } + + $mac_addr =~ s/://g; + my $packet = chr(0xff) x 6 . pack('H*', $mac_addr) x 16; + + my $addr = gethostbyname('255.255.255.255'); + my $port = getservbyname('discard', 'udp'); + my $to = Socket::pack_sockaddr_in($port, $addr); + socket(my $sock, Socket::AF_INET, Socket::SOCK_DGRAM, Socket::IPPROTO_UDP) + || die "Unable to open socket: $!\n"; + setsockopt($sock, Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1) + || die "Unable to set socket option: $!\n"; + + send($sock, $packet, 0, $to) + || die "Unable to send packet: $!\n"; + + close($sock); + + return undef; + }}); __PACKAGE__->register_method({ name => 'rrd', diff --git a/PVE/NodeConfig.pm b/PVE/NodeConfig.pm index 8ab88130..f82f4ace 100644 --- a/PVE/NodeConfig.pm +++ b/PVE/NodeConfig.pm @@ -61,6 +61,12 @@ my $confdesc = { description => 'Node description/comment.', optional => 1, }, + wakeonlan => { + type => 'string', + description => 'MAC address for wake on LAN', + pattern => '^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$', + optional => 1, + }, }; my $acmedesc = { -- 2.11.0 _______________________________________________ pve-devel mailing list [email protected] https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
