* Constrain /registries/ping to the saved URL for existing registries
When an existing registry is referenced by id, the ping health check
could target a URL different from the one stored for that registry.
Bind the ping to the registry's saved URL so the health check always
validates the actual configured endpoint instead of an arbitrary
override.
Signed-off-by: aloui ikram <ikram@container-registry.com>
* Reword URL-override guard comment to match handler convention
Signed-off-by: Vadim Bauer <vb@container-registry.com>
* Ignore saved-registry connection overrides in /registries/ping
A caller with only read:registries could reference an existing registry by
id while overriding url/insecure/ca_certificate, making the health check
send the registry's stored credentials to an attacker-controlled or MITM'd
endpoint. Bind the ping to the saved connection settings whenever an id is
supplied, and add a regression test covering the override attempts.
Signed-off-by: Vadim Bauer <vb@container-registry.com>
---------
Signed-off-by: aloui ikram <ikram@container-registry.com>
Signed-off-by: Vadim Bauer <vb@container-registry.com>
Co-authored-by: aloui ikram <ikram@container-registry.com>
Co-authored-by: Vadim Bauer <vb@container-registry.com>
* fix: avoid panic in user audit event resolver on nil event data
The user audit-event resolver is registered for both the /api/v2.0/users
collection and the /api/v2.0/users/{id} resource. For a PUT whose URL does
not match a specific user id, the base resolver returns without populating
event.Data, leaving it nil. userEventResolver.Resolve then dereferenced
event.Data through an unchecked type assertion, which panics.
Audit events are built and published in a detached goroutine
(BuildAndPublish) that had no recover(), so the panic propagated and
terminated the process instead of failing the single request.
- user.go: use a checked type assertion and skip the update when
event.Data is nil.
- event.go: recover() in the BuildAndPublish goroutine as a safeguard.
Add a regression test covering the nil event.Data path.
Signed-off-by: aloui ikram <ikram@container-registry.com>
* fix: use runtime.Stack() to log panic stack trace in BuildAndPublish recover
Signed-off-by: aloui ikram <ikram@container-registry.com>
* docs: trim added comments to WHY-only one-liners
Signed-off-by: Vadim Bauer <vb@container-registry.com>
* fix: add license header to new test file
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Prasanth Baskar <bupdprasanth@gmail.com>
---------
Signed-off-by: aloui ikram <ikram@container-registry.com>
Signed-off-by: Vadim Bauer <vb@container-registry.com>
Signed-off-by: Prasanth Baskar <bupdprasanth@gmail.com>
Co-authored-by: aloui ikram <ikram@container-registry.com>
Co-authored-by: Vadim Bauer <vb@container-registry.com>
Co-authored-by: Prasanth Baskar <bupdprasanth@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* docs(api): fix 15 swagger gaps — descriptions, responses, lint rules
- Add missing description/summary to deleteProjectMember,
UpdateImmuRule, DeleteImmuRule, listUsers, getCurrentUserInfo,
getUser, updateUserProfile, setUserSysAdmin,
getCurrentUserPermissions, listSchedules, getSchedulePaused
- Add accurate error responses traced to handler code:
404 on member/immutable ops (RequireProjectAccess paths),
403+500 on listAuditLogEventTypes (RequireSystemAccess),
412 on getCurrentUserInfo (non-local security context),
400 on listSchedules/getSchedulePaused/updateUserProfile,
401+500 on getRentenitionMetadata (Prepare middleware),
500 on pingOIDC
- Remove inaccurate responses: 404 from getSchedulePaused/
listSchedules/updateUserProfile; 403 from getSchedulePaused;
500 from getCurrentUserPermissions (in-memory only)
- Fix inline 500/401 descriptions in setUserSysAdmin and
getCurrentUserPermissions to use shared definitions
- Add operation-description and operation-summary-required rules
to .spectral.yaml to prevent regression
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
* chore: complete swagger changes for harbor-cli well known issues
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
* docs(api): restore response codes removed in error from schedules and user endpoints
- Restore 404 on listSchedules (GET /schedules)
- Restore 403 and 404 on getSchedulePaused (GET /schedules/{job_type}/paused)
- Restore 404 on updateUserProfile (PUT /users/{id})
- Restore 500 on getCurrentUserPermissions (GET /users/current/permissions)
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
* fix: clean up binaries
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
* fix: add needed statements for spectral linting and api tests
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
* fix: add changes for unsupported entity; more clear description
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Patrick Eschenbach <45457307+qcserestipy@users.noreply.github.com>
* fix: add changes for unsupported entity; more clear description
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Patrick Eschenbach <45457307+qcserestipy@users.noreply.github.com>
* fix: add changes for unsupported entity; more clear description
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
---------
Signed-off-by: Patrick Eschenbach <patrickeschenbach96@gmail.com>
Signed-off-by: Patrick Eschenbach <45457307+qcserestipy@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* bump: bump up trivy adapter version to v0.37.2-rc2
Update TRIVYADAPTERVERSION to v0.37.2-rc2 in Makefile.
Signed-off-by: stonezdj <stone.zhang@broadcom.com>
* bump: bump up Go version to v1.26.4
Update Go version from 1.26.3 to 1.26.4 across makefiles, configuration, CI workflows, and documentation.
Signed-off-by: stonezdj <stone.zhang@broadcom.com>
---------
Signed-off-by: stonezdj <stone.zhang@broadcom.com>
Signed-off-by: stonezdj(Daojun Zhang) <stonezdj@gmail.com>
- Center-align Pending Jobs counts
- Set No SBOM label cursor to default
- Convert new user form fields to standard row layout
- Widen robot name field and stop description textarea turning green
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
Enable worker list selectable and other UI regression issues
- fix#50: Baseline misalignment between Checkbox and Text Field
- fix#51: Project Quotas- keep the Text style consistence with previous version
- fix#58: Alignment issue with "Cover all projects" checkbox and info icon
- fix#59: Selected permissions checkboxes are dimmed/grayed out in dark theme
- fix#60: Global search placeholder leaks raw key "GLOBAL_SEARCH.PLACE" and top nav chatters during language toggle
- fix#62: Multi-selection checkboxes are missing in the Workers list table
- add unit test for the free button
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
Signed-off-by: stonezdj <stone.zhang@broadcom.com>
* fix(cache): replace keyMutex with singleflight and avoid canceling cache Save
- Replace the global keyMutex with singleflight.Group so concurrent callers
on an L1 miss share a single builder() result instead of serializing.
- Use context.WithoutCancel(ctx) for the inner Fetch and Save so a canceled
request context no longer prevents the Redis L2 cache from being populated.
Fixes#23335
Signed-off-by: Erwan Morvan <erwan.morvan@ovhcloud.com>
* fix(cache): address review feedback and cover codec encode error path
- Update the FetchOrSave doc comment to describe the singleflight-based
behavior (no second Fetch anymore).
- Make the Save mock expectation in TestFetchOrSaveConcurrency strictly
match the 3-arg call (no expiration passed).
- Add TestBuildResultNotEncodable to cover the codec.Encode error path.
Signed-off-by: Erwan Morvan <erwan.morvan@ovhcloud.com>
* fix(cache): consolidate cache util into helper and harden concurrency tests
- Move fetchOrSaveGroup into helper.go and delete util.go (review feedback)
- Drop redundant util_test.go; assert the real singleflight guarantee
(dedup, not exact-once) in the concurrency tests to avoid flakiness
- Rename TestSaveCalledOnlyOneTime -> TestSaveDeduplicatedAcrossConcurrentCallers:
singleflight no longer guarantees a single Save like the old keyMutex did
Signed-off-by: Erwan Morvan <erwan.morvan@ovhcloud.com>
---------
Signed-off-by: Erwan Morvan <erwan.morvan@ovhcloud.com>
Co-authored-by: Erwan Morvan <erwan.morvan@ovhcloud.com>
Co-authored-by: Vadim Bauer <vb@container-registry.com>
Co-authored-by: Chlins Zhang <chlins.zhang@gmail.com>
fix: nil deref in StopScanArtifact scan type param
Use the pre-validated local `scanType` variable instead of
dereferencing `params.ScanType.ScanType` directly, which panics
when `params.ScanType` is nil or its scan_type field is invalid.
Signed-off-by: ashnaaseth2325-oss <ashnaaseth2325@gmail.com>
Co-authored-by: Chlins Zhang <chlins.zhang@gmail.com>
- #48: Links turn red on click — add global `a { color: var(--clr-link-color) }`
override in global.scss so active/visited anchor color stays consistent
- #49: Edit Endpoint modal shows green outlines on open — wrap the form in
@if (createEditDestinationOpened) so Clarity does not pre-initialize and
validate the form before the modal is actually opened
- #52/#53: Copy button icon state broken — replace [class.is-success] /
[class.is-error] with [status] binding in copy-input component so icon
correctly reflects copied / error / default states
- #54: Sign-up / new-user form layout misaligned — add clrForm, clrLayout,
clrLabelSize="4", clr-row and responsive grid classes to new-user-form;
wrap input + icon combos in div.clr-input-group in sign-in, account-settings
and create-project to fix horizontal label-input alignment
- Also replace deprecated class="is-error" with status="danger" on clr-icon
in sbom-scan and vulnerability result-bar-chart components; normalize
global.scss indentation from 2-space to 4-space throughout
- Fix lint issue
- fix targetEndpoint validation issue
- fix copilot review comments
fix the copilot review
Signed-off-by: stonezdj <stone.zhang@broadcom.com>
Co-authored-by: Wang Yan <wangyan_0219@hotmail.com>
fix(ui): remove hardcoded SBOM permission override
Remove the temporary `this._hasSbomPermission = true` that bypassed
the actual permission check, causing all users to have SBOM access
regardless of their project role. The TODO comment marking it for
removal was left during SBOM feature development (461a5fa50d).
Fixes#23218
Signed-off-by: June Kim <kimjune01@gmail.com>
Co-authored-by: Prasanth Baskar <bupdprasanth@gmail.com>
* fix(ui): fix UI issues #37–#46 across portal components
- #37: Export CVE - Labels link did not navigate to /harbor/labels; replaced span+routerLink inside button with a proper <a [routerLink]> on a div container and added Router-based navigation
- #38: System Robot Account - new-robot form field labels misaligned; migrated name field to clr-input-container with clrLabelSize="4" and added clr-row to expiration row
- #39: SBOM scanning bar - label width constrained by fixed min/max-width causing overflow; replaced with uniform padding so labels scale naturally
- #40: Repository grid view - entire card wrapped in <a> caused nested interactive element (dropdown inside anchor); restructured to use div as card root and <a class="nav-link"> only around the content body
- #41: Webhook add form - event type checkbox labels truncated due to 8rem wrapper; increased wrapper width to 12rem to prevent clipping
- #42: Webhook executions - signpost link not stretching to full cell width; added display:inline-flex and width:100% to clr-signpost inside .flex, and corrected .link-normal width
- #43: Webhook list - Enabled column too narrow (120px) causing text wrapping; increased column width to 140px
- #44: Webhook list - disabled status icon and label vertically misaligned; added inline-flex + align-items:center + gap to .icon-wrap and reduced icon size to 18
- #45: Global search bar - search input did not expand to fill available header space; added flex:1 and width:100% to .search and its label/input descendants
- #46: Navigator header - global-search element not growing to fill remaining space; added flex:1 to .global-search host and flex:0 to .header-actions to fix layout
- Manually verified all the bug
Signed-off-by: Ashish Patel <zoom2ashish@gmail.com>
* fix(ui): fix Labels navigation in replication rule and replace deprecated clr-icon CSS status classes
- create-edit-rule: fix "Labels" link in label dropdown not navigating to
/harbor/labels; move click handler to button element and use Router.navigate
- Replace deprecated class="is-success/is-warning" with status="success/warning"
attribute on clr-icon across 10 components (confirmation-dialog,
global-confirmation-dialog, not-found, distribution-instances, config-scanner,
list-replication-rule, p2p-policy, webhook, artifact-vulnerabilities,
result-tip-histogram) so icons render correctly with Clarity theming
Signed-off-by: Ashish Patel <zoom2ashish@gmail.com>
* Add unit tests for goToLabels to increase coverage
Signed-off-by: Ashish Patel <zoom2ashish@gmail.com>
---------
Signed-off-by: Ashish Patel <zoom2ashish@gmail.com>
Co-authored-by: Wang Yan <wangyan_0219@hotmail.com>
When decrypting password-type config fields fails (e.g., due to encryption
key mismatch), the code was logging an error but then silently including
the encrypted garbage in the result map. This corrupted value would then
be cached and used by the application, causing authentication failures.
For example, an OIDC client secret that failed to decrypt would return
the encrypted bytes as a string, which would then be sent to the OIDC
provider, resulting in 'unauthorized_client' errors.
The fix skips corrupted password fields during decryption failure,
allowing the system to fall back to defaults or environment variables.
This prevents silent authentication failures caused by corrupted encrypted
configuration data.
Fixes: Users unable to authenticate when encrypted config fields fail
to decrypt (OIDC, LDAP passwords, etc.)
Testing:
- Verified OIDC authentication works when client secret fails initial
decryption
- Confirmed that skipping corrupted fields allows proper fallback behavior
- No regression in normal password field decryption
Signed-off-by: Ross Golder <ross@golder.org>
Co-authored-by: Wang Yan <wangyan_0219@hotmail.com>
* fix: enable chunked blob upload for Azure ACR replication adapter
When replicating images from Harbor to Azure Container Registry, blob
uploads larger than ~20MB fail with HTTP 413 (Request Entity Too Large).
Root cause analysis revealed three issues:
1. The Azure ACR adapter did not declare SupportedCopyByChunk in its
Info() method, so the replication flow always used monolithic
(single PUT) uploads for ACR destinations.
2. The copy flow only checked the policy-level CopyByChunk flag and
ignored the destination adapter's declared capability. This meant
even if an adapter declared chunk support, users had to manually
enable it per replication policy.
3. The registry client's PushBlobChunk() set Content-Length via
req.Header.Set() but did not set req.ContentLength on the
http.Request struct. Go's HTTP client ignores manually set
Content-Length headers and relies on req.ContentLength to decide
between Content-Length and Transfer-Encoding: chunked. As a result,
Go sent the request with Transfer-Encoding: chunked (HTTP-level),
which Azure ACR rejects with CONTENT_LENGTH_INVALID.
Changes:
- Set SupportedCopyByChunk: true in the Azure ACR adapter's Info()
- Auto-enable chunked upload in the copy flow when the destination
adapter declares support via SupportedCopyByChunk
- Set req.ContentLength in PushBlobChunk() to ensure Go sends a
proper Content-Length header instead of Transfer-Encoding: chunked
Validated with an integration test that performs a real 25MB chunked
blob upload (5 x 5MB chunks) against a live Azure ACR instance.
Fixes#23015
Related: #21640
Signed-off-by: Chrysostomos Kolovos <xrkolovos@egritosgroup.gr>
* fix: keep policy CopyByChunk authoritative for replication flow
Per review feedback on #23016, drop the auto-enabling of chunked
upload when the destination adapter declares SupportedCopyByChunk.
Whether a replication uses chunked upload is the user's choice via
the replication policy setting; an adapter declaring support must
not force the behavior, as that would also silently change the
default for Harbor-to-Harbor replications.
The Azure ACR adapter still declares SupportedCopyByChunk: true,
which exposes the "Copy by chunk" option in the replication rule UI
for ACR endpoints, and PushBlobChunk() still sets req.ContentLength
so chunked uploads work against ACR when the user enables the
option.
Also remove TestCopyByChunkAutoEnabled, which validated the removed
behavior.
Signed-off-by: Chrysostomos Kolovos <xrkolovos@egritosgroup.gr>
* chore: use placeholder registry hostname in integration test example
Signed-off-by: Chrysostomos Kolovos <xrkolovos@egritosgroup.gr>
* refactor: address review comments on chunked upload test and client
- move the ACR chunked upload integration test into adapter_test.go
- drop redundant Content-Length header now that req.ContentLength is set
- fix documented go test command path (run from the src module root)
- use a unique repository name per test run to avoid collisions
- add best-effort blob cleanup via t.Cleanup
Signed-off-by: Chrysostomos Kolovos <xrkolovos@egritosgroup.gr>
* fix: cast blobSize to int for make() in chunked upload test
Signed-off-by: Chrysostomos Kolovos <xrkolovos@egritosgroup.gr>
---------
Signed-off-by: Chrysostomos Kolovos <xrkolovos@egritosgroup.gr>
Co-authored-by: Chlins Zhang <chlins.zhang@gmail.com>
* ci: use local base for component builds; fix flaky log rotation test
- build-package.yml: set PULL_BASE_FROM_DOCKERHUB=false so components
build on the base image built in the same run, not a stale remote tag.
- test_log_rotation.py: accept Stopped or Success for the dry-run purge
job to avoid a timing flake.
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
* fix ci failure
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
---------
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
The latest upstream photon:5.0 arm64 image currently has an empty rootfs,
which fails during the multi-arch base build with "/bin/sh: no such file
or directory". Pin the Photon base to a known-good stable digest to keep
the amd64 and arm64 builds reproducible.
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
pin qemu binfmt and prevent publish races
- Pin docker/setup-qemu-action to tonistiigi/binfmt:qemu-v9.2.2 for stable arm64 emulation.
- Add per-branch concurrency in build-package workflow to avoid overlapping runs racing on mutable tags/manifests.
- Rename Go setup step label to match the actual configured version.
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
- Use stdlib crypto/pbkdf2 instead of golang.org/x/crypto/pbkdf2 for
password/secret hashing (output unchanged; no migration needed).
- Restrict JWT signing to RSA/RSA-PSS and reject other methods in
pkg/token (default RS256 unchanged).
- Remove unused common/utils/email package (no references in codebase).
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
Co-authored-by: wang yan <yan-yw.wang@broadcom.com>
The per-component base images (goharbor/harbor-core-base, harbor-db-base,
harbor-portal-base, ...) were pushed by both BUILD_PACKAGE matrix jobs to the
same unsuffixed tag (e.g. :dev), so whichever architecture finished last
overwrote the other and the published tag ended up single-arch — the same
last-writer-wins problem goharbor/photon:5.0 had before #23334 (#23324).
Apply the same pattern already used for the component images:
- make/photon/Makefile: _build_base keeps building the local unsuffixed tag
(component Dockerfiles build FROM it unchanged) but pushes an arch-suffixed
tag instead: harbor-<name>-base:<tag>-amd64 / -arm64.
- .github/workflows/build-package.yml: each matrix job also saves the list of
goharbor/*-base repos it built; CREATE_MANIFEST combines the two suffixed
tags into the unsuffixed multi-arch manifest with docker buildx imagetools
create, using the base tag scheme (dev on main, the release version on
release-* branches). The base manifest step only runs when BUILD_BASE_IMAGE
decided to rebuild bases, since otherwise no suffixed tags were pushed in
this run.
Consumers that pull harbor-*-base:<tag> (PULL_BASE_FROM_DOCKERHUB=true flows)
now resolve the correct architecture via the manifest list instead of getting
whatever architecture won the race.
Signed-off-by: Vadim Bauer <vb@container-registry.com>
The swagger, and mockery images are local build-time helper images and are not pushed with dev-{arch} tags.
Exclude them from the repo list used by the manifest job to avoid creating multi-arch manifests for images that are not part of the Harbor runtime release set.
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
Co-authored-by: wang yan <yan-yw.wang@broadcom.com>
fix#23339
The spectral image is only used as a local API lint helper and is built with its own version tag, not as a Harbor runtime image.
Exclude it from the repo list used by the manifest job so CI does not try to create goharbor/spectral:dev from missing dev-{arch} tags.
Signed-off-by: wang yan <yan-yw.wang@broadcom.com>
Co-authored-by: wang yan <yan-yw.wang@broadcom.com>
Upgrade Harbor UI to Angular 21, Clarity v18, and Node.js v22
- Upgrade the Harbor UI (src/portal) from Angular 16 to Angular 19 and subsequently to Angular 21.
- Upgrade VMware Clarity from v17 to v18, and Node.js from v20 to v22 (updated .nvmrc, CI.yml, Makefile, Dockerfile).
- Migrate Angular templates to the new @if/@for control flow syntax.
- Fix UI issues #1 through #35, including robot accounts, layout, dropdown overlay, and input styling.
- Fix unit tests: resolve NG0100 ExpressionChangedAfterItHasBeenCheckedError in policy.component.spec.ts, replace autoDetectChanges(true) with explicit detectChanges cycles, and use TestBed.overrideComponent to stub AddP2pPolicyComponent template.
- Fix Clarity v18 breaking changes: update dark-theme SCSS import, add cds-theme attribute for theming, update ClrDatagridStateInterface import path, add ClrIconModule to app module.
- Stabilize npm installs and resolve CI/CD pipeline hangs.
- Fix swagger-ui crash caused by React 19 createRoot removal:
- swagger-ui 5.28+ resolves a nested react-dom@19 which removed createRoot
from the main react-dom entry point (moved to react-dom/client). The
swagger-ui-es-bundle-core.js still imports createRoot from react-dom,
making it undefined and causing "TypeError: i is not a function" at render.
- app-swagger-ui/webpack.prod.js: alias bare 'swagger-ui' import to
swagger-ui-bundle.js (the standalone UMD build that ships with React 18
already bundled), bypassing the broken external react-dom@19 entirely.
- app-swagger-ui/package.json: add npm overrides to pin react and
react-dom to ^18.3.1 so future npm installs do not re-introduce React 19.
- angular.json: expose swagger-ui.bundle.js and swagger-ui-index.html
from app-swagger-ui/dist as Angular dev-server assets, enabling the
proxy to serve the locally built, fixed bundle during development.
- Convert eslint-plugin-header config from JSON to JS to apply the ESLint 9 schema fix at config-load time, removing the need for patch-package.
- Pin all dependency versions to exact installed versions from the lock file, and remove unused prettier-eslint package.
- Fix flake in P2pProviderService unit test by initializing date with 0 milliseconds to prevent cross-second duration calculation mismatches.
Signed-off-by: Ashish Patel <zoom2ashish@gmail.com>
Co-authored-by: stonezdj <stone.zhang@broadcom.com>
goharbor/photon:5.0 was built and pushed independently by both the amd64 and
arm64 BUILD_PACKAGE matrix jobs to the same tag, so whichever job finished last
overwrote the other and the published tag ended up single-arch ("sometimes
amd64, sometimes arm64", #23324).
Build it once as an amd64+arm64 manifest list in a dedicated BUILD_BASE_IMAGE
job that BUILD_PACKAGE depends on, and exclude goharbor/photon from the
component manifest list in CREATE_MANIFEST (it is published here and stays at
tag 5.0).
The db base image keeps the photon-snapshot repo (the stable Photon source) and
installs both postgresql15-server (old binaries at /usr/pgsql/15/bin, required
by pg_upgrade) and postgresql18-server (runtime), temporarily un-pinning the
snapshot to pull whichever major Photon has deprecated out of the current
snapshot per architecture (pg15 on amd64, pg18 on arm64). common/Dockerfile
keeps photon-snapshot and merges its setup into a single RUN.
Signed-off-by: Vadim Bauer <vb@container-registry.com>