mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-26 06:59:52 +03:00
feat: add option REGISTRY_SECURED
for registries with Basic Auth
This commit is contained in:
parent
684f82f24e
commit
ffb6d14baf
12 changed files with 35 additions and 8 deletions
|
@ -103,6 +103,7 @@ Some env options are available for use this interface for **only one server** (w
|
|||
- `CATALOG_MIN_BRANCHES`: Set the minimum repository/namespace to expand (e.g. `joxit/docker-registry-ui` `joxit/` is the repository/namespace). Can be 0 to disable branching. (see [#319](https://github.com/Joxit/docker-registry-ui/pull/319)). (default: `1`). Since 2.5.0
|
||||
- `CATALOG_MAX_BRANCHES`: Set the maximum repository/namespace to expand (e.g. `joxit/docker-registry-ui` `joxit/` is the repository/namespace). Can be 0 to disable branching. (see [#319](https://github.com/Joxit/docker-registry-ui/pull/319)). (default: `1`). Since 2.5.0
|
||||
- `TAGLIST_PAGE_SIZE`: Set the number of tags to display in one page. (default: `100`). Since 2.5.0
|
||||
- `REGISTRY_SECURED`: By default, the UI will check on every requests if your registry is secured or not (you will see `401` responses in your console). Set to `true` if your registry uses Basic Authentication and divide by two the number of call to your registry. (default `false`). Since 2.5.0
|
||||
|
||||
There are some examples with [docker-compose](https://docs.docker.com/compose/) and docker-registry-ui as proxy [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-proxy/) or docker-registry-ui as standalone [here](https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-standalone/).
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ sed -i "s~\${CATALOG_DEFAULT_EXPANDED}~${CATALOG_DEFAULT_EXPANDED}~" index.html
|
|||
sed -i "s~\${CATALOG_MIN_BRANCHES}~${CATALOG_MIN_BRANCHES}~" index.html
|
||||
sed -i "s~\${CATALOG_MAX_BRANCHES}~${CATALOG_MAX_BRANCHES}~" index.html
|
||||
sed -i "s~\${TAGLIST_PAGE_SIZE}~${TAGLIST_PAGE_SIZE}~" index.html
|
||||
sed -i "s~\${REGISTRY_SECURED}~${REGISTRY_SECURED}~" index.html
|
||||
|
||||
grep -o 'THEME[A-Z_]*' index.html | while read e; do
|
||||
sed -i "s~\${$e}~$(printenv $e)~" index.html
|
||||
|
|
|
@ -50,6 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
on-notify="{ props.onnNotify }"
|
||||
on-authentication="{ props.onAuthentication }"
|
||||
show-catalog-nb-tags="{ props.showCatalogNbTags }"
|
||||
is-registry-secured="{ props.isRegistrySecured }"
|
||||
class="animated {!state.expanded && !props.filterResults ? 'hide' : ''} {state.expanding ? 'expanding' : ''}"
|
||||
each="{item in state.images}"
|
||||
z-index="{ props.zIndex - 1 }"
|
||||
|
@ -108,6 +109,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const self = this;
|
||||
const oReq = new Http({
|
||||
onAuthentication: props.onAuthentication,
|
||||
withCredentials: props.isRegistrySecured,
|
||||
});
|
||||
oReq.addEventListener('load', function () {
|
||||
if (this.status === 200) {
|
||||
|
|
|
@ -36,6 +36,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
show-catalog-nb-tags="{ props.showCatalogNbTags }"
|
||||
catalog-default-expanded="{ props.catalogDefaultExpanded || state.nRepositories === 1 }"
|
||||
z-index="{ props.catalogMaxBranches - props.catalogMinBranches + 2 }"
|
||||
is-registry-secured="{ props.isRegistrySecured }"
|
||||
></catalog-element>
|
||||
<script>
|
||||
import CatalogElement from './catalog-element.riot';
|
||||
|
@ -81,6 +82,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const catalogUrl = `${props.registryUrl}/v2/_catalog?n=${state.catalogElementsLimit}`;
|
||||
const oReq = new Http({
|
||||
onAuthentication: this.props.onAuthentication,
|
||||
withCredentials: props.isRegistrySecured,
|
||||
});
|
||||
oReq.addEventListener('load', function () {
|
||||
if (this.status === 200) {
|
||||
|
|
|
@ -58,10 +58,11 @@
|
|||
},
|
||||
deleteImages() {
|
||||
this.props.toDelete.forEach((image) => this.getContentDigestThenDelete(image, this.props));
|
||||
this.props.onImageDeleted();
|
||||
},
|
||||
getContentDigestThenDelete({ name, tag }, opts) {
|
||||
const { registryUrl, onNotify, onAuthentication } = opts;
|
||||
const oReq = new Http({ onAuthentication });
|
||||
const { registryUrl, onNotify, onAuthentication, isRegistrySecured } = opts;
|
||||
const oReq = new Http({ onAuthentication, withCredentials: isRegistrySecured });
|
||||
const self = this;
|
||||
oReq.addEventListener('loadend', function () {
|
||||
if (this.status === 200 || this.status === 202) {
|
||||
|
@ -86,8 +87,8 @@
|
|||
oReq.send();
|
||||
},
|
||||
deleteImage({ name, tag, contentDigest }, opts) {
|
||||
const { registryUrl, ignoreError, onNotify, onAuthentication, onClick } = opts;
|
||||
const oReq = new Http({ onAuthentication });
|
||||
const { registryUrl, ignoreError, onNotify, onAuthentication, onClick, isRegistrySecured } = opts;
|
||||
const oReq = new Http({ onAuthentication, withCredentials: isRegistrySecured });
|
||||
oReq.addEventListener('loadend', function () {
|
||||
if (this.status === 200 || this.status === 202) {
|
||||
router.taglist(name);
|
||||
|
|
|
@ -59,6 +59,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
catalog-default-expanded="{ truthy(props.catalogDefaultExpanded) }"
|
||||
catalog-min-branches="{ props.catalogMinBranches }"
|
||||
catalog-max-branches="{ props.catalogMaxBranches }"
|
||||
is-registry-secured="{ truthy(props.isRegistrySecured) }"
|
||||
></catalog>
|
||||
</route>
|
||||
<route path="{baseRoute}taglist/(.*)">
|
||||
|
@ -75,6 +76,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
use-control-cache-header="{ truthy(props.useControlCacheHeader) }"
|
||||
taglist-order="{ props.taglistOrder }"
|
||||
tags-per-page="{ props.tagsPerPage }"
|
||||
is-registry-secured="{ truthy(props.isRegistrySecured) }"
|
||||
></tag-list>
|
||||
</route>
|
||||
<route path="{baseRoute}taghistory/(.*)">
|
||||
|
@ -89,6 +91,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
on-authentication="{ onAuthentication }"
|
||||
history-custom-labels="{ stringToArray(props.historyCustomLabels) }"
|
||||
use-control-cache-header="{ truthy(props.useControlCacheHeader) }"
|
||||
is-registry-secured="{ truthy(props.isRegistrySecured) }"
|
||||
></tag-history>
|
||||
</route>
|
||||
</router>
|
||||
|
|
|
@ -89,6 +89,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
onNotify: props.onNotify,
|
||||
onAuthentication: props.onAuthentication,
|
||||
useControlCacheHeader: props.useControlCacheHeader,
|
||||
isRegistrySecured: props.isRegistrySecured,
|
||||
});
|
||||
state.image.fillInfo();
|
||||
},
|
||||
|
|
|
@ -58,6 +58,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
filter-results="{ props.filterResults }"
|
||||
on-authentication="{ props.onAuthentication }"
|
||||
tags-per-page="{ props.tagsPerPage }"
|
||||
is-registry-secured="{ props.isRegistrySecured }"
|
||||
on-image-deleted="{ () => state.reload() }"
|
||||
>
|
||||
</tag-table>
|
||||
|
||||
|
@ -103,10 +105,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
this.tagComparator = getTagComparator(props.taglistOrder);
|
||||
},
|
||||
display(props, state) {
|
||||
state.reload = () => setTimeout(() => this.display(props, state), 1000);
|
||||
state.tags = [];
|
||||
const self = this;
|
||||
const oReq = new Http({
|
||||
onAuthentication: props.onAuthentication,
|
||||
withCredentials: props.isRegistrySecured,
|
||||
});
|
||||
oReq.addEventListener('load', function () {
|
||||
if (this.status === 200) {
|
||||
|
@ -119,6 +123,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
onNotify: props.onNotify,
|
||||
onAuthentication: props.onAuthentication,
|
||||
useControlCacheHeader: props.useControlCacheHeader,
|
||||
isRegistrySecured: props.isRegistrySecured,
|
||||
})
|
||||
)
|
||||
.sort(self.tagComparator);
|
||||
|
|
|
@ -23,6 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
on-authentication="{ props.onAuthentication }"
|
||||
tags="{ props.tags }"
|
||||
to-delete="{ state.toDelete }"
|
||||
is-registry-secured="{ props.isRegistrySecured }"
|
||||
on-image-deleted="{ props.onImageDeleted }"
|
||||
></confirm-delete-image>
|
||||
<material-card class="taglist">
|
||||
<table style="border: none">
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
catalog-default-expanded="${CATALOG_DEFAULT_EXPANDED}"
|
||||
catalog-min-branches="${CATALOG_MIN_BRANCHES}"
|
||||
catalog-max-branches="${CATALOG_MAX_BRANCHES}"
|
||||
is-registry-secured="${REGISTRY_SECURED}"
|
||||
theme="${THEME}"
|
||||
theme-primary-text="${THEME_PRIMARY_TEXT}"
|
||||
theme-neutral-text="${THEME_NEUTRAL_TEXT}"
|
||||
|
@ -82,6 +83,7 @@
|
|||
catalog-default-expanded=""
|
||||
catalog-min-branches="1"
|
||||
catalog-max-branches="1"
|
||||
is-registry-secured="false"
|
||||
theme="auto"
|
||||
theme-primary-text=""
|
||||
theme-neutral-text=""
|
||||
|
|
|
@ -42,7 +42,7 @@ export const platformToString = (platform) => {
|
|||
};
|
||||
|
||||
export class DockerImage {
|
||||
constructor(name, tag, { list, registryUrl, onNotify, onAuthentication, useControlCacheHeader }) {
|
||||
constructor(name, tag, { list, registryUrl, onNotify, onAuthentication, useControlCacheHeader, isRegistrySecured }) {
|
||||
this.name = name;
|
||||
this.tag = tag;
|
||||
this.chars = 0;
|
||||
|
@ -52,6 +52,7 @@ export class DockerImage {
|
|||
onNotify,
|
||||
onAuthentication,
|
||||
useControlCacheHeader,
|
||||
isRegistrySecured,
|
||||
};
|
||||
this.ociImage = false;
|
||||
observable(this);
|
||||
|
@ -91,7 +92,10 @@ export class DockerImage {
|
|||
return;
|
||||
}
|
||||
this._fillInfoWaiting = true;
|
||||
const oReq = new Http({ onAuthentication: this.opts.onAuthentication });
|
||||
const oReq = new Http({
|
||||
onAuthentication: this.opts.onAuthentication,
|
||||
withCredentials: this.opts.isRegistrySecured,
|
||||
});
|
||||
const self = this;
|
||||
oReq.addEventListener('loadend', function () {
|
||||
if (this.status === 200 || this.status === 202) {
|
||||
|
@ -148,7 +152,10 @@ export class DockerImage {
|
|||
oReq.send();
|
||||
}
|
||||
getBlobs(blob) {
|
||||
const oReq = new Http({ onAuthentication: this.opts.onAuthentication });
|
||||
const oReq = new Http({
|
||||
onAuthentication: this.opts.onAuthentication,
|
||||
withCredentials: this.opts.isRegistrySecured,
|
||||
});
|
||||
const self = this;
|
||||
oReq.addEventListener('loadend', function () {
|
||||
if (this.status === 200 || this.status === 202) {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { getFromCache, setCache } from './cache-request';
|
||||
import { getFromCache, setCache } from './cache-request.js';
|
||||
|
||||
export class Http {
|
||||
constructor(opts) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue