Compare commits
No commits in common. "bb77c5f1fceaca3dda056b7b1e1ae454348c7be0" and "60967b56063ea63511a9bc253a9117e4c7d703f9" have entirely different histories.
bb77c5f1fc
...
60967b5606
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,4 +8,3 @@ debian/pvc-*/
|
|||||||
debian/*.log
|
debian/*.log
|
||||||
debian/*.substvars
|
debian/*.substvars
|
||||||
debian/files
|
debian/files
|
||||||
client-cli/build/
|
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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")}
|
||||||
)
|
)
|
||||||
|
@ -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")
|
||||||
|
@ -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
20
client-cli/setup.py
Normal 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
2
debian/compat
vendored
@ -1 +1 @@
|
|||||||
13
|
9
|
||||||
|
5
debian/rules
vendored
5
debian/rules
vendored
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user