Skip to content

Commit

Permalink
Merge pull request #268 from cobbler/feature/add-buildiso
Browse files Browse the repository at this point in the history
Feature: Implement UI for "cobbler buildiso"
  • Loading branch information
SchoolGuy authored Jul 20, 2024
2 parents c43158c + b133c64 commit 311ae4a
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 25 deletions.
29 changes: 25 additions & 4 deletions projects/cobbler-api/src/lib/cobbler-api.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {TestBed} from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {BackgroundImportOptions, BackgroundReplicateOptions} from 'cobbler-api';
import {BackgroundBuildisoOptions, BackgroundImportOptions, BackgroundReplicateOptions} from 'cobbler-api';
import {Event, ExtendedVersion, InstallationStatus} from './custom-types/misc';
import {COBBLER_URL} from './lib.config';
import {AngularXmlrpcService} from 'typescript-xmlrpc';
Expand Down Expand Up @@ -72,9 +72,30 @@ describe('CobblerApiService', () => {
mockRequest.flush(methodResponse);
});

xit('should execute the background_buildiso action on the Cobbler Server', () => {
service.background_buildiso(undefined, '');
expect(service).toBeFalsy();
it('should execute the background_buildiso action on the Cobbler Server', (done: DoneFn) => {
// eslint-disable-next-line max-len
const methodResponse = `<?xml version='1.0'?><methodResponse><params><param><value><string>2023-01-24_083001_Build Iso_20fa7d4256fc4f61a2b9c2237c80fb41</string></value></param></params></methodResponse>`
const result = "2023-01-24_083001_Build Iso_20fa7d4256fc4f61a2b9c2237c80fb41"
const buildisoOptions: BackgroundBuildisoOptions = {
iso: "",
profiles: "",
systems: "",
buildisodir: "",
distro: "",
standalone: false,
airgapped: false,
source: "",
excludeDNS: false,
xorrisofsOpts: "",
}

service.background_buildiso(buildisoOptions, '').subscribe(
value => {
expect(value).toEqual(result);
done();
});
const mockRequest = httpTestingController.expectOne('http://localhost/cobbler_api');
mockRequest.flush(methodResponse);
});

xit('should execute the background_aclsetup action on the Cobbler Server', () => {
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
<div class="right-column" id="dataScreen">
<router-outlet></router-outlet>
<div class="BuildISO-div">
<h1 class="title"> BUILD </h1>
<div class="list-group">
<mat-list>
<mat-list-item>data 01</mat-list-item>
<mat-list-item>data 02</mat-list-item>
<mat-list-item>data 03</mat-list-item>
</mat-list>
</div>
</div>
</div>
<h1 class="title"> BUILD ISO IMAGES </h1>

<form class="form-replicate" [formGroup]="buildisoFormGroup">
<mat-form-field class="form-field-full-width">
<mat-label>Distro</mat-label>
<input matInput required type="text" formControlName="distro" placeholder="leap-x86_64" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>ISO</mat-label>
<input matInput type="text" formControlName="iso" placeholder="/var/lib/cobbler/isos/autoinstall.iso" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Profiles</mat-label>
<input matInput type="text" formControlName="profiles" placeholder="" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Systems</mat-label>
<input matInput type="text" formControlName="systems" placeholder="" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Buildiso directory</mat-label>
<input matInput type="text" formControlName="buildisodir" placeholder="/var/cache/cobbler/buildiso" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Source</mat-label>
<input matInput type="text" formControlName="source" placeholder="/var/lib/cobbler/iso-source/leap-x86_64" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>xorrisofs Options</mat-label>
<input matInput type="text" formControlName="xorrisofsOpts" placeholder="-v" />
</mat-form-field>
<mat-checkbox class="form-field-full-width" formControlName="standalone">Standalone</mat-checkbox>
<mat-checkbox class="form-field-full-width" formControlName="airgapped">Airgapped</mat-checkbox>
<mat-checkbox class="form-field-full-width" formControlName="excludeDNS">Exclude DNS</mat-checkbox>
<button mat-button (click)="runBuildiso()">Run</button>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.form-replicate {
min-width: 150px;
max-width: 600px;
width: 100%;
}

.form-field-full-width {
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {provideHttpClient} from '@angular/common/http';
import {provideHttpClientTesting} from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatListModule } from '@angular/material/list';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {provideRouter} from '@angular/router';
import {COBBLER_URL} from 'cobbler-api';

import { BuildISOComponent } from './build-iso.component';

Expand All @@ -11,9 +15,17 @@ describe('BuildISOComponent', () => {

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MatListModule, BuildISOComponent],
imports: [
BuildISOComponent,
NoopAnimationsModule,
],
providers: [
provideRouter([]),
provideHttpClient(),
provideHttpClientTesting(),
{
provide: COBBLER_URL,
useValue: new URL('http://localhost/cobbler_api')
},
]
}).compileComponents();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,81 @@
import { Component } from '@angular/core';
import { MatListModule } from '@angular/material/list';
import { RouterOutlet } from '@angular/router';
import {Component, inject} from '@angular/core';
import {FormBuilder, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButton} from '@angular/material/button';
import {MatCheckbox} from '@angular/material/checkbox';
import {MatFormField, MatLabel} from '@angular/material/form-field';
import {MatInput} from '@angular/material/input';
import {MatListModule} from '@angular/material/list';
import {MatSnackBar} from '@angular/material/snack-bar';
import {BackgroundBuildisoOptions, CobblerApiService} from 'cobbler-api';
import {UserService} from '../../services/user.service';

@Component({
selector: 'cobbler-build-iso',
templateUrl: './build-iso.component.html',
styleUrls: ['./build-iso.component.css'],
styleUrls: ['./build-iso.component.scss'],
standalone: true,
imports: [RouterOutlet, MatListModule],
imports: [
MatListModule,
FormsModule,
MatButton,
MatFormField,
MatInput,
MatLabel,
ReactiveFormsModule,
MatCheckbox
],
})
export class BuildISOComponent {
constructor() {}
private readonly _formBuilder = inject(FormBuilder);
buildisoFormGroup = this._formBuilder.group({
iso: '',
profiles: '',
systems: '',
buildisodir: '',
distro: '',
standalone: false,
airgapped: false,
source: '',
excludeDNS: false,
xorrisofsOpts: '',
})

constructor(
public userService: UserService,
private cobblerApiService: CobblerApiService,
private _snackBar: MatSnackBar
) {
}

runBuildiso(): void {
const buildisoOptions: BackgroundBuildisoOptions = {
iso: this.buildisoFormGroup.controls.iso.value,
profiles: this.buildisoFormGroup.controls.profiles.value,
systems: this.buildisoFormGroup.controls.systems.value,
buildisodir: this.buildisoFormGroup.controls.buildisodir.value,
distro: this.buildisoFormGroup.controls.distro.value,
standalone: this.buildisoFormGroup.controls.standalone.value,
airgapped: this.buildisoFormGroup.controls.airgapped.value,
source: this.buildisoFormGroup.controls.source.value,
excludeDNS: this.buildisoFormGroup.controls.excludeDNS.value,
xorrisofsOpts: this.buildisoFormGroup.controls.xorrisofsOpts.value,
};
if (this.buildisoFormGroup.invalid) {
this._snackBar.open('Please fill out all required inputs!', 'Close', {duration: 2000});
return;
}
this.cobblerApiService.background_buildiso(buildisoOptions, this.userService.token).subscribe(
value => {
// TODO
},
error => {
// HTML encode the error message since it originates from XML
this._snackBar.open(this.toHTML(error.message), 'Close');
});
}

toHTML(input: string): any {
// FIXME: Deduplicate method
return new DOMParser().parseFromString(input, 'text/html').documentElement.textContent;
}
}

0 comments on commit 311ae4a

Please sign in to comment.