4 Commits

Author SHA1 Message Date
Ramkumar Chinchani
19e366ee1f fix: use the official icon
Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
2023-10-11 19:56:02 -07:00
Raul-Cristian Kele
b41fb2f841 patch: update nodata display on homepage
Signed-off-by: Raul-Cristian Kele <raulkeleblk@gmail.com>
2023-10-02 14:16:15 -07:00
Raul Kele
b787273b84 fix: fixed display of new signature tooltips in some cases (#379)
Signed-off-by: Raul-Cristian Kele <raulkeleblk@gmail.com>
2023-08-29 19:46:13 +03:00
Andrei Aaron
9ecd46e4d0 ci(end-to-end): Fix a few issues with the workflow (#380)
- free up disk space before running tests
- remove uneeded call to /v2/_catalog.
- add a check to make sure the images are scanned for CVEs before tests start

Signed-off-by: Andrei Aaron <aaaron@luxoft.com>
2023-08-29 19:09:52 +03:00
7 changed files with 103 additions and 92 deletions

View File

@@ -23,6 +23,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cleanup disk space
run: |
# To free up ~15 GB of disk space
sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/share/boost
sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnet
- name: Checkout zui repository
uses: actions/checkout@v3
with:
@@ -116,10 +124,10 @@ jobs:
cd $GITHUB_WORKSPACE
make playwright-browsers
- name: Trigger catalog
- name: Trigger CVE scanning
run: |
while true; do x=0; curl -f http://$REGISTRY_HOST:$REGISTRY_PORT/v2/_catalog || x=1; if [ $x -eq 0 ]; then break; fi; sleep 1; done
# trigger CVE scanning for all images before running the tests
curl -X POST -H "Content-Type: application/json" -m 600 --data '{ "query": "{ ImageListForCVE (id:\"CVE-2021-43616\") { Results { RepoName Tag } } }" }' http://$REGISTRY_HOST:$REGISTRY_PORT/v2/_zot/ext/search
- name: Run integration tests
run: |

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -200,11 +200,16 @@ function Home() {
navigate({ pathname: `/explore`, search: createSearchParams({ [type]: value }).toString() });
};
const renderCards = (cardArray, isLoading) => {
if (cardArray && cardArray.length < 1 && !isLoading) {
return <NoDataComponent text="No images" />;
}
const isNoData = () =>
!isLoading &&
!isLoadingBookmarks &&
!isLoadingPopular &&
!isLoadingRecent &&
bookmarkData.length === 0 &&
popularData.length === 0 &&
recentData.length === 0;
const renderCards = (cardArray) => {
return (
cardArray &&
cardArray.map((item, index) => {
@@ -232,68 +237,68 @@ function Home() {
);
};
return (
<>
{isLoading ? (
<Loading />
) : (
<Stack alignItems="center" className={classes.gridWrapper}>
<Stack className={classes.sectionHeaderContainer} sx={{ paddingTop: '3rem' }}>
<div>
<Typography variant="h4" align="left" className={classes.sectionTitle}>
Most popular images
</Typography>
</div>
<div onClick={() => handleClickViewAll('sortby', sortByCriteria.downloads.value)}>
<Typography variant="body2" className={classes.viewAll}>
View all
</Typography>
</div>
</Stack>
{isLoadingPopular ? <Loading /> : renderCards(popularData, isLoadingPopular)}
{/* currently most popular will be by downloads until stars are implemented */}
<Stack className={classes.sectionHeaderContainer}>
<div>
<Typography variant="h4" align="left" className={classes.sectionTitle}>
Recently updated images
</Typography>
</div>
<div>
<Typography
variant="body2"
className={classes.viewAll}
onClick={() => handleClickViewAll('sortby', sortByCriteria.updateTime.value)}
>
View all
</Typography>
</div>
</Stack>
{isLoadingRecent ? <Loading /> : renderCards(recentData, isLoadingRecent)}
{!isEmpty(bookmarkData) && (
<>
<Stack className={classes.sectionHeaderContainer}>
<div>
<Typography variant="h4" align="left" className={classes.sectionTitle}>
Bookmarks
</Typography>
</div>
<div>
<Typography
variant="body2"
className={classes.viewAll}
onClick={() => handleClickViewAll('filter', 'IsBookmarked')}
>
View all
</Typography>
</div>
</Stack>
{isLoadingBookmarks ? <Loading /> : renderCards(bookmarkData, isLoadingBookmarks)}
</>
)}
const renderContent = () => {
return isNoData() === true ? (
<NoDataComponent text="No images" />
) : (
<Stack alignItems="center" className={classes.gridWrapper}>
<Stack className={classes.sectionHeaderContainer} sx={{ paddingTop: '3rem' }}>
<div>
<Typography variant="h4" align="left" className={classes.sectionTitle}>
Most popular images
</Typography>
</div>
<div onClick={() => handleClickViewAll('sortby', sortByCriteria.downloads.value)}>
<Typography variant="body2" className={classes.viewAll}>
View all
</Typography>
</div>
</Stack>
)}
</>
);
{isLoadingPopular ? <Loading /> : renderCards(popularData, isLoadingPopular)}
{/* currently most popular will be by downloads until stars are implemented */}
<Stack className={classes.sectionHeaderContainer}>
<div>
<Typography variant="h4" align="left" className={classes.sectionTitle}>
Recently updated images
</Typography>
</div>
<div>
<Typography
variant="body2"
className={classes.viewAll}
onClick={() => handleClickViewAll('sortby', sortByCriteria.updateTime.value)}
>
View all
</Typography>
</div>
</Stack>
{isLoadingRecent ? <Loading /> : renderCards(recentData, isLoadingRecent)}
{!isEmpty(bookmarkData) && (
<>
<Stack className={classes.sectionHeaderContainer}>
<div>
<Typography variant="h4" align="left" className={classes.sectionTitle}>
Bookmarks
</Typography>
</div>
<div>
<Typography
variant="body2"
className={classes.viewAll}
onClick={() => handleClickViewAll('filter', 'IsBookmarked')}
>
View all
</Typography>
</div>
</Stack>
{isLoadingBookmarks ? <Loading /> : renderCards(bookmarkData, isLoadingBookmarks)}
</>
)}
</Stack>
);
};
return <>{isLoading ? <Loading /> : renderContent()}</>;
}
export default Home;

View File

@@ -12,8 +12,8 @@ function SignatureTooltip({ isSigned, signatureInfo }) {
<Stack direction="column">
<Typography>{isSigned ? 'Verified Signature' : 'Unverified Signature'}</Typography>
<Typography>Tool: {tool}</Typography>
<Typography>Trusted: {isTrusted ? 'Yes' : 'No'}</Typography>
<Typography>Author: {author}</Typography>
<Typography>Trusted: {!isEmpty(isTrusted) ? isTrusted : 'Unknown'}</Typography>
<Typography>Author: {!isEmpty(author) ? author : 'Unknown'}</Typography>
</Stack>
);
}

View File

@@ -101,7 +101,7 @@ const mapSignatureInfo = (signatureInfo) => {
return signatureInfo
? {
tool: signatureInfo.Tool,
isTrusted: signatureInfo.IsTrusted,
isTrusted: signatureInfo.IsTrusted?.toString(),
author: signatureInfo.Author
}
: {

View File

@@ -145,7 +145,7 @@ const CriticalVulnerabilityIcon = ({ vulnerabilityStringTitle }) => {
const NoneVulnerabilityChip = () => {
return (
<Chip
label="No Vulnerability"
label="None"
sx={{ backgroundColor: '#E8F5E9', color: '#388E3C', fontSize: '0.8125rem' }}
variant="filled"
onDelete={() => {
@@ -159,7 +159,7 @@ const NoneVulnerabilityChip = () => {
const UnknownVulnerabilityChip = () => {
return (
<Chip
label="Unknown Vulnerability"
label="Unknown"
sx={{ backgroundColor: '#ECEFF1', color: '#52637A', fontSize: '0.8125rem' }}
variant="filled"
onDelete={() => {
@@ -187,7 +187,7 @@ const FailedScanChip = () => {
const LowVulnerabilityChip = () => {
return (
<Chip
label="Low Vulnerability"
label="Low"
sx={{ backgroundColor: '#FFF3E0', color: '#FB8C00', fontSize: '0.8125rem' }}
variant="filled"
onDelete={() => {
@@ -201,7 +201,7 @@ const LowVulnerabilityChip = () => {
const MediumVulnerabilityChip = () => {
return (
<Chip
label="Medium Vulnerability"
label="Medium"
sx={{ backgroundColor: '#FFF3E0', color: '#FB8C00', fontSize: '0.8125rem' }}
variant="filled"
onDelete={() => {
@@ -215,7 +215,7 @@ const MediumVulnerabilityChip = () => {
const HighVulnerabilityChip = () => {
return (
<Chip
label="High Vulnerability"
label="High"
sx={{ backgroundColor: '#FEEBEE', color: '#E53935', fontSize: '0.8125rem' }}
variant="filled"
onDelete={() => {
@@ -229,7 +229,7 @@ const HighVulnerabilityChip = () => {
const CriticalVulnerabilityChip = () => {
return (
<Chip
label="Critical Vulnerability"
label="Critical"
sx={{ backgroundColor: '#FEEBEE', color: '#E53935', fontSize: '0.8125rem' }}
variant="filled"
onDelete={() => {

View File

@@ -23,9 +23,9 @@ const endpoints = {
globalSearch: (searchTerm, sortCriteria, pageNumber = 1, pageSize = 10) =>
`/v2/_zot/ext/search?query={GlobalSearch(query:%22${searchTerm}%22,%20requestedPage:%20{limit:${pageSize}%20offset:${
10 * (pageNumber - 1)
}%20sortBy:%20${sortCriteria}}%20)%20{Page%20{TotalCount%20ItemCount}%20Repos%20{Name%20LastUpdated%20Size%20Platforms%20{%20Os%20Arch%20}%20IsStarred%20IsBookmarked%20NewestImage%20{%20Tag%20Vulnerabilities%20{MaxSeverity%20Count}%20Description%20IsSigned%20Licenses%20Vendor%20Labels%20}%20DownloadCount}}}`,
}%20sortBy:%20${sortCriteria}}%20)%20{Page%20{TotalCount%20ItemCount}%20Repos%20{Name%20LastUpdated%20Size%20Platforms%20{%20Os%20Arch%20}%20IsStarred%20IsBookmarked%20NewestImage%20{%20Tag%20Vulnerabilities%20{MaxSeverity%20Count}%20Description%20IsSigned%20SignatureInfo%20{%20Tool%20IsTrusted%20Author%20}%20Licenses%20Vendor%20Labels%20}%20DownloadCount}}}`,
image: (name) =>
`/v2/_zot/ext/search?query={Image(image:%20%22${name}%22){RepoName%20IsSigned%20Vulnerabilities%20{MaxSeverity%20Count}%20%20Referrers%20{MediaType%20ArtifactType%20Size%20Digest%20Annotations{Key%20Value}}%20Tag%20Manifests%20{History%20{Layer%20{Size%20Digest}%20HistoryDescription%20{CreatedBy%20EmptyLayer}}%20Digest%20ConfigDigest%20LastUpdated%20Size%20Platform%20{Os%20Arch}}%20Vendor%20Licenses%20}}`
`/v2/_zot/ext/search?query={Image(image:%20%22${name}%22){RepoName%20IsSigned%20SignatureInfo%20{%20Tool%20IsTrusted%20Author%20}%20Vulnerabilities%20{MaxSeverity%20Count}%20%20Referrers%20{MediaType%20ArtifactType%20Size%20Digest%20Annotations{Key%20Value}}%20Tag%20Manifests%20{History%20{Layer%20{Size%20Digest}%20HistoryDescription%20{CreatedBy%20EmptyLayer}}%20Digest%20ConfigDigest%20LastUpdated%20Size%20Platform%20{Os%20Arch}}%20Vendor%20Licenses%20}}`
};
export { hosts, endpoints, sortCriteria, pageSizes };