Commit 996d32fd authored by Rafael Monnerat's avatar Rafael Monnerat

Unpriviledged boot and bang

This change allow us to use slapos node boot/bang under a slaprunner (or any non-root environment).

It should be usefull to not create ad-hoc implementation for those procedures.

/cc @jerome @tomo @Nicolas

See merge request !214
parents 0ab33235 7e462a6f
......@@ -27,10 +27,10 @@
#
##############################################################################
from slapos.cli.command import must_be_root
from slapos.cli.config import ConfigCommand
from slapos.bang import do_bang
from slapos.util import string_to_boolean
from slapos.cli.command import check_root_user
class BangCommand(ConfigCommand):
......@@ -41,11 +41,17 @@ class BangCommand(ConfigCommand):
def get_parser(self, prog_name):
ap = super(BangCommand, self).get_parser(prog_name)
ap.add_argument('-m', '--message',
help='Message for bang')
ap.add_argument('-m', '--message', help='Message for bang')
return ap
@must_be_root
def take_action(self, args):
configp = self.fetch_config(args)
root_check = True
if configp.has_option('slapos', 'root_check'):
root_check = configp.getboolean('slapos', 'root_check')
if root_check:
check_root_user(self)
do_bang(configp, args.message)
......@@ -37,10 +37,13 @@ import os
import netifaces
import socket
from netaddr import valid_ipv4, valid_ipv6
from slapos.cli.command import must_be_root
from slapos.cli.command import check_root_user
from slapos.cli.entry import SlapOSApp
from slapos.cli.config import ConfigCommand
from slapos.format import isGlobalScopeAddress
from slapos.util import string_to_boolean
import argparse
def _removeTimestamp(instancehome, partition_base_name):
"""
......@@ -54,6 +57,7 @@ def _removeTimestamp(instancehome, partition_base_name):
print("Removing %s" % timestamp_path)
os.remove(timestamp_path)
def _runBang(app):
"""
Launch slapos node format.
......@@ -64,6 +68,7 @@ def _runBang(app):
return 0
return 1
def _runFormat(app):
"""
Launch slapos node format.
......@@ -74,14 +79,15 @@ def _runFormat(app):
return 0
return 1
def _ping(hostname):
"""
Ping a hostname
"""
print("[BOOT] Invoking ipv4 ping to %s..." % hostname)
p = subprocess.Popen(
["ping", "-c", "2", hostname],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p = subprocess.Popen(["ping", "-c", "2", hostname],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode == 0:
print("[BOOT] IPv4 network reachable...")
......@@ -89,6 +95,7 @@ def _ping(hostname):
print("[BOOT] [ERROR] IPv4 network unreachable...")
return 0
def _ping6(hostname):
"""
Ping an ipv6 address
......@@ -104,18 +111,21 @@ def _ping6(hostname):
print("[BOOT] [ERROR] IPv6 network unreachable...")
return 0
def _test_ping(hostname):
is_ready = _ping(hostname)
while is_ready == 0:
sleep(5)
is_ready = _ping(hostname)
def _test_ping6(hostname):
is_ready = _ping6(hostname)
while is_ready == 0:
sleep(5)
is_ready = _ping6(hostname)
def _ping_hostname(hostname):
is_ready = _ping6(hostname)
while is_ready == 0:
......@@ -126,6 +136,7 @@ def _ping_hostname(hostname):
# try ping on ipv6
is_ready = _ping6(hostname)
def _waitIpv6Ready(ipv6_interface):
"""
test if ipv6 is ready on ipv6_interface
......@@ -156,19 +167,33 @@ class BootCommand(ConfigCommand):
help='Message for bang')
return ap
@must_be_root
def take_action(self, args):
configp = self.fetch_config(args)
instance_root = configp.get('slapos','instance_root')
partition_base_name = "slappart"
if configp.has_option('slapformat', 'partition_base_name'):
partition_base_name = configp.get('slapformat', 'partition_base_name')
master_url = urlparse(configp.get('slapos','master_url'))
master_hostname = master_url.hostname
root_check = True
if configp.has_option('slapos', 'root_check'):
root_check = configp.getboolean('slapos', 'root_check')
if root_check:
check_root_user(self)
# Check that we have IPv6 ready
if configp.has_option('slapformat', 'ipv6_interface'):
ipv6_interface = configp.get('slapformat', 'ipv6_interface')
else:
elif configp.has_option('slapformat', 'interface_name'):
ipv6_interface = configp.get('slapformat', 'interface_name')
else:
# It is most likely the we are running on unpriviledged environment
# so we for slapformat handle it.
ipv6_interface = None
if ipv6_interface is not None:
_waitIpv6Ready(ipv6_interface)
# Check that node can ping master
......
......@@ -336,7 +336,8 @@ class TestCliBoot(CliMixin):
SlapOSApp().run.assert_any_call(['node', 'bang', '-m', 'Reboot'])
# timestamp files have been removed
self.assertFalse(os.path.exists(timestamp))
self.assertFalse(os.path.exists(timestamp),
timestamp)
class TestCliNode(CliMixin):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment