Provides the basic functionality to allow a wake on LAN call to start sleeping 
nodes in a cluster from an other cluster member.

Signed-off-by: Christian Ebner <[email protected]>
---
Changes to v3:
    * 'wol' -> 'wakeonlan'
    * 'or' -> '||'
    * Changed the permission back to /nodes/{node} as discussed offline

 PVE/API2/Nodes.pm | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 PVE/NodeConfig.pm |  6 ++++++
 2 files changed, 52 insertions(+)

diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm
index dd5471f8..144dff81 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,50 @@ __PACKAGE__->register_method({
        return undef;
     }});
 
+__PACKAGE__->register_method({
+    name => 'wakeonlan',
+    path => 'wakeonlan',
+    method => 'POST',
+    permissions => {
+       check => ['perm', '/nodes/{node}', [ 'Sys.PowerMgmt' ]],
+    },
+    protected => 1,
+    description => "Boot node via 'wake on LAN'.",
+    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 $proto = getprotobyname('udp');
+       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, $proto)
+           || die "Unable to open socket for sending wake on LAN packet!\n";
+       setsockopt($sock, Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
+           || die "Unable to set socket option for sending wake on LAN 
packet!\n";
+       send($sock, $packet, 0, $to)
+           || die "Unable to send wake on LAN 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

Reply via email to