diff options
author | Ryo Nakamura <upa@haeena.net> | 2024-02-04 16:18:27 +0900 |
---|---|---|
committer | Ryo Nakamura <upa@haeena.net> | 2024-02-04 16:18:27 +0900 |
commit | d57ed4149d0e3bbcc09793bc00c6bd34fd2ca1fb (patch) | |
tree | 9d508883e59ca0967802da2635aea3e0e4f7e98e | |
parent | 7f5fcc617ca121876b1984da3989942807c3726f (diff) |
drop python binding support
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | CMakeLists.txt | 28 | ||||
-rw-r--r-- | Doxyfile | 2 | ||||
-rwxr-xr-x | debian/rules | 4 | ||||
-rw-r--r-- | docker/almalinux-8.8.Dockerfile | 5 | ||||
-rw-r--r-- | docker/alpine-3.17.Dockerfile | 3 | ||||
-rw-r--r-- | docker/rocky-8.8.Dockerfile | 5 | ||||
-rw-r--r-- | docker/ubuntu-20.04.Dockerfile | 4 | ||||
-rw-r--r-- | docker/ubuntu-22.04.Dockerfile | 5 | ||||
-rw-r--r-- | examples/.gitignore | 3 | ||||
-rw-r--r-- | examples/mscp-example.ipynb | 226 | ||||
-rwxr-xr-x | examples/mscp-python.py | 63 | ||||
-rw-r--r-- | mscp/__init__.py | 1 | ||||
-rw-r--r-- | mscp/mscp.py | 187 | ||||
-rw-r--r-- | pysetup.py | 37 | ||||
-rw-r--r-- | src/pymscp.c | 499 | ||||
-rw-r--r-- | test/test_python.py | 131 |
17 files changed, 2 insertions, 1205 deletions
@@ -5,7 +5,3 @@ CMakeUserPresets.json .*.swp include/mscp_version.h - -dist -*.egg-info -__pycache__ diff --git a/CMakeLists.txt b/CMakeLists.txt index 8335258..84b555b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,8 +52,6 @@ if (BUILD_STATIC) endif() -option(INSTALL_EXECUTABLE_ONLY OFF) # do not install libmscp - # add libssh static library set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) @@ -90,28 +88,9 @@ configure_file( ${mscp_SOURCE_DIR}/include/mscp_version.h.in ${mscp_SOURCE_DIR}/include/mscp_version.h) - -# libmscp.so +# libmscp.a set(LIBMSCP_SRC src/mscp.c src/ssh.c src/fileops.c src/path.c src/platform.c src/message.c) -add_library(mscp-shared SHARED ${LIBMSCP_SRC}) -target_include_directories(mscp-shared - PUBLIC $<BUILD_INTERFACE:${mscp_SOURCE_DIR}/include> - $<INSTALL_INTERFACE:include> - PRIVATE ${MSCP_BUILD_INCLUDE_DIRS}) -target_compile_options(mscp-shared PRIVATE ${MSCP_COMPILE_OPTS}) -target_link_libraries(mscp-shared PRIVATE ${MSCP_LINK_LIBS}) -set_target_properties(mscp-shared - PROPERTIES - OUTPUT_NAME mscp - PUBLIC_HEADER ${mscp_SOURCE_DIR}/include/mscp.h) - -if(!INSTALL_EXECUTABLE_ONLY) - install(TARGETS mscp-shared) -endif() - - -# libmscp.a add_library(mscp-static STATIC ${LIBMSCP_SRC}) target_include_directories(mscp-static PRIVATE ${MSCP_BUILD_INCLUDE_DIRS} ${mscp_SOURCE_DIR}/include) @@ -121,11 +100,6 @@ set_target_properties(mscp-static PROPERTIES OUTPUT_NAME mscp) -if(!INSTALL_EXECUTABLE_ONLY) - install(TARGETS mscp-static) -endif() - - # mscp executable list(APPEND MSCP_LINK_LIBS m pthread) @@ -9,5 +9,5 @@ GENERATE_MAN = NO SOURCE_BROWSER = YES -INPUT = src include mscp +INPUT = src include diff --git a/debian/rules b/debian/rules index 87da342..066fd81 100755 --- a/debian/rules +++ b/debian/rules @@ -4,10 +4,6 @@ dh $@ -override_dh_auto_configure: - dh_auto_configure -- \ - -DINSTALL_EXECUTABLE_ONLY=ON - override_dh_auto_test: diff --git a/docker/almalinux-8.8.Dockerfile b/docker/almalinux-8.8.Dockerfile index 1b440ce..5ff41ed 100644 --- a/docker/almalinux-8.8.Dockerfile +++ b/docker/almalinux-8.8.Dockerfile @@ -32,8 +32,3 @@ RUN cd ${mscpdir} \ && cpack -G RPM CPackConfig.cmake \ && rpm -iv *.rpm -# install mscp python module -RUN cd ${mscpdir} \ - && python3 pysetup.py install --user \ - && ldconfig - diff --git a/docker/alpine-3.17.Dockerfile b/docker/alpine-3.17.Dockerfile index 9fce2bd..b79510f 100644 --- a/docker/alpine-3.17.Dockerfile +++ b/docker/alpine-3.17.Dockerfile @@ -35,6 +35,3 @@ RUN cd ${mscpdir} \ && cp mscp /mscp/build/mscp_alpine-3.17-x86_64.static # copy mscp to PKG FILE NAME because this build doesn't use CPACK -# install mscp python module -RUN cd ${mscpdir} \ - && python3 pysetup.py install --user diff --git a/docker/rocky-8.8.Dockerfile b/docker/rocky-8.8.Dockerfile index 0345a4c..6140905 100644 --- a/docker/rocky-8.8.Dockerfile +++ b/docker/rocky-8.8.Dockerfile @@ -29,8 +29,3 @@ RUN cd ${mscpdir} \ && cpack -G RPM CPackConfig.cmake \ && rpm -iv *.rpm -# install mscp python module -RUN cd ${mscpdir} \ - && python3 pysetup.py install --user \ - && ldconfig - diff --git a/docker/ubuntu-20.04.Dockerfile b/docker/ubuntu-20.04.Dockerfile index 3c55ffe..c1da765 100644 --- a/docker/ubuntu-20.04.Dockerfile +++ b/docker/ubuntu-20.04.Dockerfile @@ -34,7 +34,3 @@ RUN cd ${mscpdir} \ && cpack -G DEB CPackConfig.cmake \ && dpkg -i *.deb -# install mscp python module -RUN cd ${mscpdir} \ - && python3 pysetup.py install --user \ - && ldconfig diff --git a/docker/ubuntu-22.04.Dockerfile b/docker/ubuntu-22.04.Dockerfile index c5d85d5..377cfff 100644 --- a/docker/ubuntu-22.04.Dockerfile +++ b/docker/ubuntu-22.04.Dockerfile @@ -33,8 +33,3 @@ RUN cd ${mscpdir} \ && cpack -G DEB CPackConfig.cmake \ && dpkg -i *.deb -# install mscp python module -RUN cd ${mscpdir} \ - && python3 pysetup.py install --user \ - && ldconfig - diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 9cef686..0000000 --- a/examples/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -simple-copy-dest -*.img -.ipynb_checkpoints diff --git a/examples/mscp-example.ipynb b/examples/mscp-example.ipynb deleted file mode 100644 index 915aeff..0000000 --- a/examples/mscp-example.ipynb +++ /dev/null @@ -1,226 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "ccda9e3a-35de-43fc-9b6e-02475c763f6b", - "metadata": {}, - "source": [ - "# mscp python binding example" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "df04d655-a082-47eb-9a1e-154ebc2a5655", - "metadata": {}, - "outputs": [], - "source": [ - "import glob\n", - "import time\n", - "import os\n", - "\n", - "import mscp" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "e9ed4519-c3fd-4639-89a5-1c1cdffd9519", - "metadata": {}, - "outputs": [], - "source": [ - "this_dir = os.getcwd()" - ] - }, - { - "cell_type": "markdown", - "id": "fee75bf8-df40-45f4-81d1-113069c34f13", - "metadata": {}, - "source": [ - "## Simple copy" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "2b06e6d3-30cc-47be-bd4f-af27eb141c8c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['../src/ssh.c',\n", - " '../src/mscp.c',\n", - " '../src/platform.c',\n", - " '../src/pymscp.c',\n", - " '../src/main.c',\n", - " '../src/path.c',\n", - " '../src/message.c',\n", - " '../src/fileops.c']" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# preparing files to be transferred\n", - "c_sources = glob.glob(\"../src/*.c\")\n", - "c_sources" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "89bb4558-9472-4d26-9af3-24f426b15edc", - "metadata": {}, - "outputs": [], - "source": [ - "# copy files using mscp\n", - "dst_dir = this_dir + \"/simple-copy-dest\"\n", - "m = mscp.mscp(\"localhost\", mscp.LOCAL2REMOTE)\n", - "m.copy(c_sources, dst_dir)" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "6daf2c98-8905-4039-b82a-a593df3107fe", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['ssh.c',\n", - " 'mscp.c',\n", - " 'platform.c',\n", - " 'pymscp.c',\n", - " 'main.c',\n", - " 'path.c',\n", - " 'message.c',\n", - " 'fileops.c']" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "os.listdir(\"simple-copy-dest\")" - ] - }, - { - "cell_type": "markdown", - "id": "f4a3869a-878e-43b0-9758-a049eaf8b5bd", - "metadata": {}, - "source": [ - "## Simple Copy with Python Rich ProgressBar" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "e7cb7cd6-b845-4d26-93ed-aee8ed3983ab", - "metadata": {}, - "outputs": [], - "source": [ - "# make a 256MB file\n", - "src = \"example-256MB-src.img\"\n", - "with open(src, \"wb\") as f:\n", - " f.seek(128 * 1024 * 1024 -1, 0)\n", - " f.write(b'1')" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "878607ed-5c06-4b15-81ac-9845dad0c9c6", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "b700e9fc00464969a22a26300404dc35", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Output()" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n" - ], - "text/plain": [] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n", - "</pre>\n" - ], - "text/plain": [ - "\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# copy the 256MB file while ploting progress bar using python rich\n", - "dst = this_dir + \"/example-256MB-dst.img\"\n", - "\n", - "kw = {\"nr_threads\": 1, \"nr_ahead\": 1} # slow mscp to watch the progress bar\n", - "\n", - "m = mscp.mscp(\"localhost\", mscp.LOCAL2REMOTE, **kw)\n", - "m.copy(src, dst, nonblock = True)\n", - "\n", - "# m.stats() returns total bytes to be transferred, bytes transferred (done), and finished (bool).\n", - "total, done, finished = m.stats()\n", - "with Progress() as progress:\n", - "\n", - " task = progress.add_task(f\"[green]Copying {src}\", total = total)\n", - "\n", - " while not progress.finished:\n", - " total, done, finished = m.stats()\n", - " progress.update(task, completed = done)\n", - " time.sleep(0.5)\n", - "\n", - "m.join()\n", - "m.cleanup()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/mscp-python.py b/examples/mscp-python.py deleted file mode 100755 index d1cb856..0000000 --- a/examples/mscp-python.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 -"""mscp.py - -An example python script running mscp -""" - -import argparse -import time -import sys - -from rich.progress import Progress - -import mscp - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("-f", "--from", dest = "fr", - metavar = "REMOTE", default = None, - help = "copy a file from this remote host") - parser.add_argument("-t", "--to", metavar = "REMOTE", default = None, - help = "copy a file to this remote host") - parser.add_argument("source", help = "path to source file to be copied") - parser.add_argument("destination", help = "path of copy destination") - - args = parser.parse_args() - - if args.fr and args.to: - print("-f and -t are exclusive", file = sys.stderr) - sys.exit(1) - elif args.fr: - d = mscp.REMOTE2LOCAL - remote = args.fr - elif args.to: - d = mscp.LOCAL2REMOTE - remote = args.to - else: - print("-f or -t must be specified", file = sys.stderr) - sys.exit(1) - - - m = mscp.mscp(remote, d) - m.connect() - m.add_src_path(args.source) - m.set_dst_path(args.destination) - m.scan() - m.start() - - total, done, finished = m.stats() - with Progress() as progress: - - task = progress.add_task("[green]Copying...", total = total) - - while not progress.finished: - total, done, finished = m.stats() - progress.update(task, completed = done) - time.sleep(0.5) - - m.join() - m.cleanup() - - -if __name__ == "__main__": - main() diff --git a/mscp/__init__.py b/mscp/__init__.py deleted file mode 100644 index 64b226b..0000000 --- a/mscp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from mscp.mscp import * diff --git a/mscp/mscp.py b/mscp/mscp.py deleted file mode 100644 index 5804791..0000000 --- a/mscp/mscp.py +++ /dev/null @@ -1,187 +0,0 @@ - -_retry_import_pymscp = False - -try: - import pymscp -except ImportError: - _retry_import_pymscp = True - -if _retry_import_pymscp: - """ libmscp.so is not installed on system library paths. So retry - to import libmscp.so installed on the mscp python module - directory. - """ - import os - import sys - import ctypes - - if sys.platform == "linux": - libmscp = "libmscp.so" - elif sys.platform == "darwin": - libmscp = "libmscp.dylib" - - mscp_dir = os.path.dirname(__file__) - ctypes.cdll.LoadLibrary("{}/{}".format(mscp_dir, libmscp)) - import pymscp - - -# inherit static values from pymscp -LOCAL2REMOTE = pymscp.LOCAL2REMOTE -REMOTE2LOCAL = pymscp.REMOTE2LOCAL -SEVERITY_NONE = pymscp.SEVERITY_NONE -SEVERITY_ERR = pymscp.SEVERITY_ERR -SEVERITY_WARN = pymscp.SEVERITY_WARN -SEVERITY_NOTICE = pymscp.SEVERITY_NOTICE -SEVERITY_INFO = pymscp.SEVERITY_INFO -SEVERITY_DEBUG = pymscp.SEVERITY_DEBUG - -STATE_INIT = 0 -STATE_CONNECTED = 1 -STATE_SCANNED = 2 -STATE_RUNNING = 3 -STATE_STOPPED = 4 -STATE_JOINED = 5 -STATE_CLEANED = 6 -STATE_RELEASED = 7 - -_state_str = { - STATE_INIT: "init", - STATE_CONNECTED: "connected", - STATE_SCANNED: "scanned", - STATE_RUNNING: "running", - STATE_STOPPED: "stopped", - STATE_JOINED: "joined", - STATE_CLEANED: "cleaned", - STATE_RELEASED: "released", -} - - -class mscp: - - - def __init__(self, remote: str, direction: int, **kwargs): - self.remote = remote - self.direction = direction - kwargs["remote"] = remote - kwargs["direction"] = direction - self.m = pymscp.mscp_init(**kwargs) - - self.src_paths = [] - self.dst_path = None - self.state = STATE_INIT - - def __str__(self): - if not hasattr(self, "state"): - # this instance failed on mscp_init - return "mscp:{}:init-failed" - return "mscp:{}:{}".format(self.remote, self.__state2str()) - - def __repr__(self): - return "<{}>".format(str(self)) - - def __del__(self): - - if not hasattr(self, "state"): - return # this instance failed on mscp_init - - if self.state == STATE_RUNNING: - self.stop() - if self.state == STATE_STOPPED: - self.join() - - self.cleanup() - self.release() - - def __state2str(self): - return _state_str[self.state] - - - def connect(self): - if not (self.state == STATE_INIT or state.state == STATE_CLEANED): - raise RuntimeError("invalid mscp state: {}".format(self.__state2str())) - pymscp.mscp_connect(m = self.m) - self.state = STATE_CONNECTED - - def add_src_path(self, src_path: str): - if type(src_path) != str: - raise ValueError("src_path must be str: {}".format(src_path)) - self.src_paths.append(src_path) - pymscp.mscp_add_src_path(m = self.m, src_path = src_path) - - def set_dst_path(self, dst_path: str): - if type(dst_path) != str: - raise ValueError("dst_path must be str: {}".format(dst_path)) - self.dst_path = dst_path - pymscp.mscp_set_dst_path(m = self.m, dst_path = dst_path); - - def scan(self): - if self.state == STATE_SCANNED: - return - if self.state != STATE_CONNECTED: - raise RuntimeError("invalid mscp state: {}".format(self.__state2str())) - if not self.src_paths: - raise RuntimeError("src path list is empty") - if self.dst_path == None: - raise RuntimeError("dst path is not set") - - pymscp.mscp_scan(m = self.m) - self.state = STATE_SCANNED - - def start(self): - if self.state != STATE_SCANNED: - raise RuntimeError("invalid mscp state: {}".format(self.__state2str())) - - pymscp.mscp_start(m = self.m) - self.state = STATE_RUNNING - - def stop(self): - if self.state != STATE_RUNNING: - raise RuntimeError("invalid mscp state: {}".format(self.__state2str())) - pymscp.mscp_stop(m = self.m) - self.state = STATE_STOPPED - - def join(self): - if self.state == STATE_JOINED: - return - if not (self.state == STATE_RUNNING or self.state == STATE_STOPPED): - raise RuntimeError("invalid mscp state: {}".format(self.__state2str())) - pymscp.mscp_join(m = self.m) - self.state = STATE_JOINED - - def stats(self): - return pymscp.mscp_get_stats(m = self.m) - - def cleanup(self): - if self.state == STATE_RUNNING: - raise RuntimeError("invalid mscp state: {}".format(self.__state2str())) - pymscp.mscp_cleanup(m = self.m) - self.state = STATE_CLEANED - - def release(self): - if self.state != STATE_CLEANED: - raise RuntimeError("invalid mscp state: {}".format(self.__state2str())) - pymscp.mscp_free(m = self.m) - self.state = STATE_RELEASED - - # Simple interface: mscp.copy(src, dst) - def copy(self, src, dst, nonblock = False): - if self.state < STATE_CONNECTED: - self.connect() - - if type(src) == list: - for path in src: - self.add_src_path(path) - elif type(src) == str: - self.add_src_path(src) - else: - raise ValueError("src must be str of list: '{}'".format(src)) - - self.set_dst_path(dst) - - self.scan() - self.start() - if nonblock: - return - - self.join() - self.cleanup() diff --git a/pysetup.py b/pysetup.py deleted file mode 100644 index 67bb2a3..0000000 --- a/pysetup.py +++ /dev/null @@ -1,37 +0,0 @@ -from setuptools import setup, Extension, find_packages -import sys -import os - -mypackage_root_dir = os.path.dirname(__file__) -with open(os.path.join(mypackage_root_dir, 'VERSION')) as version_file: - version = version_file.read().strip() - -if sys.platform == "linux": - libmscp = "libmscp.so" -elif sys.platform == "darwin": - libmscp = "libmscp.dylib" - -data_dir = sys.prefix + "/lib" -libmscp = "build/" + libmscp - -setup( - name='mscp', - version = version, - description = "libmscp python binding", - author = "Ryo Nakamura", - author_email = "upa@haeena.net", - url = "https://github.com/upa/mscp", - packages = find_packages("mscp"), - package_dir = {"": "mscp"}, - data_files = [ (data_dir, [libmscp])], - py_modules = [ "mscp" ], - ext_modules = [ - Extension( - 'pymscp', - ['src/pymscp.c'], - library_dirs = ['build'], - libraries = ['mscp'], - include_dirs = ['include'] - ) - ] -) diff --git a/src/pymscp.c b/src/pymscp.c deleted file mode 100644 index 6c7f628..0000000 --- a/src/pymscp.c +++ /dev/null @@ -1,499 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-only */ -#define PY_SSIZE_T_CLEAN -#include <Python.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <mscp.h> - -/* - * This is a wrapper for python binding of libmscp. setup.py builds - * pymscp.c after libmscp was built, and setup.py installs pymscp - * modlue and mscp python module (mscp/mscp.py), which is a warpper - * for pymscp. - */ - -#define MAX_MSCP_INSTS 64 - -/* XXX: cut corners */ -struct instance { - struct mscp_opts mo; - struct mscp_ssh_opts so; - struct mscp *m; -}; - -struct instance *insts[MAX_MSCP_INSTS]; - -static int add_instance(struct instance *i) -{ - int n; - for (n = 0; n < MAX_MSCP_INSTS; n++) { - if (insts[n] == NULL) { - insts[n] = i; - return 0; - } - } - - return -1; /* full of mscp instances */ -} - -static struct instance *get_instance(unsigned long long addr) -{ - int n; - for (n = 0; n < MAX_MSCP_INSTS; n++) { - if (insts[n] == (void *)addr) - return insts[n]; - } - - return NULL; -} - -static struct mscp *get_mscp(unsigned long long addr) -{ - struct instance *i = get_instance(addr); - - if (!i) - return NULL; - return i->m; -} - -static int release_instance(struct instance *i) -{ - int n; - for (n = 0; n < MAX_MSCP_INSTS; n++) { - if (insts[n] == i) { - insts[n] = NULL; - return 0; - } - } - - free(i); - - return -1; -} - - -/* wrapper functions */ - -static PyObject *wrap_mscp_init(PyObject *self, PyObject *args, PyObject *kw) -{ - /* - * Initialize struct mscp with options. wrap_mscp_init - * receives all the arguments with keywords. - */ - - char *remote; - char *keywords[] = { - "remote", /* const char * */ - "direction", /* int, MSCP_DIRECTION_L2R or MSCP_DIRECTION_R2L */ - - /* mscp_opts */ - "nr_threads", /* int */ - "nr_ahead", /* int */ - - "min_chunk_sz", /* unsigned long */ - "max_chunk_sz", /* unsigned long */ - "buf_sz", /* unsigned long */ - - "coremask", /* const char * */ - - "max_startups", /* int */ - "interval", /* int */ - "severity", /* int, MSCP_SERVERITY_* */ - "msg_fd", /* int */ - - /* mscp_ssh_opts */ - "login_name", /* const char * */ - "port", /* const char * */ - "config", /* const char * */ - "identity", /* const char * */ - - "cipher", /* const char * */ - "hmac", /* const char * */ - "compress", /* const char * */ - "ccalgo", /* const char * */ - "password", /* const char * */ - "passphrase", /* const char * */ - - "debug_level", /* int */ - "no_hostkey_check", /* bool */ - "enable_nagle", /* bool */ - NULL, - }; - const char *fmt = "si" "|" "ii" "kkk" "s" "iiii" "ssss" "ssssss" "ipp"; - char *coremask = NULL; - char *login_name = NULL, *port = NULL, *config = NULL, *identity = NULL; - char *cipher = NULL, *hmac = NULL, *compress = NULL, *ccalgo = NULL; - char *password = NULL, *passphrase = NULL; - - struct instance *i; - int direction; - int ret; - - i = malloc(sizeof(*i)); - if (!i) { - PyErr_Format(PyExc_RuntimeError, strerror(errno)); - return NULL; - } - - memset(i, 0, sizeof(*i)); - - ret = PyArg_ParseTupleAndKeywords(args, kw, fmt, keywords, - &remote, - &direction, - &i->mo.nr_threads, - &i->mo.nr_ahead, - &i->mo.min_chunk_sz, - &i->mo.max_chunk_sz, - &i->mo.buf_sz, - &coremask, - &i->mo.max_startups, - &i->mo.interval, - &i->mo.severity, - &i->mo.msg_fd, - &login_name, - &port, - &config, - &identity, - &cipher, - &hmac, - &compress, - &ccalgo, - &password, - &passphrase, - &i->so.debug_level, - &i->so.no_hostkey_check, - &i->so.enable_nagle); - - if (!ret) - return NULL; - - if (coremask) - strncpy(i->mo.coremask, coremask, MSCP_MAX_COREMASK_STR - 1); - if (login_name) - strncpy(i->so.login_name, login_name, MSCP_SSH_MAX_LOGIN_NAME - 1); - if (port) - strncpy(i->so.port, port, MSCP_SSH_MAX_PORT_STR - 1); - if (config) - strncpy(i->so.config, config, PATH_MAX - 1); - if (identity) - strncpy(i->so.identity, identity, MSCP_SSH_MAX_IDENTITY_PATH - 1); - if (cipher) - strncpy(i->so.cipher, cipher, MSCP_SSH_MAX_CIPHER_STR - 1); - if (hmac) - strncpy(i->so.hmac, hmac, MSCP_SSH_MAX_HMAC_STR - 1); - if (compress) - strncpy(i->so.compress, compress, MSCP_SSH_MAX_COMP_STR - 1); - if (ccalgo) - strncpy(i->so.ccalgo, ccalgo, MSCP_SSH_MAX_CCALGO_STR - 1); - if (password) - strncpy(i->so.password, password, MSCP_SSH_MAX_PASSWORD - 1); - if (passphrase) - strncpy(i->so.passphrase, passphrase, MSCP_SSH_MAX_PASSPHRASE - 1); - - i->m = mscp_init(remote, direction, &i->mo, &i->so); - if (!i->m) { - PyErr_Format(PyExc_RuntimeError, "%s", mscp_get_error()); - free(i); - return NULL; - } - - if (add_instance(i) < 0) { - PyErr_Format(PyExc_RuntimeError, "too many mscp isntances"); - mscp_free(i->m); - free(i); - return NULL; - } - - return Py_BuildValue("K", (unsigned long long)i); -} - -static PyObject *wrap_mscp_connect(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - if (mscp_connect(m) < 0) { - PyErr_Format(PyExc_RuntimeError, mscp_get_error()); - return NULL; - } - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_add_src_path(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", "src_path", NULL }; - unsigned long long addr; - char *src_path; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "Ks", keywords, &addr, &src_path)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - if (mscp_add_src_path(m, src_path) < 0) { - PyErr_Format(PyExc_RuntimeError, mscp_get_error()); - return NULL; - } - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_set_dst_path(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", "dst_path", NULL }; - unsigned long long addr; - char *dst_path; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "Ks", keywords, &addr, &dst_path)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - if (mscp_set_dst_path(m, dst_path) < 0) { - PyErr_Format(PyExc_RuntimeError, mscp_get_error()); - return NULL; - } - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_scan(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - if (mscp_scan(m) < 0) { - PyErr_Format(PyExc_RuntimeError, mscp_get_error()); - return NULL; - } - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_start(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - if (mscp_start(m) < 0) { - PyErr_Format(PyExc_RuntimeError, mscp_get_error()); - return NULL; - } - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_stop(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - mscp_stop(m); - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_join(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - if (mscp_join(m) < 0) { - PyErr_Format(PyExc_RuntimeError, mscp_get_error()); - return NULL; - } - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_get_stats(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct mscp_stats s; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - mscp_get_stats(m, &s); - - return Py_BuildValue("KKO", s.total, s.done, PyBool_FromLong(s.finished)); -} - -static PyObject *wrap_mscp_cleanup(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct mscp *m; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - m = get_mscp(addr); - if (!m) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - mscp_cleanup(m); - - return Py_BuildValue(""); -} - -static PyObject *wrap_mscp_free(PyObject *self, PyObject *args, PyObject *kw) -{ - char *keywords[] = { "m", NULL }; - unsigned long long addr; - struct instance *i; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "K", keywords, &addr)) - return NULL; - - i = get_instance(addr); - if (!i) { - PyErr_Format(PyExc_RuntimeError, "invalid mscp instance address"); - return NULL; - } - - mscp_free(i->m); - release_instance(i); - - return Py_BuildValue(""); -} - -static PyMethodDef pymscpMethods[] = { - { - "mscp_init", (PyCFunction)wrap_mscp_init, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_connect", (PyCFunction)wrap_mscp_connect, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_add_src_path", (PyCFunction)wrap_mscp_add_src_path, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_set_dst_path", (PyCFunction)wrap_mscp_set_dst_path, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_scan", (PyCFunction)wrap_mscp_scan, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_start", (PyCFunction)wrap_mscp_start, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_stop", (PyCFunction)wrap_mscp_stop, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_join", (PyCFunction)wrap_mscp_join, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_get_stats", (PyCFunction)wrap_mscp_get_stats, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_cleanup", (PyCFunction)wrap_mscp_cleanup, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { - "mscp_free", (PyCFunction)wrap_mscp_free, - METH_VARARGS | METH_KEYWORDS, NULL - }, - { NULL, NULL, 0, NULL }, -}; - -static PyModuleDef pymscpModule = { - PyModuleDef_HEAD_INIT, "pymscp", NULL, -1, pymscpMethods, -}; - -PyMODINIT_FUNC PyInit_pymscp(void) { - PyObject *mod = PyModule_Create(&pymscpModule); - - PyModule_AddIntConstant(mod, "LOCAL2REMOTE", MSCP_DIRECTION_L2R); - PyModule_AddIntConstant(mod, "REMOTE2LOCAL", MSCP_DIRECTION_R2L); - PyModule_AddIntConstant(mod, "SEVERITY_NONE", MSCP_SEVERITY_NONE); - PyModule_AddIntConstant(mod, "SEVERITY_ERR", MSCP_SEVERITY_ERR); - PyModule_AddIntConstant(mod, "SEVERITY_WARN", MSCP_SEVERITY_WARN); - PyModule_AddIntConstant(mod, "SEVERITY_NOTICE", MSCP_SEVERITY_NOTICE); - PyModule_AddIntConstant(mod, "SEVERITY_INFO", MSCP_SEVERITY_INFO); - PyModule_AddIntConstant(mod, "SEVERITY_DEBUG", MSCP_SEVERITY_DEBUG); - - return mod; -} - diff --git a/test/test_python.py b/test/test_python.py deleted file mode 100644 index 22d778a..0000000 --- a/test/test_python.py +++ /dev/null @@ -1,131 +0,0 @@ - -""" -test_python.py: Testing libmscp through the mscp python binding. -""" - -import pytest -import mscp -import os -from util import File, check_same_md5sum - -def test_create_and_release(): - m = mscp.mscp("localhost", mscp.LOCAL2REMOTE) - m.cleanup() - - -""" copy test """ - -remote = "localhost" -remote_prefix = "{}/".format(os.getcwd()) # use current dir -param_remote_prefix_and_direction = [ - ("", remote_prefix, mscp.LOCAL2REMOTE), (remote_prefix, "", mscp.REMOTE2LOCAL) -] - - -param_single_copy = [ - (File("src", size = 64), File("dst")), - (File("src", size = 4096 * 1), File("dst")), - (File("src", size = 128 * 1024 * 1024), File("dst")), -] - -@pytest.mark.parametrize("src_prefix, dst_prefix, direction", - param_remote_prefix_and_direction) -@pytest.mark.parametrize("src, dst", param_single_copy) -def test_single_copy(src_prefix, dst_prefix, direction, src, dst): - src.make() - m = mscp.mscp(remote, direction) - m.copy(src_prefix + src.path, dst_prefix + dst.path) - assert check_same_md5sum(src, dst) - src.cleanup() - dst.cleanup() - - -param_double_copy = [ - (File("src1", size = 1024 * 1024), File("src2", size = 1024 * 1024), - File("dst/src1"), File("dst/src2") - ) -] -@pytest.mark.parametrize("src_prefix, dst_prefix, direction", - param_remote_prefix_and_direction) -@pytest.mark.parametrize("s1, s2, d1, d2", param_double_copy) -def test_double_copy(src_prefix, dst_prefix, direction, s1, s2, d1, d2): - s1.make() - s2.make() - mscp.mscp(remote, direction).copy([src_prefix + s1.path, src_prefix + s2.path], - dst_prefix + "dst") - assert check_same_md5sum(s1, d1) - assert check_same_md5sum(s2, d2) - s1.cleanup() - s2.cleanup() - d1.cleanup() - d2.cleanup() - - -param_single_copy = [ - (File("src", size = 1024 * 1024 * 4), File("dst")), -] - -param_kwargs = [ - { "nr_threads": 6 }, - { "nr_ahead": 64 }, - { "min_chunk_sz": 1 * 1024 * 1024 }, - { "max_chunk_sz": 64 * 1024 * 1024 }, - { "coremask": "0x0f" }, - { "max_startups": 5 }, - { "severity": mscp.SEVERITY_NONE }, - { "cipher": "aes128-gcm@openssh.com" }, - { "compress": "yes" }, - { "no_hostkey_check": True }, - { "enable_nagle": True }, -] - -@pytest.mark.parametrize("src_prefix, dst_prefix, direction", - param_remote_prefix_and_direction) -@pytest.mark.parametrize("src, dst", param_single_copy) -@pytest.mark.parametrize("kw", param_kwargs) -def test_kwargs(src_prefix, dst_prefix, direction, src, dst, kw): - src.make() - m = mscp.mscp(remote, direction, **kw) - m.copy(src_prefix + src.path, dst_prefix + dst.path) - assert check_same_md5sum(src, dst) - src.cleanup() - dst.cleanup() - -def test_login_failed(): - m = mscp.mscp("asdfasdf@" + remote, mscp.LOCAL2REMOTE) - with pytest.raises(RuntimeError) as e: - m.connect() - - m = mscp.mscp(remote, mscp.LOCAL2REMOTE, login_name = "asdfadsf") - with pytest.raises(RuntimeError) as e: - m.connect() - - m = mscp.mscp(remote, mscp.LOCAL2REMOTE, port = "65534") - with pytest.raises(RuntimeError) as e: - m.connect() - -def test_get_stat_before_copy_start(): - m = mscp.mscp("localhost", mscp.LOCAL2REMOTE) - m.connect() - (total, done, finished) = m.stats() - assert total == 0 and done == 0 - - -param_invalid_kwargs = [ - { "nr_threads": -1 }, - { "nr_ahead": -1 }, - { "min_chunk_sz": 1 }, - { "max_chunk_sz": 1 }, - { "coremask": "xxxxx" }, - { "max_startups": -1 }, - { "cipher": "invalid" }, - { "hmac": "invalid"}, - { "compress": "invalid"}, - { "ccalgo": "invalid"}, -] - -@pytest.mark.parametrize("kw", param_invalid_kwargs) -def test_invalid_options(kw): - with pytest.raises(RuntimeError) as e: - m = mscp.mscp("localhost", mscp.LOCAL2REMOTE, **kw) - m.connect() |