Cleanup display of image commands to be better shared
Also moves the work into a TS component
This commit is contained in:
parent
7f436bb54a
commit
1d60414a23
10 changed files with 41 additions and 51 deletions
|
@ -164,9 +164,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
||||||
<span bo-if="feature.imageCommand">
|
<span bo-if="feature.imageCommand">
|
||||||
<span data-title="{{ feature.imageCommand }}" data-container="body" bs-tooltip>
|
<image-command command="feature.imageCommand"></image-command>
|
||||||
<dockerfile-command command="feature.imageCommand"></dockerfile-command>
|
|
||||||
</span>
|
|
||||||
<a href="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ feature.imageId }}"><i class="fa fa-archive"></i></a>
|
<a href="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ feature.imageId }}"><i class="fa fa-archive"></i></a>
|
||||||
</span>
|
</span>
|
||||||
<span bo-if="!feature.imageCommand">
|
<span bo-if="!feature.imageCommand">
|
||||||
|
|
|
@ -5,9 +5,7 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="image-command">
|
<div class="image-command">
|
||||||
<div class="nondocker-command" ng-if="!getDockerfileCommand(image.command)">{{ image.command.join(' ') }}</div>
|
<image-command command="image.command"></image-command>
|
||||||
<dockerfile-command command="getDockerfileCommand(image.command)"
|
|
||||||
ng-if="getDockerfileCommand(image.command)"></dockerfile-command>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="image-layer-dot"></div>
|
<div class="image-layer-dot"></div>
|
||||||
<div class="image-layer-line"></div>
|
<div class="image-layer-line"></div>
|
||||||
|
|
|
@ -152,9 +152,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
<td class="double-col image-col hidden-xs hidden-sm hidden-md">
|
||||||
<span bo-if="vuln.imageCommand">
|
<span bo-if="vuln.imageCommand">
|
||||||
<span data-title="{{ vuln.imageCommand }}" data-container="body" bs-tooltip>
|
<image-command command="vuln.imageCommand"></image-command>
|
||||||
<dockerfile-command command="vuln.imageCommand"></dockerfile-command>
|
|
||||||
</span>
|
|
||||||
<a href="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ vuln.imageId }}"><i class="fa fa-archive"></i></a>
|
<a href="/repository/{{ repository.namespace }}/{{ repository.name }}/image/{{ vuln.imageId }}"><i class="fa fa-archive"></i></a>
|
||||||
</span>
|
</span>
|
||||||
<span bo-if="!vuln.imageCommand">
|
<span bo-if="!vuln.imageCommand">
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="image-command-element">
|
||||||
|
<div class="nondocker-command" ng-if="!$ctrl.getDockerfileCommand($ctrl.command)">{{ ::$ctrl.command.join(' ') }}</div>
|
||||||
|
<dockerfile-command command="::$ctrl.getDockerfileCommand($ctrl.command)"
|
||||||
|
ng-if="$ctrl.getDockerfileCommand($ctrl.command)"></dockerfile-command>
|
||||||
|
</div>
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Input, Component, Inject } from 'ng-metadata/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A component which displays an image's command, nicely formatted.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'image-command',
|
||||||
|
templateUrl: '/static/js/directives/ui/image-command/image-command.component.html',
|
||||||
|
})
|
||||||
|
export class ImageCommandComponent {
|
||||||
|
@Input('<') public command: string;
|
||||||
|
|
||||||
|
private getDockerfileCommand(command: string[]): string {
|
||||||
|
if (!command || !command.length) { return ''; }
|
||||||
|
command = command.join(' ').split(' ');
|
||||||
|
|
||||||
|
// ["/bin/sh", "-c", "#(nop)", "RUN", "foo"]
|
||||||
|
if (command[0] != '/bin/sh' || command[1] != '-c') { return ''; }
|
||||||
|
|
||||||
|
if (command[2].trim() != '#(nop)') {
|
||||||
|
return 'RUN ' + command.slice(2).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return command.slice(3).join(' ');
|
||||||
|
};
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ angular.module('quay').directive('imageFeatureView', function () {
|
||||||
'image': '=image',
|
'image': '=image',
|
||||||
'isEnabled': '=isEnabled'
|
'isEnabled': '=isEnabled'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, Config, ApiService, VulnerabilityService, ViewArray, ImageMetadataService, TableService) {
|
controller: function($scope, $element, Config, ApiService, VulnerabilityService, ViewArray, TableService) {
|
||||||
$scope.options = {
|
$scope.options = {
|
||||||
'filter': null,
|
'filter': null,
|
||||||
'predicate': 'fixableScore',
|
'predicate': 'fixableScore',
|
||||||
|
|
|
@ -13,9 +13,7 @@ angular.module('quay').directive('imageViewLayer', function () {
|
||||||
'image': '=image',
|
'image': '=image',
|
||||||
'images': '=images'
|
'images': '=images'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, ImageMetadataService) {
|
controller: function($scope, $element) {
|
||||||
$scope.getDockerfileCommand = ImageMetadataService.getDockerfileCommand;
|
|
||||||
|
|
||||||
$scope.getClass = function() {
|
$scope.getClass = function() {
|
||||||
var index = $.inArray($scope.image, $scope.images);
|
var index = $.inArray($scope.image, $scope.images);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ angular.module('quay').directive('imageVulnerabilityView', function () {
|
||||||
'image': '=image',
|
'image': '=image',
|
||||||
'isEnabled': '=isEnabled'
|
'isEnabled': '=isEnabled'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, $routeParams, Config, ApiService, VulnerabilityService, ViewArray, ImageMetadataService, TableService) {
|
controller: function($scope, $element, $routeParams, Config, ApiService, VulnerabilityService, ViewArray, TableService) {
|
||||||
$scope.options = {
|
$scope.options = {
|
||||||
'filter': null,
|
'filter': null,
|
||||||
'fixableVulns': $routeParams['fixable'] == 'true',
|
'fixableVulns': $routeParams['fixable'] == 'true',
|
||||||
|
|
|
@ -29,6 +29,7 @@ import { MarkdownViewComponent } from './directives/ui/markdown/markdown-view.co
|
||||||
import { MarkdownToolbarComponent } from './directives/ui/markdown/markdown-toolbar.component';
|
import { MarkdownToolbarComponent } from './directives/ui/markdown/markdown-toolbar.component';
|
||||||
import { MarkdownEditorComponent } from './directives/ui/markdown/markdown-editor.component';
|
import { MarkdownEditorComponent } from './directives/ui/markdown/markdown-editor.component';
|
||||||
import { DockerfileCommandComponent } from './directives/ui/dockerfile-command/dockerfile-command.component';
|
import { DockerfileCommandComponent } from './directives/ui/dockerfile-command/dockerfile-command.component';
|
||||||
|
import { ImageCommandComponent } from './directives/ui/image-command/image-command.component';
|
||||||
import { BrowserPlatform, browserPlatform } from './constants/platform.constant';
|
import { BrowserPlatform, browserPlatform } from './constants/platform.constant';
|
||||||
import { ManageTriggerComponent } from './directives/ui/manage-trigger/manage-trigger.component';
|
import { ManageTriggerComponent } from './directives/ui/manage-trigger/manage-trigger.component';
|
||||||
import { ClipboardCopyDirective } from './directives/ui/clipboard-copy/clipboard-copy.directive';
|
import { ClipboardCopyDirective } from './directives/ui/clipboard-copy/clipboard-copy.directive';
|
||||||
|
@ -68,6 +69,7 @@ import * as Clipboard from 'clipboard';
|
||||||
MarkdownEditorComponent,
|
MarkdownEditorComponent,
|
||||||
SearchBoxComponent,
|
SearchBoxComponent,
|
||||||
DockerfileCommandComponent,
|
DockerfileCommandComponent,
|
||||||
|
ImageCommandComponent,
|
||||||
TypeaheadDirective,
|
TypeaheadDirective,
|
||||||
ManageTriggerComponent,
|
ManageTriggerComponent,
|
||||||
ClipboardCopyDirective,
|
ClipboardCopyDirective,
|
||||||
|
|
|
@ -1,28 +1,8 @@
|
||||||
/**
|
/**
|
||||||
* Helper service for returning information extracted from repository image metadata.
|
* Helper service for returning information extracted from repository image metadata.
|
||||||
*/
|
*/
|
||||||
angular.module('quay').factory('ImageMetadataService', ['UtilService', function(UtilService) {
|
angular.module('quay').factory('ImageMetadataService', [function() {
|
||||||
var metadataService = {};
|
var metadataService = {};
|
||||||
metadataService.getFormattedCommand = function(image) {
|
|
||||||
if (!image || !image.command || !image.command.length) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
var getCommandStr = function(command) {
|
|
||||||
// Handle /bin/sh commands specially.
|
|
||||||
if (command.length > 2 && command[0] == '/bin/sh' && command[1] == '-c') {
|
|
||||||
return command[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
return command.join(' ');
|
|
||||||
};
|
|
||||||
|
|
||||||
return getCommandStr(image.command);
|
|
||||||
};
|
|
||||||
|
|
||||||
metadataService.getEscapedFormattedCommand = function(image) {
|
|
||||||
return UtilService.textToSafeHtml(metadataService.getFormattedCommand(image));
|
|
||||||
};
|
|
||||||
|
|
||||||
metadataService.getImageCommand = function(image, imageId) {
|
metadataService.getImageCommand = function(image, imageId) {
|
||||||
if (!image) {
|
if (!image) {
|
||||||
|
@ -44,22 +24,7 @@ angular.module('quay').factory('ImageMetadataService', ['UtilService', function(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return metadataService.getDockerfileCommand(found.command);
|
return found.command;
|
||||||
};
|
|
||||||
|
|
||||||
metadataService.getDockerfileCommand = function(command) {
|
|
||||||
if (!command) { return ''; }
|
|
||||||
command = command.join(' ').split(' ');
|
|
||||||
|
|
||||||
// ["/bin/sh", "-c", "#(nop)", "RUN", "foo"]
|
|
||||||
if (command[0] != '/bin/sh' || command[1] != '-c') { return ''; }
|
|
||||||
|
|
||||||
var commandPrefix = '#(nop)';
|
|
||||||
if (command[2] != commandPrefix) {
|
|
||||||
return 'RUN ' + command.slice(2).join(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
return command.slice(3).join(' ');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return metadataService;
|
return metadataService;
|
||||||
|
|
Reference in a new issue