mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-30 06:03:45 +01:00
Merge pull request #2201 from wknet123/release-1.1.0-fix-notary
Fix notary signature issue.
This commit is contained in:
commit
624f33fee9
@ -28,10 +28,11 @@ export class RepositoryService {
|
|||||||
constructor(private http: Http){}
|
constructor(private http: Http){}
|
||||||
|
|
||||||
listRepositories(projectId: number, repoName: string, page?: number, pageSize?: number): Observable<any> {
|
listRepositories(projectId: number, repoName: string, page?: number, pageSize?: number): Observable<any> {
|
||||||
console.log('List repositories with project ID:' + projectId);
|
|
||||||
let params = new URLSearchParams();
|
let params = new URLSearchParams();
|
||||||
params.set('page', page + '');
|
if(page && pageSize) {
|
||||||
params.set('page_size', pageSize + '');
|
params.set('page', page + '');
|
||||||
|
params.set('page_size', pageSize + '');
|
||||||
|
}
|
||||||
return this.http
|
return this.http
|
||||||
.get(`/api/repositories?project_id=${projectId}&q=${repoName}&detail=1`, {search: params})
|
.get(`/api/repositories?project_id=${projectId}&q=${repoName}&detail=1`, {search: params})
|
||||||
.map(response=>response)
|
.map(response=>response)
|
||||||
@ -60,7 +61,7 @@ export class RepositoryService {
|
|||||||
tags.forEach(t=>{
|
tags.forEach(t=>{
|
||||||
for(let i = 0; i < signatures.length; i++) {
|
for(let i = 0; i < signatures.length; i++) {
|
||||||
if(signatures[i].tag === t.tag) {
|
if(signatures[i].tag === t.tag) {
|
||||||
t.signed = true;
|
t.signed = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,14 +69,13 @@ export class RepositoryService {
|
|||||||
return tags;
|
return tags;
|
||||||
})
|
})
|
||||||
.catch(error=>{
|
.catch(error=>{
|
||||||
return tags;
|
return Observable.of(tags);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(error=>Observable.throw(error));
|
.catch(error=>Observable.throw(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteRepository(repoName: string): Observable<any> {
|
deleteRepository(repoName: string): Observable<any> {
|
||||||
console.log('Delete repository with repo name:' + repoName);
|
|
||||||
return this.http
|
return this.http
|
||||||
.delete(`/api/repositories/${repoName}/tags`)
|
.delete(`/api/repositories/${repoName}/tags`)
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
@ -83,7 +83,6 @@ export class RepositoryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteRepoByTag(repoName: string, tag: string): Observable<any> {
|
deleteRepoByTag(repoName: string, tag: string): Observable<any> {
|
||||||
console.log('Delete repository with repo name:' + repoName + ', tag:' + tag);
|
|
||||||
return this.http
|
return this.http
|
||||||
.delete(`/api/repositories/${repoName}/tags/${tag}`)
|
.delete(`/api/repositories/${repoName}/tags/${tag}`)
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
|
@ -24,23 +24,27 @@
|
|||||||
<clr-dg-column>{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.ARCHITECTURE' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.ARCHITECTURE' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.OS' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.OS' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let t of tags" [clrDgItem]='t'>
|
<clr-dg-row *clrDgItems="let t of tags" [clrDgItem]='t'>
|
||||||
<clr-dg-action-overflow>
|
<clr-dg-action-overflow>
|
||||||
<button class="action-item" (click)="showTagID('tag', t)">{{'REPOSITORY.COPY_ID' | translate}}</button>
|
<button class="action-item" (click)="showTagID('tag', t)">{{'REPOSITORY.COPY_ID' | translate}}</button>
|
||||||
<button class="action-item" (click)="showTagID('parent', t)">{{'REPOSITORY.COPY_PARENT_ID' | translate}}</button>
|
<button class="action-item" (click)="showTagID('parent', t)">{{'REPOSITORY.COPY_PARENT_ID' | translate}}</button>
|
||||||
<button class="action-item" [hidden]="!hasProjectAdminRole" (click)="deleteTag(t)">{{'REPOSITORY.DELETE' | translate}}</button>
|
<button class="action-item" [hidden]="!hasProjectAdminRole" (click)="deleteTag(t)">{{'REPOSITORY.DELETE' | translate}}</button>
|
||||||
</clr-dg-action-overflow>
|
</clr-dg-action-overflow>
|
||||||
<clr-dg-cell>{{t.tag}}</clr-dg-cell>
|
<clr-dg-cell>{{t.tag}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{t.pullCommand}}</clr-dg-cell>
|
<clr-dg-cell>{{t.pullCommand}}</clr-dg-cell>
|
||||||
<clr-dg-cell *ngIf="withNotary">
|
<clr-dg-cell *ngIf="withNotary" [ngSwitch]="t.signed">
|
||||||
<clr-icon shape="check" *ngIf="t.signed" style="color: #1D5100;"></clr-icon>
|
<clr-icon shape="check" *ngSwitchCase="1" style="color: #1D5100;"></clr-icon>
|
||||||
<clr-icon shape="close" *ngIf="!t.signed" style="color: #C92100;"></clr-icon>
|
<clr-icon shape="close" *ngSwitchCase="0" style="color: #C92100;"></clr-icon>
|
||||||
</clr-dg-cell>
|
<a href="javascript:void(0)" *ngSwitchDefault role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
|
||||||
<clr-dg-cell>{{t.author}}</clr-dg-cell>
|
<clr-icon shape="help" style="color: #565656;" size="16"></clr-icon>
|
||||||
<clr-dg-cell>{{t.created | date: 'short'}}</clr-dg-cell>
|
<span class="tooltip-content">{{'REPOSITORY.NOTARY_IS_UNDETERMINED' | translate}}</span>
|
||||||
<clr-dg-cell>{{t.dockerVersion}}</clr-dg-cell>
|
</a>
|
||||||
<clr-dg-cell>{{t.architecture}}</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
<clr-dg-cell>{{t.os}}</clr-dg-cell>
|
<clr-dg-cell>{{t.author}}</clr-dg-cell>
|
||||||
|
<clr-dg-cell>{{t.created | date: 'short'}}</clr-dg-cell>
|
||||||
|
<clr-dg-cell>{{t.dockerVersion}}</clr-dg-cell>
|
||||||
|
<clr-dg-cell>{{t.architecture}}</clr-dg-cell>
|
||||||
|
<clr-dg-cell>{{t.os}}</clr-dg-cell>
|
||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
<clr-dg-footer>{{tags ? tags.length : 0}} {{'REPOSITORY.ITEMS' | translate}}</clr-dg-footer>
|
<clr-dg-footer>{{tags ? tags.length : 0}} {{'REPOSITORY.ITEMS' | translate}}</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
import { RepositoryService } from '../repository.service';
|
import { RepositoryService } from '../repository.service';
|
||||||
@ -35,7 +35,8 @@ import { Project } from '../../project/project';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'tag-repository',
|
selector: 'tag-repository',
|
||||||
templateUrl: 'tag-repository.component.html',
|
templateUrl: 'tag-repository.component.html',
|
||||||
styleUrls: ['./tag-repository.component.css']
|
styleUrls: ['./tag-repository.component.css'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class TagRepositoryComponent implements OnInit, OnDestroy {
|
export class TagRepositoryComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@ -66,7 +67,8 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
private deletionDialogService: ConfirmationDialogService,
|
private deletionDialogService: ConfirmationDialogService,
|
||||||
private repositoryService: RepositoryService,
|
private repositoryService: RepositoryService,
|
||||||
private appConfigService: AppConfigService,
|
private appConfigService: AppConfigService,
|
||||||
private session: SessionService){
|
private session: SessionService,
|
||||||
|
private ref: ChangeDetectorRef){
|
||||||
|
|
||||||
this.subscription = this.deletionDialogService.confirmationConfirm$.subscribe(
|
this.subscription = this.deletionDialogService.confirmationConfirm$.subscribe(
|
||||||
message => {
|
message => {
|
||||||
@ -117,19 +119,31 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
retrieve() {
|
retrieve() {
|
||||||
this.tags = [];
|
this.tags = [];
|
||||||
|
this.repositoryService
|
||||||
|
.listTags(this.repoName)
|
||||||
|
.subscribe(
|
||||||
|
items => this.listTags(items),
|
||||||
|
error => this.messageHandlerService.handleError(error));
|
||||||
|
|
||||||
if(this.withNotary) {
|
if(this.withNotary) {
|
||||||
this.repositoryService
|
this.repositoryService
|
||||||
.listTagsWithVerifiedSignatures(this.repoName)
|
.listNotarySignatures(this.repoName)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
items => this.listTags(items),
|
signatures => {
|
||||||
error => this.messageHandlerService.handleError(error));
|
this.tags.forEach((t, n)=>{
|
||||||
} else {
|
let signed = false;
|
||||||
this.repositoryService
|
for(let i = 0; i < signatures.length; i++) {
|
||||||
.listTags(this.repoName)
|
if (signatures[i].tag === t.tag) {
|
||||||
.subscribe(
|
signed = true;
|
||||||
items => this.listTags(items),
|
break;
|
||||||
error => this.messageHandlerService.handleError(error));
|
}
|
||||||
}
|
}
|
||||||
|
this.tags[n].signed = (signed) ? 1 : 0;
|
||||||
|
this.ref.markForCheck();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error => console.error('Cannot determine the signature of this tag.'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private listTags(tags: Tag[]): void {
|
private listTags(tags: Tag[]): void {
|
||||||
@ -148,6 +162,8 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
tag.parent = data['parent'];
|
tag.parent = data['parent'];
|
||||||
this.tags.push(tag);
|
this.tags.push(tag);
|
||||||
});
|
});
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteTag(tag: TagView) {
|
deleteTag(tag: TagView) {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
export class TagView {
|
export class TagView {
|
||||||
tag: string;
|
tag: string;
|
||||||
pullCommand: string;
|
pullCommand: string;
|
||||||
signed: boolean;
|
signed: number = -1;
|
||||||
author: string;
|
author: string;
|
||||||
created: Date;
|
created: Date;
|
||||||
dockerVersion: string;
|
dockerVersion: string;
|
||||||
|
@ -36,5 +36,5 @@ export class Tag {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
signed: boolean;
|
signed: number;
|
||||||
}
|
}
|
@ -325,7 +325,8 @@
|
|||||||
"POP_REPOS": "Popular Repositories",
|
"POP_REPOS": "Popular Repositories",
|
||||||
"DELETED_REPO_SUCCESS": "Deleted repository successfully.",
|
"DELETED_REPO_SUCCESS": "Deleted repository successfully.",
|
||||||
"DELETED_TAG_SUCCESS": "Deleted tag successfully.",
|
"DELETED_TAG_SUCCESS": "Deleted tag successfully.",
|
||||||
"COPY": "Copy"
|
"COPY": "Copy",
|
||||||
|
"NOTARY_IS_UNDETERMINED": "Cannot determine the signature of this tag."
|
||||||
},
|
},
|
||||||
"ALERT": {
|
"ALERT": {
|
||||||
"FORM_CHANGE_CONFIRMATION": "Some changes are not saved yet. Do you want to cancel?"
|
"FORM_CHANGE_CONFIRMATION": "Some changes are not saved yet. Do you want to cancel?"
|
||||||
|
@ -325,7 +325,8 @@
|
|||||||
"POP_REPOS": "受欢迎的镜像仓库",
|
"POP_REPOS": "受欢迎的镜像仓库",
|
||||||
"DELETED_REPO_SUCCESS": "成功删除镜像仓库。",
|
"DELETED_REPO_SUCCESS": "成功删除镜像仓库。",
|
||||||
"DELETED_TAG_SUCCESS": "成功删除镜像标签。",
|
"DELETED_TAG_SUCCESS": "成功删除镜像标签。",
|
||||||
"COPY": "复制"
|
"COPY": "复制",
|
||||||
|
"NOTARY_IS_UNDETERMINED": "无法确定镜像标签签名。"
|
||||||
},
|
},
|
||||||
"ALERT": {
|
"ALERT": {
|
||||||
"FORM_CHANGE_CONFIRMATION": "表单内容改变,确认是否取消?"
|
"FORM_CHANGE_CONFIRMATION": "表单内容改变,确认是否取消?"
|
||||||
|
Loading…
Reference in New Issue
Block a user