X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fnepi%2Fresources%2Flinux%2Fnode.py;h=13cf07676667e8d82a96beaec5c950e2013dae6e;hb=071f62fddeabab808850b303249adaaf84747c4c;hp=f9ae091cc5715b28b694a6a6ca6e0123f4e1e66e;hpb=2efd5eabeba8a6577ace9132d6336d44be0510e8;p=nepi.git diff --git a/src/nepi/resources/linux/node.py b/src/nepi/resources/linux/node.py index f9ae091c..13cf0767 100644 --- a/src/nepi/resources/linux/node.py +++ b/src/nepi/resources/linux/node.py @@ -233,9 +233,13 @@ class LinuxNode(ResourceManager): home = os.path.join(self._home_dir, home) return home + @property + def nepi_home(self): + return os.path.join(self.home_dir, ".nepi") + @property def usr_dir(self): - return os.path.join(self.home_dir, "nepi-usr") + return os.path.join(self.nepi_home, "nepi-usr") @property def lib_dir(self): @@ -255,7 +259,7 @@ class LinuxNode(ResourceManager): @property def exp_dir(self): - return os.path.join(self.home_dir, "nepi-exp") + return os.path.join(self.nepi_home, "nepi-exp") @property def exp_home(self): @@ -274,7 +278,8 @@ class LinuxNode(ResourceManager): if self._os: return self._os - if (not self.get("hostname") or not self.get("username")): + if self.get("hostname") not in ["localhost", "127.0.0.1"] and \ + not self.get("username"): msg = "Can't resolve OS, insufficient data " self.error(msg) raise RuntimeError, msg @@ -348,14 +353,14 @@ class LinuxNode(ResourceManager): if self.get("cleanExperiment"): self.clean_experiment() - # Create shared directory structure - self.mkdir(self.lib_dir) - self.mkdir(self.bin_dir) - self.mkdir(self.src_dir) - self.mkdir(self.share_dir) + # Create shared directory structure and node home directory + paths = [self.lib_dir, + self.bin_dir, + self.src_dir, + self.share_dir, + self.node_home] - # Create experiment node home directory - self.mkdir(self.node_home) + self.mkdir(paths) super(LinuxNode, self).do_provision() @@ -400,9 +405,11 @@ class LinuxNode(ResourceManager): def clean_processes(self): self.info("Cleaning up processes") + if self.get("hostname") in ["localhost", "127.0.0.2"]: + return + if self.get("username") != 'root': cmd = ("sudo -S killall tcpdump || /bin/true ; " + - "sudo -S kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; " + "sudo -S killall -u %s || /bin/true ; " % self.get("username")) else: if self.state >= ResourceState.READY: @@ -424,7 +431,6 @@ class LinuxNode(ResourceManager): cmd = ("killall tcpdump || /bin/true ; " + "kill $(ps aux | grep '[n]epi' | awk '{print $2}') || /bin/true ; ") - out = err = "" (out, err), proc = self.execute(cmd, retry = 1, with_lock = True) def clean_home(self): @@ -432,7 +438,7 @@ class LinuxNode(ResourceManager): """ self.info("Cleaning up home") - cmd = "cd %s ; find . -maxdepth 1 \( -name 'nepi-usr' -o -name 'nepi-exp' \) -execdir rm -rf {} + " % ( + cmd = "cd %s ; find . -maxdepth 1 -name \.nepi -execdir rm -rf {} + " % ( self.home_dir ) return self.execute(cmd, with_lock = True) @@ -534,14 +540,13 @@ class LinuxNode(ResourceManager): self.debug("Running command '%s'" % command) if self.localhost: - (out, err), proc = execfuncs.lspawn(command, pidfile, - stdout = stdout, - stderr = stderr, - stdin = stdin, + (out, err), proc = execfuncs.lspawn(command, pidfile, home = home, create_home = create_home, - sudo = sudo, - user = user) + stdin = stdin or '/dev/null', + stdout = stdout or '/dev/null', + stderr = stderr or '/dev/null', + sudo = sudo) else: with self._node_lock: (out, err), proc = sshfuncs.rspawn( @@ -549,9 +554,9 @@ class LinuxNode(ResourceManager): pidfile = pidfile, home = home, create_home = create_home, - stdin = stdin if stdin is not None else '/dev/null', - stdout = stdout if stdout else '/dev/null', - stderr = stderr if stderr else '/dev/null', + stdin = stdin or '/dev/null', + stdout = stdout or '/dev/null', + stderr = stderr or '/dev/null', sudo = sudo, host = self.get("hostname"), user = self.get("username"), @@ -631,9 +636,8 @@ class LinuxNode(ResourceManager): def copy(self, src, dst): if self.localhost: - (out, err), proc = execfuncs.lcopy(source, dest, - recursive = True, - strict_host_checking = False) + (out, err), proc = execfuncs.lcopy(src, dst, + recursive = True) else: with self._node_lock: (out, err), proc = sshfuncs.rcopy( @@ -648,7 +652,8 @@ class LinuxNode(ResourceManager): return (out, err), proc - def upload(self, src, dst, text = False, overwrite = True): + def upload(self, src, dst, text = False, overwrite = True, + raise_on_error = True): """ Copy content to destination src string with the content to copy. Can be: @@ -676,7 +681,7 @@ class LinuxNode(ResourceManager): # If dst files should not be overwritten, check that the files do not # exits already if isinstance(src, str): - src = map(str.strip, src.split(";")) + src = map(os.path.expanduser, map(str.strip, src.split(";"))) if overwrite == False: src = self.filter_existing_files(src, dst) @@ -687,19 +692,36 @@ class LinuxNode(ResourceManager): # Build destination as @: dst = "%s@%s:%s" % (self.get("username"), self.get("hostname"), dst) - result = self.copy(src, dst) + ((out, err), proc) = self.copy(src, dst) # clean up temp file if f: os.remove(f.name) - return result + if err: + msg = " Failed to upload files - src: %s dst: %s" % (";".join(src), dst) + self.error(msg, out, err) + + if raise_on_error: + raise RuntimeError, msg - def download(self, src, dst): + return ((out, err), proc) + + def download(self, src, dst, raise_on_error = True): if not self.localhost: # Build destination as @: src = "%s@%s:%s" % (self.get("username"), self.get("hostname"), src) - return self.copy(src, dst) + + ((out, err), proc) = self.copy(src, dst) + + if err: + msg = " Failed to download files - src: %s dst: %s" % (";".join(src), dst) + self.error(msg, out, err) + + if raise_on_error: + raise RuntimeError, msg + + return ((out, err), proc) def install_packages_command(self, packages): command = "" @@ -714,7 +736,8 @@ class LinuxNode(ResourceManager): return command - def install_packages(self, packages, home, run_home = None): + def install_packages(self, packages, home, run_home = None, + raise_on_error = True): """ Install packages in the Linux host. 'home' is the directory to upload the package installation script. @@ -731,11 +754,12 @@ class LinuxNode(ResourceManager): stdout = "instpkg_stdout", stderr = "instpkg_stderr", overwrite = False, - raise_on_error = True) + raise_on_error = raise_on_error) return (out, err), proc - def remove_packages(self, packages, home, run_home = None): + def remove_packages(self, packages, home, run_home = None, + raise_on_error = True): """ Uninstall packages from the Linux host. 'home' is the directory to upload the package un-installation script. @@ -759,18 +783,35 @@ class LinuxNode(ResourceManager): stdout = "rmpkg_stdout", stderr = "rmpkg_stderr", overwrite = False, - raise_on_error = True) + raise_on_error = raise_on_error) return (out, err), proc - def mkdir(self, path, clean = False): + def mkdir(self, paths, clean = False): + """ Paths is either a single remote directory path to create, + or a list of directories to create. + """ if clean: - self.rmdir(path) + self.rmdir(paths) + + if isinstance(paths, str): + paths = [paths] - return self.execute("mkdir -p %s" % path, with_lock = True) + cmd = " ; ".join(map(lambda path: "mkdir -p %s" % path, paths)) - def rmdir(self, path): - return self.execute("rm -rf %s" % path, with_lock = True) + return self.execute(cmd, with_lock = True) + + def rmdir(self, paths): + """ Paths is either a single remote directory path to delete, + or a list of directories to delete. + """ + + if isinstance(paths, str): + paths = [paths] + + cmd = " ; ".join(map(lambda path: "rm -rf %s" % path, paths)) + + return self.execute(cmd, with_lock = True) def run_and_wait(self, command, home, shfile = "cmd.sh", @@ -783,7 +824,7 @@ class LinuxNode(ResourceManager): stderr = "stderr", sudo = False, tty = False, - raise_on_error = False): + raise_on_error = True): """ Uploads the 'command' to a bash script in the host. Then runs the script detached in background in the host, and @@ -1037,8 +1078,7 @@ class LinuxNode(ResourceManager): """ Removes files that already exist in the Linux host from src list """ # construct a dictionary with { dst: src } - dests = dict(map( - lambda s: (os.path.join(dst, os.path.basename(s)), s ), s)) \ + dests = dict(map(lambda s: (os.path.join(dst, os.path.basename(s)), s), src)) \ if len(src) > 1 else dict({dst: src[0]}) command = []