Commit cffbbae7 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Implement virtual cluster support in Python code



- pathutils: Prepend node-specific prefix path
- RPC: Use virtual paths (see vcluster.py)
- SSH: Pass environment variables, use destination's node directory when
  copying files using scp, use GANETI_HOSTNAME to determine hostname
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarRené Nussbaumer <rn@google.com>
parent 9340cc2b
......@@ -63,6 +63,7 @@ from ganeti import runtime
from ganeti import mcpu
from ganeti import compat
from ganeti import pathutils
from ganeti import vcluster
_BOOT_ID_PATH = "/proc/sys/kernel/random/boot_id"
......@@ -2072,6 +2073,8 @@ def UploadFile(file_name, data, mode, uid, gid, atime, mtime):
@rtype: None
"""
file_name = vcluster.LocalizeVirtualPath(file_name)
if not os.path.isabs(file_name):
_Fail("Filename passed to UploadFile is not absolute: '%s'", file_name)
......@@ -2821,6 +2824,8 @@ def JobQueueUpdate(file_name, content):
@return: the success of the operation
"""
file_name = vcluster.LocalizeVirtualPath(file_name)
_EnsureJobQueueFile(file_name)
getents = runtime.GetEnts()
......@@ -2842,6 +2847,9 @@ def JobQueueRename(old, new):
@return: the success of the operation and payload
"""
old = vcluster.LocalizeVirtualPath(old)
new = vcluster.LocalizeVirtualPath(new)
_EnsureJobQueueFile(old)
_EnsureJobQueueFile(new)
......
......@@ -33,11 +33,12 @@ from ganeti.hypervisor import hv_base
from ganeti import netutils
from ganeti import objects
from ganeti import pathutils
from ganeti import vcluster
XEND_CONFIG_FILE = "/etc/xen/xend-config.sxp"
XL_CONFIG_FILE = "/etc/xen/xl.conf"
VIF_BRIDGE_SCRIPT = "/etc/xen/scripts/vif-bridge"
XEND_CONFIG_FILE = vcluster.AddNodePrefix("/etc/xen/xend-config.sxp")
XL_CONFIG_FILE = vcluster.AddNodePrefix("/etc/xen/xl.conf")
VIF_BRIDGE_SCRIPT = vcluster.AddNodePrefix("/etc/xen/scripts/vif-bridge")
_DOM0_NAME = "Domain-0"
......
......@@ -60,6 +60,7 @@ from ganeti import ht
from ganeti import query
from ganeti import qlang
from ganeti import pathutils
from ganeti import vcluster
JOBQUEUE_THREADS = 25
......@@ -85,6 +86,14 @@ def TimeStampNow():
return utils.SplitTime(time.time())
def _CallJqUpdate(runner, names, file_name, content):
"""Updates job queue file after virtualizing filename.
"""
virt_file_name = vcluster.MakeVirtualPath(file_name)
return runner.call_jobqueue_update(names, virt_file_name, content)
class _SimpleJobQuery:
"""Wrapper for job queries.
......@@ -1690,8 +1699,8 @@ class JobQueue(object):
# Read file content
content = utils.ReadFile(file_name)
result = self._GetRpc(addrs).call_jobqueue_update([node_name], file_name,
content)
result = _CallJqUpdate(self._GetRpc(addrs), [node_name],
file_name, content)
msg = result[node_name].fail_msg
if msg:
logging.error("Failed to upload file %s to node %s: %s",
......@@ -1775,7 +1784,7 @@ class JobQueue(object):
if replicate:
names, addrs = self._GetNodeIp()
result = self._GetRpc(addrs).call_jobqueue_update(names, file_name, data)
result = _CallJqUpdate(self._GetRpc(addrs), names, file_name, data)
self._CheckRpcResult(result, self._nodes, "Updating %s" % file_name)
def _RenameFilesUnlocked(self, rename):
......
......@@ -24,15 +24,19 @@
"""
from ganeti import _autoconf
from ganeti import vcluster
# Build-time constants
DEFAULT_FILE_STORAGE_DIR = _autoconf.FILE_STORAGE_DIR
DEFAULT_SHARED_FILE_STORAGE_DIR = _autoconf.SHARED_FILE_STORAGE_DIR
EXPORT_DIR = _autoconf.EXPORT_DIR
DEFAULT_FILE_STORAGE_DIR = vcluster.AddNodePrefix(_autoconf.FILE_STORAGE_DIR)
DEFAULT_SHARED_FILE_STORAGE_DIR = \
vcluster.AddNodePrefix(_autoconf.SHARED_FILE_STORAGE_DIR)
EXPORT_DIR = vcluster.AddNodePrefix(_autoconf.EXPORT_DIR)
OS_SEARCH_PATH = _autoconf.OS_SEARCH_PATH
SSH_CONFIG_DIR = _autoconf.SSH_CONFIG_DIR
SYSCONFDIR = _autoconf.SYSCONFDIR
SYSCONFDIR = vcluster.AddNodePrefix(_autoconf.SYSCONFDIR)
TOOLSDIR = _autoconf.TOOLSDIR
LOCALSTATEDIR = vcluster.AddNodePrefix(_autoconf.LOCALSTATEDIR)
# Paths which don't change for a virtual cluster
DAEMON_UTIL = _autoconf.PKGLIBDIR + "/daemon-util"
......@@ -43,10 +47,10 @@ SETUP_SSH = _autoconf.TOOLSDIR + "/setup-ssh"
XM_CONSOLE_WRAPPER = _autoconf.PKGLIBDIR + "/tools/xm-console-wrapper"
# Top-level paths
DATA_DIR = _autoconf.LOCALSTATEDIR + "/lib/ganeti"
LOCK_DIR = _autoconf.LOCALSTATEDIR + "/lock"
LOG_DIR = _autoconf.LOCALSTATEDIR + "/log/ganeti"
RUN_DIR = _autoconf.LOCALSTATEDIR + "/run/ganeti"
DATA_DIR = LOCALSTATEDIR + "/lib/ganeti"
LOCK_DIR = LOCALSTATEDIR + "/lock"
LOG_DIR = LOCALSTATEDIR + "/log/ganeti"
RUN_DIR = LOCALSTATEDIR + "/run/ganeti"
#: Script to configure master IP address
DEFAULT_MASTER_SETUP_SCRIPT = TOOLSDIR + "/master-ip-setup"
......
......@@ -48,6 +48,7 @@ from ganeti import runtime
from ganeti import compat
from ganeti import rpc_defs
from ganeti import pathutils
from ganeti import vcluster
# Special module generated at build time
from ganeti import _generated_rpc
......@@ -524,7 +525,9 @@ def _PrepareFileUpload(getents_fn, filename):
getents = getents_fn()
return [filename, data, st.st_mode, getents.LookupUid(st.st_uid),
virt_filename = vcluster.MakeVirtualPath(filename)
return [virt_filename, data, st.st_mode, getents.LookupUid(st.st_uid),
getents.LookupGid(st.st_gid), st.st_atime, st.st_mtime]
......
......@@ -33,6 +33,7 @@ from ganeti import errors
from ganeti import constants
from ganeti import netutils
from ganeti import pathutils
from ganeti import vcluster
def FormatParamikoFingerprint(fingerprint):
......@@ -184,7 +185,17 @@ class SshRunner:
quiet=quiet))
if tty:
argv.extend(["-t", "-t"])
argv.extend(["%s@%s" % (user, hostname), command])
argv.append("%s@%s" % (user, hostname))
# Insert variables for virtual nodes
argv.extend("export %s=%s;" %
(utils.ShellQuote(name), utils.ShellQuote(value))
for (name, value) in
vcluster.EnvironmentForHost(hostname).items())
argv.append(command)
return argv
def Run(self, *args, **kwargs):
......@@ -225,7 +236,7 @@ class SshRunner:
if netutils.IP6Address.IsValid(node):
node = netutils.FormatAddress((node, None))
command.append("%s:%s" % (node, filename))
command.append("%s:%s" % (node, vcluster.ExchangeNodeRoot(node, filename)))
result = utils.RunCmd(command)
......@@ -255,7 +266,12 @@ class SshRunner:
- detail: string with details
"""
retval = self.Run(node, "root", "hostname --fqdn", quiet=False)
cmd = ("if test -z \"$GANETI_HOSTNAME\"; then"
" hostname --fqdn;"
"else"
" echo \"$GANETI_HOSTNAME\";"
"fi")
retval = self.Run(node, "root", cmd, quiet=False)
if retval.failed:
msg = "ssh problem"
......
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