Skip to content

Commit

Permalink
filter by pre-releases in Client._check_updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisvang committed Mar 31, 2022
1 parent 7f91ca5 commit 92d1041
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,28 @@ See the [tuf docs][4] for more information.
## Archives and patches

Notsotuf works with *archives* (gzipped PyInstaller bundles) and *patches* (binary differences between subsequent archives).
Each archive, except the first one, must have a corresponding patch file.

Archive files (and patch files) are named according to [PEP440][6] version specifications.
Each archive (except the first one) has a corresponding patch file, with the matching filename but different extension (`.patch` vs `.gz`).
Archive filenames and patch filenames follow the pattern

`<name>-<version><suffix>`

where `name` is a short string that may contain alphanumeric characters, underscores, and hyphens, `version` is a version string according to the [PEP440][6] specification, and `suffix` is either `'.gz'` or `'.patch'`.

Patches are typically smaller than archives, so the notsotuf client will always attempt to update using one or more patches.
However, if the total amount of patch data is greater than the desired full archive file, a full update will be performed.

## How updates are applied

Updates are applied by replacing all files in the current app installation path with files from the latest archive.
The latest archive is either downloaded in full (as described above), or it is derived from the current archive by applying one or more downloaded patches.
Once the latest archive is available, it is decompressed to a temporary location.
From there, a script is started that clears the current app installation dir, and moves the new files into place.
After starting the script, the currently running process will exit.

## Migrating from PyUpdater
## Migrating from other update frameworks

If you have a working update framework built around PyUpdater, here's how you could migrate to `notsotuf`:
Here's one way to migrate from another update framework, such as `pyupdater`, to `notsotuf`:

1. Add `notsotuf` to your main application environment as a core dependency, and move `pyupdater` from core dependencies to development dependencies.
2. Replace all `pyupdater` client code (and configuration) in your application by the `notsotuf` client.
Expand Down
20 changes: 17 additions & 3 deletions notsotuf/tools/client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import pathlib
import shutil
from tempfile import TemporaryDirectory
from typing import Optional

import tuf.ngclient

Expand All @@ -12,11 +15,21 @@ def __init__(self, current_archive_path: str, *args, **kwargs):
self.new_targets = {}
self.downloaded_target_files = {}

def update(self, ):
if self._check_updates() and self._download_updates():
def update(self, pre: Optional[str] = None):
"""
Check, download, and apply updates.
Final releases are always included. Pre-releases are excluded by
default. If `pre` is specified, pre-releases are included, down to
the specified level. Pre-release identifiers follow the PEP440
specification, i.e. 'a', 'b', or 'rc', for alpha, beta, and release
candidate, respectively.
"""
if self._check_updates(pre=pre) and self._download_updates():
self._apply_updates()

def _check_updates(self) -> bool:
def _check_updates(self, pre: Optional[str]) -> bool:
included = {None: '', '': '', 'a': 'abrc', 'b': 'brc', 'rc': 'rc'}
# refresh top-level metadata (root -> timestamp -> snapshot -> targets)
self.refresh()
# check for new target files
Expand All @@ -27,6 +40,7 @@ def _check_updates(self) -> bool:
all_new_targets = dict(
item for item in trusted_targets.items()
if item[0].name == self.current_archive.name
and (not item[0].version.pre or item[0].version.pre[0] in included[pre])
and item[0].version > self.current_archive.version
)
# split new targets into patches and archives
Expand Down
2 changes: 1 addition & 1 deletion notsotuf/tools/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class TargetPath(object):
filename_regex = re.compile(
r'^(?P<name>[\w -]+)-(?P<version>.+)(?P<suffix>\.gz|\.patch)$'
r'^(?P<name>[\w-]+)-(?P<version>.+)(?P<suffix>\.gz|\.patch)$'
)

def __init__(self, target_path: str):
Expand Down

0 comments on commit 92d1041

Please sign in to comment.