check for writable/free_space + auto_file fallback

This commit is contained in:
tyeth 2024-03-02 22:18:49 +00:00
parent 3ed849593d
commit d19e4745df
2 changed files with 45 additions and 7 deletions

View file

@ -4,7 +4,6 @@
"""
CircUp -- a utility to manage and update libraries on a CircuitPython device.
"""
import pdb
import ctypes
import glob
@ -646,7 +645,6 @@ def find_modules(backend, bundles_list):
bundle_version = bundle_metadata.get("__version__")
mpy = device_metadata["mpy"]
compatibility = device_metadata.get("compatibility", (None, None))
pdb.set_trace()
module_name = (
path.split(os.sep)[-1]
if not path.endswith(os.sep)
@ -1284,8 +1282,15 @@ def install(ctx, modules, pyext, requirement, auto, auto_file): # pragma: no co
auto_file_path = ctx.obj["backend"].get_auto_file_path(auto_file)
print(f"Auto file path: {auto_file_path}")
if not os.path.isfile(auto_file_path):
click.secho(f"Auto file not found: {auto_file}", fg="red")
sys.exit(1)
# fell through to here when run from random folder on windows - ask backend.
new_auto_file = ctx.obj["backend"].get_file_path(auto_file)
if os.path.isfile(new_auto_file):
auto_file = new_auto_file
auto_file_path = ctx.obj["backend"].get_auto_file_path(auto_file)
print(f"Auto file path: {auto_file_path}")
else:
click.secho(f"Auto file not found: {auto_file}", fg="red")
sys.exit(1)
requested_installs = libraries_from_code_py(auto_file_path, mod_names)
else:

View file

@ -122,12 +122,16 @@ class Backend:
if not isinstance(self, WebBackend)
else urljoin(device_path, self.LIB_DIR_PATH)
)
metadata = mod_names[name]
bundle = metadata["bundle"]
bundle.size = os.path.getsize(metadata['path'])
if self.get_free_space() < bundle.size:
self.logger.error(f"Aborted installing module {name} - not enough free space ({bundle.size} < {self.get_free_space()})")
# Create the library directory first.
self._create_library_directory(device_path, library_path)
metadata = mod_names[name]
bundle = metadata["bundle"]
if pyext:
# Use Python source for module.
self._install_module_py(metadata)
@ -161,6 +165,12 @@ class Backend:
To be overridden by subclass
"""
raise NotImplementedError
def get_free_space(self):
"""
To be overridden by subclass
"""
raise NotImplementedError
def is_device_present(self):
"""
@ -564,7 +574,23 @@ class WebBackend(Backend):
connected device.
"""
return self.get_modules(urljoin(self.device_location, self.LIB_DIR_PATH))
def get_free_space(self):
"""
Returns the free space on the device in bytes.
"""
auth = HTTPBasicAuth("", self.password)
with self.session.get(
urljoin(self.device_location , "fs/"), auth=auth, headers={"Accept": "application/json"}, timeout=self.timeout
) as r:
r.raise_for_status()
if r.json().get("free") is None:
self.logger.error("Unable to get free space from device.")
if r.json().get("block_size") is None:
self.logger.error("Unable to get block size from device.")
if r.json().get("writable") is None or r.json().get("writable") is False:
raise PermissionError("CircuitPython Web Workflow Device not writable\n - Remount storage as writable to device (not PC)")
return r.json()["free"] * r.json()["block_size"] # bytes
class DiskBackend(Backend):
"""
@ -743,3 +769,10 @@ class DiskBackend(Backend):
returns True if the device is currently connected
"""
return os.path.exists(self.device_location)
def get_free_space(self):
"""
Returns the free space on the device in bytes.
"""
_, total, free = shutil.disk_usage(self.device_location)
return free