def parse(self, value, kic_path=None): command_value = value[4:].strip() if not command_value: return {} paths = [] if command_value[0] == "[" and command_value[-1] == "]": try: paths = simplejson.loads(command_value.replace("\\", "\\\\")) except: raise Exception("invalid json array") if not paths: # if path has whitespace, quote it. and support multi paths paths = get_content_parts(command_value) if len(paths) == 1: raise Exception("target not found") args = [] files = [] for path in paths[:-1]: # the <src> allow remote file URL if "http://" in path or "https://" in path: urlinfo = urlparse.urlparse(path) filename = os.path.split(urlinfo["path"])[1] if ( ":" in filename or "?" in filename or "*" in filename or "\"" in filename or "<" in filename or ">" in filename or "/" in filename or "\\" in filename or "|" in filename ): raise Exception("the filename has special character") files.append( {"name": filename, "url": path} ) # if <dest> ends with a trailing slash /, it will be considered a directory if paths[-1][-1] == "/": to = "%s%s" % (paths[-1], filename) args.append({"from": filename, "to": to}) else: args.append({"from": filename, "to": paths[-1]}) continue if not os.path.isdir(path) and not os.path.isfile(path): kic_folder = os.path.dirname(kic_path) path = os.path.join(kic_folder, path) if not os.path.exists(path): raise Exception("%s not found" % path) # the <src> allow directory if os.path.isdir(path): files_info = get_files_info(path) files.extend(files_info) for file_info in files_info: # if <dest> ends with a trailing slash /, it will be considered a directory if paths[-1][-1] == "/": to = "%s%s" % (paths[-1], file_info["name"]) args.append({"from": file_info["name"], "to": to}) elif len(files_info) > 1: to = "%s/%s" % (paths[-1], file_info["name"]) args.append({"from": file_info["name"], "to": to}) else: args.append({"from": file_info["name"], "to": paths[-1]}) elif os.path.isfile(path): filedir, filename = os.path.split(path) files.append( {"name": filename, "url": path} ) # if <dest> ends with a trailing slash /, it will be considered a directory if paths[-1][-1] == "/": to = "%s%s" % (paths[-1], filename) args.append({"from": filename, "to": to}) elif len(paths) > 2: to = "%s/%s" % (paths[-1], filename) args.append({"from": filename, "to": to}) else: args.append({"from": filename, "to": paths[-1]}) return { "action": "ADD", "args": args, "images": [], "files": files }
def run(self, ssh_client, command, filesdir, imagesdir, cd, envs, ki_path=None): args = [] if isinstance(command["args"], dict): args = [command["args"]] elif isinstance(command["args"], list): args = command["args"] files_info = [] for arg in args: src = arg["from"] if "http://" in src or "https://" in src: urlinfo = urlparse.urlparse(src) filename = os.path.split(urlinfo["path"])[1] file_name, file_ext = os.path.splitext(filename) downloads_tmp_folder = os.path.join(self.kindo_tmps_path, "downloads") if not os.path.isdir(downloads_tmp_folder): os.makedirs(downloads_tmp_folder) # create unique tmpfile src = os.path.join(downloads_tmp_folder, "%s%s" % (get_md5(arg["from"]), file_ext)) if not os.path.isfile(src): download_with_progressbar(arg["from"], src) elif not os.path.isdir(src) and not os.path.isfile(src): src = os.path.join(self.startfolder, arg["from"]) if ( not os.path.exists(src) and "http://" not in arg["from"] and "https://" not in arg["from"] ): ki_folder = os.path.dirname(ki_path) src = os.path.join(ki_folder, arg["from"]) if os.path.isfile(src): if arg["to"][-1] == "/": filedir, filename = os.path.split(src) files_info.append({ "from": src, "to": "%s%s" % (arg["to"], filename) }) elif len(args) > 2: filedir, filename = os.path.split(src) files_info.append({ "from": src, "to": "%s/%s" % (arg["to"], filename) }) else: files_info.append({ "from": src, "to": arg["to"] }) elif os.path.isdir(src): files = get_files_info(src) for f in files: if arg["to"][-1] == "/": files_info.append({ "from": f["url"], "to": "%s%s" % (arg["to"], f["name"]) }) elif len(files) > 1: files_info.append({ "from": f["url"], "to": "%s/%s" % (arg["to"], f["name"]) }) else: files_info.append({ "from": f["url"], "to": arg["to"] }) for file_info in files_info: if len(ssh_client.put(file_info["from"], file_info["to"])) == 0: raise Exception("{0} upload failed".format(f)) return cd, envs