Compare commits

..

No commits in common. "bb77c5f1fceaca3dda056b7b1e1ae454348c7be0" and "60967b56063ea63511a9bc253a9117e4c7d703f9" have entirely different histories.

10 changed files with 66 additions and 77 deletions

1
.gitignore vendored
View File

@ -8,4 +8,3 @@ debian/pvc-*/
debian/*.log debian/*.log
debian/*.substvars debian/*.substvars
debian/files debian/files
client-cli/build/

View File

@ -25,6 +25,7 @@ from functools import wraps
from json import dump as jdump from json import dump as jdump
from json import dumps as jdumps from json import dumps as jdumps
from json import loads as jloads from json import loads as jloads
from lxml.etree import fromstring, tostring
from os import environ, makedirs, path from os import environ, makedirs, path
from re import sub, match from re import sub, match
from yaml import load as yload from yaml import load as yload
@ -1191,8 +1192,6 @@ def cli_vm_define(
# Verify our XML is sensible # Verify our XML is sensible
try: try:
from lxml.etree import fromstring, tostring
xml_data = fromstring(vmconfig_data) xml_data = fromstring(vmconfig_data)
new_cfg = tostring(xml_data, pretty_print=True).decode("utf8") new_cfg = tostring(xml_data, pretty_print=True).decode("utf8")
except Exception: except Exception:
@ -1378,9 +1377,6 @@ def cli_vm_modify(
# Grab the current config # Grab the current config
current_vm_cfg_raw = vm_information.get("xml") current_vm_cfg_raw = vm_information.get("xml")
from lxml.etree import fromstring, tostring
xml_data = fromstring(current_vm_cfg_raw) xml_data = fromstring(current_vm_cfg_raw)
current_vm_cfgfile = tostring(xml_data, pretty_print=True).decode("utf8").strip() current_vm_cfgfile = tostring(xml_data, pretty_print=True).decode("utf8").strip()
@ -1439,8 +1435,6 @@ def cli_vm_modify(
# Verify our XML is sensible # Verify our XML is sensible
try: try:
from lxml.etree import fromstring, tostring
xml_data = fromstring(new_vm_cfgfile) xml_data = fromstring(new_vm_cfgfile)
new_cfg = tostring(xml_data, pretty_print=True).decode("utf8") new_cfg = tostring(xml_data, pretty_print=True).decode("utf8")
except Exception as e: except Exception as e:
@ -3271,9 +3265,6 @@ def cli_vm_dump(filename, domain):
finish(False, 'ERROR: Could not find VM "{}"!'.format(domain)) finish(False, 'ERROR: Could not find VM "{}"!'.format(domain))
current_vm_cfg_raw = retdata.get("xml") current_vm_cfg_raw = retdata.get("xml")
from lxml.etree import fromstring, tostring
xml_data = fromstring(current_vm_cfg_raw) xml_data = fromstring(current_vm_cfg_raw)
current_vm_cfgfile = tostring(xml_data, pretty_print=True).decode("utf8") current_vm_cfgfile = tostring(xml_data, pretty_print=True).decode("utf8")
xml = current_vm_cfgfile.strip() xml = current_vm_cfgfile.strip()

View File

@ -20,6 +20,7 @@
############################################################################### ###############################################################################
from click import echo as click_echo from click import echo as click_echo
from distutils.util import strtobool
from json import load as jload from json import load as jload
from json import dump as jdump from json import dump as jdump
from os import chmod, environ, getpid, path, get_terminal_size from os import chmod, environ, getpid, path, get_terminal_size
@ -149,7 +150,9 @@ def get_config(store_data, connection=None):
if connection == "local": if connection == "local":
config["verify_ssl"] = False config["verify_ssl"] = False
else: else:
config["verify_ssl"] = environ.get("PVC_CLIENT_VERIFY_SSL", "True") == "True" config["verify_ssl"] = bool(
strtobool(environ.get("PVC_CLIENT_VERIFY_SSL", "True"))
)
return config return config

View File

@ -19,13 +19,12 @@
# #
############################################################################### ###############################################################################
import os
import math
import time
import requests
import click
from ast import literal_eval from ast import literal_eval
from click import echo, progressbar
from math import ceil
from os.path import getsize
from requests import get, post, put, patch, delete, Response
from requests.exceptions import ConnectionError
from time import time
from urllib3 import disable_warnings from urllib3 import disable_warnings
@ -40,7 +39,7 @@ def format_bytes(size_bytes):
} }
human_bytes = "0B" human_bytes = "0B"
for unit in sorted(byte_unit_matrix, key=byte_unit_matrix.get): for unit in sorted(byte_unit_matrix, key=byte_unit_matrix.get):
formatted_bytes = int(ceil(size_bytes / byte_unit_matrix[unit])) formatted_bytes = int(math.ceil(size_bytes / byte_unit_matrix[unit]))
if formatted_bytes < 10000: if formatted_bytes < 10000:
human_bytes = "{}{}".format(formatted_bytes, unit) human_bytes = "{}{}".format(formatted_bytes, unit)
break break
@ -58,7 +57,7 @@ def format_metric(integer):
} }
human_integer = "0" human_integer = "0"
for unit in sorted(integer_unit_matrix, key=integer_unit_matrix.get): for unit in sorted(integer_unit_matrix, key=integer_unit_matrix.get):
formatted_integer = int(ceil(integer / integer_unit_matrix[unit])) formatted_integer = int(math.ceil(integer / integer_unit_matrix[unit]))
if formatted_integer < 10000: if formatted_integer < 10000:
human_integer = "{}{}".format(formatted_integer, unit) human_integer = "{}{}".format(formatted_integer, unit)
break break
@ -98,12 +97,12 @@ def format_age(age_secs):
class UploadProgressBar(object): class UploadProgressBar(object):
def __init__(self, filename, end_message="", end_nl=True): def __init__(self, filename, end_message="", end_nl=True):
file_size = getsize(filename) file_size = os.path.getsize(filename)
file_size_human = format_bytes(file_size) file_size_human = format_bytes(file_size)
echo("Uploading file (total size {})...".format(file_size_human)) click.echo("Uploading file (total size {})...".format(file_size_human))
self.length = file_size self.length = file_size
self.time_last = int(round(time() * 1000)) - 1000 self.time_last = int(round(time.time() * 1000)) - 1000
self.bytes_last = 0 self.bytes_last = 0
self.bytes_diff = 0 self.bytes_diff = 0
self.is_end = False self.is_end = False
@ -115,7 +114,7 @@ class UploadProgressBar(object):
else: else:
self.end_suffix = "" self.end_suffix = ""
self.bar = progressbar(length=self.length, width=20, show_eta=True) self.bar = click.progressbar(length=self.length, width=20, show_eta=True)
def update(self, monitor): def update(self, monitor):
bytes_cur = monitor.bytes_read bytes_cur = monitor.bytes_read
@ -124,7 +123,7 @@ class UploadProgressBar(object):
self.is_end = True self.is_end = True
self.bytes_last = bytes_cur self.bytes_last = bytes_cur
time_cur = int(round(time() * 1000)) time_cur = int(round(time.time() * 1000))
if (time_cur - 1000) > self.time_last: if (time_cur - 1000) > self.time_last:
self.time_last = time_cur self.time_last = time_cur
self.bar.update(self.bytes_diff) self.bar.update(self.bytes_diff)
@ -133,13 +132,13 @@ class UploadProgressBar(object):
if self.is_end: if self.is_end:
self.bar.update(self.bytes_diff) self.bar.update(self.bytes_diff)
self.bytes_diff = 0 self.bytes_diff = 0
echo() click.echo()
echo() click.echo()
if self.end_message: if self.end_message:
echo(self.end_message + self.end_suffix, nl=self.end_nl) click.echo(self.end_message + self.end_suffix, nl=self.end_nl)
class ErrorResponse(Response): class ErrorResponse(requests.Response):
def __init__(self, json_data, status_code, headers): def __init__(self, json_data, status_code, headers):
self.json_data = json_data self.json_data = json_data
self.status_code = status_code self.status_code = status_code
@ -179,7 +178,7 @@ def call_api(
for i in range(3): for i in range(3):
failed = False failed = False
try: try:
response = get( response = requests.get(
uri, uri,
timeout=timeout, timeout=timeout,
headers=headers, headers=headers,
@ -191,14 +190,16 @@ def call_api(
failed = True failed = True
continue continue
break break
except ConnectionError: except requests.exceptions.ConnectionError:
failed = True failed = True
continue continue
if failed: if failed:
error = f"Code {response.status_code}" if response else "Timeout" error = f"Code {response.status_code}" if response else "Timeout"
raise ConnectionError(f"Failed to connect after 3 tries ({error})") raise requests.exceptions.ConnectionError(
f"Failed to connect after 3 tries ({error})"
)
if operation == "post": if operation == "post":
response = post( response = requests.post(
uri, uri,
timeout=timeout, timeout=timeout,
headers=headers, headers=headers,
@ -208,7 +209,7 @@ def call_api(
verify=config["verify_ssl"], verify=config["verify_ssl"],
) )
if operation == "put": if operation == "put":
response = put( response = requests.put(
uri, uri,
timeout=timeout, timeout=timeout,
headers=headers, headers=headers,
@ -218,7 +219,7 @@ def call_api(
verify=config["verify_ssl"], verify=config["verify_ssl"],
) )
if operation == "patch": if operation == "patch":
response = patch( response = requests.patch(
uri, uri,
timeout=timeout, timeout=timeout,
headers=headers, headers=headers,
@ -227,7 +228,7 @@ def call_api(
verify=config["verify_ssl"], verify=config["verify_ssl"],
) )
if operation == "delete": if operation == "delete":
response = patch, delete( response = requests.delete(
uri, uri,
timeout=timeout, timeout=timeout,
headers=headers, headers=headers,
@ -242,10 +243,10 @@ def call_api(
# Display debug output # Display debug output
if config["debug"]: if config["debug"]:
echo("API endpoint: {}".format(uri), err=True) click.echo("API endpoint: {}".format(uri), err=True)
echo("Response code: {}".format(response.status_code), err=True) click.echo("Response code: {}".format(response.status_code), err=True)
echo("Response headers: {}".format(response.headers), err=True) click.echo("Response headers: {}".format(response.headers), err=True)
echo(err=True) click.echo(err=True)
# Return the response object # Return the response object
return response return response

View File

@ -19,6 +19,11 @@
# #
############################################################################### ###############################################################################
from requests_toolbelt.multipart.encoder import (
MultipartEncoder,
MultipartEncoderMonitor,
)
import pvc.lib.ansiprint as ansiprint import pvc.lib.ansiprint as ansiprint
from pvc.lib.common import UploadProgressBar, call_api, get_wait_retdata from pvc.lib.common import UploadProgressBar, call_api, get_wait_retdata
@ -544,12 +549,6 @@ def ova_upload(config, name, ova_file, params):
bar = UploadProgressBar( bar = UploadProgressBar(
ova_file, end_message="Parsing file on remote side...", end_nl=False ova_file, end_message="Parsing file on remote side...", end_nl=False
) )
from requests_toolbelt.multipart.encoder import (
MultipartEncoder,
MultipartEncoderMonitor,
)
upload_data = MultipartEncoder( upload_data = MultipartEncoder(
fields={"file": ("filename", open(ova_file, "rb"), "application/octet-stream")} fields={"file": ("filename", open(ova_file, "rb"), "application/octet-stream")}
) )

View File

@ -23,6 +23,10 @@ import math
from os import path from os import path
from json import loads from json import loads
from requests_toolbelt.multipart.encoder import (
MultipartEncoder,
MultipartEncoderMonitor,
)
import pvc.lib.ansiprint as ansiprint import pvc.lib.ansiprint as ansiprint
from pvc.lib.common import UploadProgressBar, call_api, get_wait_retdata from pvc.lib.common import UploadProgressBar, call_api, get_wait_retdata
@ -1208,12 +1212,6 @@ def ceph_volume_upload(config, pool, volume, image_format, image_file):
bar = UploadProgressBar( bar = UploadProgressBar(
image_file, end_message="Parsing file on remote side...", end_nl=False image_file, end_message="Parsing file on remote side...", end_nl=False
) )
from requests_toolbelt.multipart.encoder import (
MultipartEncoder,
MultipartEncoderMonitor,
)
upload_data = MultipartEncoder( upload_data = MultipartEncoder(
fields={ fields={
"file": ("filename", open(image_file, "rb"), "application/octet-stream") "file": ("filename", open(image_file, "rb"), "application/octet-stream")

View File

@ -1,21 +0,0 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "pvc"
version = "0.9.107"
dependencies = [
"Click",
"PyYAML",
"lxml",
"colorama",
"requests",
"requests-toolbelt",
]
[tool.setuptools]
packages = ["pvc.cli", "pvc.lib"]
[project.scripts]
pvc = "pvc.cli.cli:cli"

20
client-cli/setup.py Normal file
View File

@ -0,0 +1,20 @@
from setuptools import setup
setup(
name="pvc",
version="0.9.107",
packages=["pvc.cli", "pvc.lib"],
install_requires=[
"Click",
"PyYAML",
"lxml",
"colorama",
"requests",
"requests-toolbelt",
],
entry_points={
"console_scripts": [
"pvc = pvc.cli.cli:cli",
],
},
)

2
debian/compat vendored
View File

@ -1 +1 @@
13 9

5
debian/rules vendored
View File

@ -7,14 +7,13 @@ export DH_VERBOSE = 1
dh $@ --with python3 dh $@ --with python3
override_dh_python3: override_dh_python3:
cd $(CURDIR)/client-cli; pybuild --system=pyproject --dest-dir=../debian/pvc-client-cli/ cd $(CURDIR)/client-cli; pybuild --system=distutils --dest-dir=../debian/pvc-client-cli/
mkdir -p debian/pvc-client-cli/usr/lib/python3 mkdir -p debian/pvc-client-cli/usr/lib/python3
mv debian/pvc-client-cli/usr/lib/python3*/* debian/pvc-client-cli/usr/lib/python3/ mv debian/pvc-client-cli/usr/lib/python3*/* debian/pvc-client-cli/usr/lib/python3/
rm -r $(CURDIR)/client-cli/.pybuild $(CURDIR)/client-cli/pvc.egg-info rm -r $(CURDIR)/client-cli/.pybuild $(CURDIR)/client-cli/pvc.egg-info
override_dh_auto_clean: override_dh_auto_clean:
find $(CURDIR) -name "__pycache__" -o -name ".pybuild" -exec rm -fr {} + || true find . -name "__pycache__" -o -name ".pybuild" -exec rm -fr {} + || true
rm -r $(CURDIR)/client-cli/build
# If you need to rebuild the Sphinx documentation # If you need to rebuild the Sphinx documentation
# Add spinxdoc to the dh --with line # Add spinxdoc to the dh --with line