archive: add gitea generic package registry backend - #705
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #705 +/- ##
==========================================
+ Coverage 89.23% 89.28% +0.04%
==========================================
Files 50 50
Lines 16450 16512 +62
==========================================
+ Hits 14679 14742 +63
+ Misses 1771 1770 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
i'm not sure, but the root cause of the failed windows build could be: |
f72e3d7 to
fe1828f
Compare
|
Thanks. I'll have a look after my vacation... |
jkloetzke
left a comment
There was a problem hiding this comment.
Can you split the change into multiple commits? At least one for the implementation, one for the documentation and one for the tests? Also, if you need to extend the Webdav class, that should be a separate commit as well.
fe1828f to
d54543d
Compare
|
@jkloetzke Thanks for your review and feedback! Hopefully everything should be addressed. The change is now split into four commits:
|
183fe76 to
49a591d
Compare
|
disk full issue again. |
The HTTP basic authentication credentials are part of the archive URL. All
three places that turn that URL back into a string for display used the raw
netloc, which still carries the "user:password@" part:
* getArchiveName() feeds _namedErrorString(), so the credentials were
printed on *every* error message -- including the perfectly ordinary
"artifact not found" that occurs for each package on a cache miss. No
verbosity flag needed.
* _remoteName() is the "details" of the DOWNLOAD/UPLOAD/MAP-SRC/CACHE-BID/
CACHE-FPR/MAP-FPRNT status lines, shown with -v.
* getArchiveUri() is printed by "bob archive".
These messages routinely end up in build logs and CI consoles.
WebDav._getURL() already stripped the credentials before putting the URL on
the wire, so this only ever affected the display strings. Factor that logic
out into stripUserInfo() and use it in the three spots above as well.
While at it, cut at the last '@' instead of the first. urlparse() delimits
the user info at the last '@', so for a password containing an unencoded '@'
the previous split('@')[1] produced a bogus host -- and revealed part of the
password on top.
The optional 'name' archive setting was no workaround: _remoteName() and
getArchiveUri() do not consult it.
The http backend takes the basic authentication credentials as part of the URL. State that they are not echoed back in the status lines, so it is clear that putting them there does not put them into every build log.
testNoCredentialsInMessages checks the three user visible strings derived from the archive URL: the password and the '@' delimiter must be gone while the host must survive. Reverting archive.py alone makes all three subtests fail. TestStripUserInfo covers the helper itself: URL without credentials (returned unchanged), plain removal, a password containing an unencoded '@', an IPv6 literal host, and preservation of the urlsplit() result type.
The SSL context was created in the constructor. That rendered the object unpicklable, though, and the archive backends are sent to the up-/download executor processes. Using the http backend with "sslVerify: False" therefore aborted the build with a "cannot pickle 'SSLContext' object" error. Create the context on demand instead. Additionally two small extensions are needed for package registries that are not real WebDAV servers: Some servers do not honour the "If-None-Match" header but refuse to overwrite an existing file with a 409 instead. Treat that like the 412 that a WebDAV server would send. Add deletePath() that takes an absolute path like upload() and download() do. The existing delete() keeps its relative filename and just delegates.
Add a `gitea` archive backend that stores binary artifacts in a Gitea
generic package registry. The backend is configured with the server
`url`, the registry `owner` and the generic `package` name. Artifacts
are put below `{url}/api/packages/{owner}/generic/{package}/` with one
package version per artifact.
As for the http backend the HTTP basic authentication credentials are
part of the URL. Gitea accepts a personal access token in place of the
password. The registry only speaks plain HTTP (HEAD, GET, PUT and
DELETE), so the WebDav class does the transport.
The managed operations (scan/clean) are not implemented because they
would require the Gitea package list API.
While at it, move the retry loop of the http backend into a small
function that both backends share.
Add a mock of the Gitea generic package registry that translates the package API layout to the on-disk layout of the shared archive tests, so that all common upload/download assertions apply unchanged. On top of that, cover authentication via the URL and the individual error replies of the registry.
GiteaArchive has its own getArchiveName(), _remoteName() and getArchiveUri(). Built on the raw netloc they would carry the "user:password@" part into the status lines and error messages, most notably into the perfectly ordinary "artifact not found" that occurs for every package on a cache miss. Use the same stripUserInfo() helper as the http backend.
TestGiteaAuthArchive already runs against a mock registry that requires basic authentication, so the credentials are readily at hand. Assert that the three user visible strings derived from the URL carry neither the token nor the user name, while the host survives. Reverting the previous commit makes all three subtests fail.
49a591d to
abade2f
Compare
Add a
giteaarchive backend that stores binary artifacts in a Gitea generic package registry. The backend is configured with the serverurl, the registryownerand the genericpackagename. Credentials are given explicitly as atoken(personal access token) or auser/passwordpair for HTTP basic authentication, so uploads work even inside the build sandbox. OptionalsslVerifyandretrieskeys tune the transport.Uploads perform a preflight check and report clearer connection and authentication errors.
depends on #706 (archive: do not leak URL credentials in user visible messages)