199 lines
5.6 KiB
JavaScript
199 lines
5.6 KiB
JavaScript
|
/**
|
||
|
* An element which displays a form for manually starting a dockerfile build.
|
||
|
*/
|
||
|
angular.module('quay').directive('dockerfileBuildForm', function () {
|
||
|
var directiveDefinitionObject = {
|
||
|
priority: 0,
|
||
|
templateUrl: '/static/directives/dockerfile-build-form.html',
|
||
|
replace: false,
|
||
|
transclude: false,
|
||
|
restrict: 'C',
|
||
|
scope: {
|
||
|
'repository': '=repository',
|
||
|
'startNow': '=startNow',
|
||
|
'isReady': '=isReady',
|
||
|
'uploadFailed': '&uploadFailed',
|
||
|
'uploadStarted': '&uploadStarted',
|
||
|
'buildStarted': '&buildStarted',
|
||
|
'buildFailed': '&buildFailed',
|
||
|
'missingFile': '&missingFile',
|
||
|
'uploading': '=uploading',
|
||
|
'building': '=building'
|
||
|
},
|
||
|
controller: function($scope, $element, ApiService) {
|
||
|
$scope.internal = {'hasDockerfile': false};
|
||
|
$scope.pull_entity = null;
|
||
|
$scope.is_public = true;
|
||
|
|
||
|
var handleBuildFailed = function(message) {
|
||
|
message = message || 'Dockerfile build failed to start';
|
||
|
|
||
|
var result = false;
|
||
|
if ($scope.buildFailed) {
|
||
|
result = $scope.buildFailed({'message': message});
|
||
|
}
|
||
|
|
||
|
if (!result) {
|
||
|
bootbox.dialog({
|
||
|
"message": message,
|
||
|
"title": "Cannot start Dockerfile build",
|
||
|
"buttons": {
|
||
|
"close": {
|
||
|
"label": "Close",
|
||
|
"className": "btn-primary"
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var handleUploadFailed = function(message) {
|
||
|
message = message || 'Error with file upload';
|
||
|
|
||
|
var result = false;
|
||
|
if ($scope.uploadFailed) {
|
||
|
result = $scope.uploadFailed({'message': message});
|
||
|
}
|
||
|
|
||
|
if (!result) {
|
||
|
bootbox.dialog({
|
||
|
"message": message,
|
||
|
"title": "Cannot upload file for Dockerfile build",
|
||
|
"buttons": {
|
||
|
"close": {
|
||
|
"label": "Close",
|
||
|
"className": "btn-primary"
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var handleMissingFile = function() {
|
||
|
var result = false;
|
||
|
if ($scope.missingFile) {
|
||
|
result = $scope.missingFile({});
|
||
|
}
|
||
|
|
||
|
if (!result) {
|
||
|
bootbox.dialog({
|
||
|
"message": 'A Dockerfile or an archive containing a Dockerfile is required',
|
||
|
"title": "Missing Dockerfile",
|
||
|
"buttons": {
|
||
|
"close": {
|
||
|
"label": "Close",
|
||
|
"className": "btn-primary"
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var startBuild = function(fileId) {
|
||
|
$scope.building = true;
|
||
|
|
||
|
var repo = $scope.repository;
|
||
|
var data = {
|
||
|
'file_id': fileId
|
||
|
};
|
||
|
|
||
|
if (!$scope.is_public && $scope.pull_entity) {
|
||
|
data['pull_robot'] = $scope.pull_entity['name'];
|
||
|
}
|
||
|
|
||
|
var params = {
|
||
|
'repository': repo.namespace + '/' + repo.name,
|
||
|
};
|
||
|
|
||
|
ApiService.requestRepoBuild(data, params).then(function(resp) {
|
||
|
$scope.building = false;
|
||
|
$scope.uploading = false;
|
||
|
|
||
|
if ($scope.buildStarted) {
|
||
|
$scope.buildStarted({'build': resp});
|
||
|
}
|
||
|
}, function(resp) {
|
||
|
$scope.building = false;
|
||
|
$scope.uploading = false;
|
||
|
|
||
|
handleBuildFailed(resp.message);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
var conductUpload = function(file, url, fileId, mimeType) {
|
||
|
if ($scope.uploadStarted) {
|
||
|
$scope.uploadStarted({});
|
||
|
}
|
||
|
|
||
|
var request = new XMLHttpRequest();
|
||
|
request.open('PUT', url, true);
|
||
|
request.setRequestHeader('Content-Type', mimeType);
|
||
|
request.onprogress = function(e) {
|
||
|
$scope.$apply(function() {
|
||
|
var percentLoaded;
|
||
|
if (e.lengthComputable) {
|
||
|
$scope.upload_progress = (e.loaded / e.total) * 100;
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
request.onerror = function() {
|
||
|
$scope.$apply(function() {
|
||
|
handleUploadFailed();
|
||
|
});
|
||
|
};
|
||
|
request.onreadystatechange = function() {
|
||
|
var state = request.readyState;
|
||
|
if (state == 4) {
|
||
|
$scope.$apply(function() {
|
||
|
startBuild(fileId);
|
||
|
$scope.uploading = false;
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
};
|
||
|
request.send(file);
|
||
|
};
|
||
|
|
||
|
var startFileUpload = function(repo) {
|
||
|
$scope.uploading = true;
|
||
|
$scope.uploading_progress = 0;
|
||
|
|
||
|
var uploader = $('#file-drop')[0];
|
||
|
if (uploader.files.length == 0) {
|
||
|
handleMissingFile();
|
||
|
$scope.uploading = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var file = uploader.files[0];
|
||
|
$scope.upload_file = file.name;
|
||
|
|
||
|
var mimeType = file.type || 'application/octet-stream';
|
||
|
var data = {
|
||
|
'mimeType': mimeType
|
||
|
};
|
||
|
|
||
|
var getUploadUrl = ApiService.getFiledropUrl(data).then(function(resp) {
|
||
|
conductUpload(file, resp.url, resp.file_id, mimeType);
|
||
|
}, function() {
|
||
|
handleUploadFailed('Could not retrieve upload URL');
|
||
|
});
|
||
|
};
|
||
|
|
||
|
var checkIsReady = function() {
|
||
|
$scope.isReady = $scope.internal.hasDockerfile && ($scope.is_public || $scope.pull_entity);
|
||
|
};
|
||
|
|
||
|
$scope.$watch('pull_entity', checkIsReady);
|
||
|
$scope.$watch('is_public', checkIsReady);
|
||
|
$scope.$watch('internal.hasDockerfile', checkIsReady);
|
||
|
|
||
|
$scope.$watch('startNow', function() {
|
||
|
if ($scope.startNow && $scope.repository && !$scope.uploading && !$scope.building) {
|
||
|
startFileUpload();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
return directiveDefinitionObject;
|
||
|
});
|