Fix notary signature issue.

This commit is contained in:
kunw 2017-05-03 18:01:04 +08:00
parent 97e214c3d3
commit e44c0c8af9
7 changed files with 62 additions and 41 deletions

View File

@ -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)

View File

@ -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>

View File

@ -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) {

View File

@ -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;

View File

@ -36,5 +36,5 @@ export class Tag {
} }
]; ];
}; };
signed: boolean; signed: number;
} }

View File

@ -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?"

View File

@ -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": "表单内容改变,确认是否取消?"