Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container template support add command and args #308

Merged
merged 4 commits into from Feb 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -157,7 +157,7 @@ <h3 class="modal-title">{{nsTitle}}
<div [style.display]="showACE ? 'block' : 'none'" class="container-box">
<div class="form-group" style="padding-left: 135px;">
<label class="clr-col-md-3 form-group-label-override">元数据</label>
<wayne-ace-editor-box style="width: 500px"></wayne-ace-editor-box>
<wayne-ace-editor-box></wayne-ace-editor-box>
</div>
</div>
</section>
Expand Down
Expand Up @@ -35,7 +35,7 @@ <h3 class="header-title" id="创建计划任务模版">{{'CRONJOB.CREATE_TMP' |
<label aria-haspopup="true" role="tooltip" [class.invalid]="!isScheduleValid"
class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
<input type="text" name="schedule"
[(ngModel)]="kubeCronjob.spec.schedule"
[(ngModel)]="kubeResource.spec.schedule"
size="40"
required
class="tooltip tooltip-validation tooltip-md tooltip-bottom-left"
Expand All @@ -55,7 +55,7 @@ <h3 class="header-title" id="创建计划任务模版">{{'CRONJOB.CREATE_TMP' |
</label>
<label aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
<div class="select">
<select name="concurrencyPolicy" [(ngModel)]="kubeCronjob.spec.concurrencyPolicy">
<select name="concurrencyPolicy" [(ngModel)]="kubeResource.spec.concurrencyPolicy">
<option value="Allow" selected>{{'ACTION.ALLOW' | translate}}</option>
<option value="Forbid">{{'ACTION.FORBID' | translate}}</option>
<option value="Replace">{{'ACTION.REPLACE' | translate}}</option>
Expand All @@ -73,7 +73,7 @@ <h3 class="header-title" id="创建计划任务模版">{{'CRONJOB.CREATE_TMP' |
<label aria-haspopup="true" role="tooltip" [class.invalid]="formValid('activeDeadlineSeconds')"
class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
<input type="number" name="activeDeadlineSeconds"
[(ngModel)]="kubeCronjob.spec.jobTemplate.spec.activeDeadlineSeconds" size="45" required
[(ngModel)]="kubeResource.spec.jobTemplate.spec.activeDeadlineSeconds" size="45" required
[placeholder]="'CRONJOB.MAX_EXECUTE_TIME' | translate">{{'UNIT.SECOND' | translate}}
</label>
</div>
Expand All @@ -86,7 +86,7 @@ <h3 class="header-title" id="创建计划任务模版">{{'CRONJOB.CREATE_TMP' |
</a>
</label>
<label aria-haspopup="true" role="tooltip" [class.invalid]="formValid('successfulJobsHistoryLimit')" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
<input type="number" name="successfulJobsHistoryLimit" [(ngModel)]="kubeCronjob.spec.successfulJobsHistoryLimit" size="45" required
<input type="number" name="successfulJobsHistoryLimit" [(ngModel)]="kubeResource.spec.successfulJobsHistoryLimit" size="45" required
placeholder="'CRONJOB.MAX_EXECUTE_TIME' | translate">
</label>
</div>
Expand All @@ -98,13 +98,13 @@ <h3 class="header-title" id="创建计划任务模版">{{'CRONJOB.CREATE_TMP' |
</a>
</label>
<label aria-haspopup="true" role="tooltip" [class.invalid]="formValid('failedJobsHistoryLimit')" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
<input type="number" name="failedJobsHistoryLimit" [(ngModel)]="kubeCronjob.spec.failedJobsHistoryLimit" size="45" required
<input type="number" name="failedJobsHistoryLimit" [(ngModel)]="kubeResource.spec.failedJobsHistoryLimit" size="45" required
placeholder="'CRONJOB.MAX_EXECUTE_TIME' | translate">
</label>
</div>-->
</div>
</section>
<section *ngFor="let container of kubeCronjob.spec.jobTemplate.spec.template.spec.containers; let i = index"
<section *ngFor="let container of kubeResource.spec.jobTemplate.spec.template.spec.containers; let i = index"
class="form-block wrap">
<div>
<label class="label-level1" [id]="i ? '容器配置' + i : '容器配置'">{{'TEMPLATE.CONTAINER_CONFIG' | translate}}
Expand Down Expand Up @@ -167,6 +167,31 @@ <h3 class="header-title" id="创建计划任务模版">{{'CRONJOB.CREATE_TMP' |

</div>

<div class="container-box">
<label class="label-level2" [id]="i ? '启动命令' + i : '启动命令'">启动命令
<button (click)="onAddContainerCommand(i)" style="margin-left: 10px;" class="wayne-button primary">
<clr-icon shape="add-text"></clr-icon>
添加命令</button>
</label>
<div *ngFor="let cmd of container.command; let cmdIndex = index; trackBy:trackByFn">
<input style="margin-top: 10px" type="text" size="60" name="command_{{i}}_{{cmdIndex}}" [(ngModel)]="container.command[cmdIndex]"
placeholder="容器 Entrypoint">
<clr-icon style="margin-top: 5px;margin-left: 5px;" (click)="onDeleteContainerCommand(i,cmdIndex)" shape="trash" class="is-solid"></clr-icon>
</div>
</div>
<div class="container-box">
<label class="label-level2" [id]="i ? '启动参数' + i : '启动参数'">启动参数
<button (click)="onAddContainerArgs(i)" style="margin-left: 10px;" class="wayne-button primary">
<clr-icon shape="add-text"></clr-icon>
添加参数</button>
</label>
<div *ngFor="let arg of container.args; let l = index; trackBy:trackByFn">
<input style="margin-top: 10px" type="text" size="60" name="args_{{i}}_{{l}}" [(ngModel)]="container.args[l]"
placeholder="容器 CMD">
<clr-icon style="margin-top: 5px;margin-left: 5px;" (click)="onDeleteContainerArg(i,l)" shape="trash" class="is-solid"></clr-icon>
</div>
</div>

<div class="container-box">
<label class="label-level2" [id]="i ? '环境变量配置' + i : '环境变量配置'">{{'TEMPLATE.ENVIRONMENT_VAR' | translate}}
<button (click)="onAddEnvFrom(i)" style="margin-left: 10px;" class="wayne-button primary">
Expand Down
@@ -1,7 +1,7 @@
import { AfterViewInit, Component, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import { DOCUMENT, Location } from '@angular/common';
import { DOCUMENT, Location } from '@angular/common';
import { FormBuilder, NgForm } from '@angular/forms';
import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
import {
Expand Down Expand Up @@ -35,6 +35,7 @@ import { defaultCronJob } from '../../../shared/default-models/cronjob.const';
import { combineLatest } from 'rxjs';
import * as cron from 'cron-parser';
import { ObjectMeta } from '../../../shared/model/v1/kubernetes/deployment';
import { ContainerTpl } from '../../../shared/base/container/container-tpl';

const templateDom = [
{
Expand Down Expand Up @@ -67,7 +68,7 @@ const containerDom = {
templateUrl: 'create-edit-cronjobtpl.component.html',
styleUrls: ['create-edit-cronjobtpl.scss']
})
export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnDestroy {
export class CreateEditCronjobTplComponent extends ContainerTpl implements OnInit, AfterViewInit, OnDestroy {
ngForm: NgForm;
@ViewChild('ngForm')
currentForm: NgForm;
Expand All @@ -77,7 +78,6 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
isSubmitOnGoing = false;
app: App;
cronjob: Cronjob;
kubeCronjob: KubeCronJob = new KubeCronJob();
componentName = '计划任务模板';
top: number;
box: HTMLElement;
Expand All @@ -96,8 +96,34 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
private route: ActivatedRoute,
private messageHandlerService: MessageHandlerService,
@Inject(DOCUMENT) private document: any,
private eventManager: EventManager
) {
private eventManager: EventManager) {
super();
}

trackByFn(index: any, item: any) {
return index;
}

onAddContainerCommand(index: number) {
if (!this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].command) {
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].command = [];
}
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].command.push('');
}

onAddContainerArgs(index: number) {
if (!this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].args) {
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].args = [];
}
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].args.push('');
}

onDeleteContainerCommand(i: number, j: number) {
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[i].command.splice(j, 1);
}

onDeleteContainerArg(i: number, j: number) {
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[i].args.splice(j, 1);
}

ngAfterViewInit() {
Expand Down Expand Up @@ -132,7 +158,7 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD

get containersLength(): number {
try {
return this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers.length;
return this.kubeResource.spec.jobTemplate.spec.template.spec.containers.length;
} catch (error) {
return 0;
}
Expand All @@ -157,10 +183,10 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
}

get isScheduleValid(): boolean {
if (!this.kubeCronjob.spec.schedule) {
if (!this.kubeResource.spec.schedule) {
return false;
}
const result = cron.parseString(this.kubeCronjob.spec.schedule);
const result = cron.parseString(this.kubeResource.spec.schedule);
if (Object.keys(result.errors).length !== 0) {
return false;
}
Expand Down Expand Up @@ -216,8 +242,8 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
}

initDefault() {
this.kubeCronjob = JSON.parse(defaultCronJob);
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers.push(this.defaultContainer());
this.kubeResource = JSON.parse(defaultCronJob);
this.kubeResource.spec.jobTemplate.spec.template.spec.containers.push(this.defaultContainer());
}

defaultContainer(): Container {
Expand Down Expand Up @@ -275,51 +301,51 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD

fillCronjobLabel(kubeCronJob: KubeCronJob): KubeCronJob {
kubeCronJob.metadata.name = this.cronjob.name;
kubeCronJob.metadata.labels = this.buildLabels(this.kubeCronjob.metadata.labels);
kubeCronJob.spec.jobTemplate.metadata.labels = this.buildLabels(this.kubeCronjob.spec.jobTemplate.metadata.labels);
kubeCronJob.metadata.labels = this.buildLabels(this.kubeResource.metadata.labels);
kubeCronJob.spec.jobTemplate.metadata.labels = this.buildLabels(this.kubeResource.spec.jobTemplate.metadata.labels);
kubeCronJob.spec.jobTemplate.spec.template.metadata.labels = this.buildLabels(
this.kubeCronjob.spec.jobTemplate.spec.template.metadata.labels);
this.kubeResource.spec.jobTemplate.spec.template.metadata.labels);
return kubeCronJob;
}

onDeleteContainer(index: number) {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers.splice(index, 1);
this.kubeResource.spec.jobTemplate.spec.template.spec.containers.splice(index, 1);
this.initNavList();
}

onAddContainer() {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers.push(this.defaultContainer());
this.kubeResource.spec.jobTemplate.spec.template.spec.containers.push(this.defaultContainer());
this.initNavList();
}

onAddEnv(index: number) {
if (!this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[index].env) {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[index].env = [];
if (!this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].env) {
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].env = [];
}
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[index].env.push(this.defaultEnv(0));
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].env.push(this.defaultEnv(0));
}

onAddEnvFrom(index: number) {
if (!this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[index].envFrom) {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[index].envFrom = [];
if (!this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].envFrom) {
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].envFrom = [];
}
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[index].envFrom.push(this.defaultEnvFrom(1));
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[index].envFrom.push(this.defaultEnvFrom(1));
}

onDeleteEnv(i: number, j: number) {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[i].env.splice(j, 1);
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[i].env.splice(j, 1);
}

onDeleteEnvFrom(i: number, j: number) {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[i].envFrom.splice(j, 1);
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[i].envFrom.splice(j, 1);
}

envChange(type: number, i: number, j: number) {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[i].env[j] = this.defaultEnv(type);
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[i].env[j] = this.defaultEnv(type);
}

envFromChange(type: number, i: number, j: number) {
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers[i].envFrom[j] = this.defaultEnvFrom(type);
this.kubeResource.spec.jobTemplate.spec.template.spec.containers[i].envFrom[j] = this.defaultEnvFrom(type);
}

defaultEnv(type: number): EnvVar {
Expand Down Expand Up @@ -361,7 +387,7 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
}
this.isSubmitOnGoing = true;

let newState = JSON.parse(JSON.stringify(this.kubeCronjob));
let newState = JSON.parse(JSON.stringify(this.kubeResource));
newState = this.generateCronJob(newState);
this.cronjobTpl.cronjobId = this.cronjob.id;
this.cronjobTpl.template = JSON.stringify(newState);
Expand All @@ -381,20 +407,20 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
);
}

generateCronJob(kubeCronjob: KubeCronJob): KubeCronJob {
kubeCronjob = mergeDeep(JSON.parse(defaultCronJob), kubeCronjob);
this.kubeCronjob = mergeDeep(JSON.parse(defaultCronJob), this.kubeCronjob);
kubeCronjob = this.addResourceUnit(kubeCronjob);
kubeCronjob = this.fillCronjobLabel(kubeCronjob);
generateCronJob(kubeResource: KubeCronJob): KubeCronJob {
kubeResource = mergeDeep(JSON.parse(defaultCronJob), kubeResource);
this.kubeResource = mergeDeep(JSON.parse(defaultCronJob), this.kubeResource);
kubeResource = this.addResourceUnit(kubeResource);
kubeResource = this.fillCronjobLabel(kubeResource);

return kubeCronjob;
return kubeResource;
}

saveCronjob(kubeCronjob: KubeCronJob) {
saveCronjob(kubeResource: KubeCronJob) {
// this.removeResourceUnit(kubeStatefulSet);
this.removeUnused(kubeCronjob);
this.fillDefault(kubeCronjob);
this.kubeCronjob = kubeCronjob;
this.removeUnused(kubeResource);
this.fillDefault(kubeResource);
this.kubeResource = kubeResource;
this.initNavList();
}

Expand All @@ -409,11 +435,11 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
obj.status = undefined;
}

fillDefault(kubeCronjob: KubeCronJob) {
this.kubeCronjob = mergeDeep(JSON.parse(defaultCronJob), kubeCronjob);
if (this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers &&
this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers.length > 0) {
for (const container of this.kubeCronjob.spec.jobTemplate.spec.template.spec.containers) {
fillDefault(kubeResource: KubeCronJob) {
this.kubeResource = mergeDeep(JSON.parse(defaultCronJob), kubeResource);
if (this.kubeResource.spec.jobTemplate.spec.template.spec.containers &&
this.kubeResource.spec.jobTemplate.spec.template.spec.containers.length > 0) {
for (const container of this.kubeResource.spec.jobTemplate.spec.template.spec.containers) {
if (!container.resources) {
container.resources = ResourceRequirements.emptyObject();
}
Expand All @@ -426,7 +452,7 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
}
}

addResourceUnit(kubeCronjob: KubeCronJob): KubeCronJob {
addResourceUnit(kubeResource: KubeCronJob): KubeCronJob {
let cpuRequestLimitPercent = 0.5;
let memoryRequestLimitPercent = 1;
if (this.cronjob.metaData) {
Expand All @@ -447,7 +473,7 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
}
}

for (const container of kubeCronjob.spec.jobTemplate.spec.template.spec.containers) {
for (const container of kubeResource.spec.jobTemplate.spec.template.spec.containers) {
const memoryLimit = container.resources.limits['memory'];
const cpuLimit = container.resources.limits['cpu'];
if (!container.resources.requests) {
Expand All @@ -462,7 +488,7 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
container.resources.requests['cpu'] = (parseFloat(cpuLimit) * cpuRequestLimitPercent).toString();
}
}
return kubeCronjob;
return kubeResource;
}

public get isValid(): boolean {
Expand All @@ -484,7 +510,7 @@ export class CreateEditCronjobTplComponent implements OnInit, AfterViewInit, OnD
openModal(): void {
// let copy = Object.assign({}, myObject).
// but this wont work for nested objects. SO an alternative would be
let newState = JSON.parse(JSON.stringify(this.kubeCronjob));
let newState = JSON.parse(JSON.stringify(this.kubeResource));
newState = this.generateCronJob(newState);
this.aceEditorService.announceMessage(AceEditorMsg.Instance(newState, true));
}
Expand Down