Files
backroad/app/portainer/services/api/templateService.js
Chaim Lev-Ari 53b37ab8c8 feat(custom-templates): introduce custom templates (#3906)
* feat(custom-templates): introduce types

* feat(custom-templates): introduce data layer service

* feat(custom-templates): introduce http handler

* feat(custom-templates): create routes and view stubs

* feat(custom-templates): add create custom template ui

* feat(custom-templates): add json keys

* feat(custom-templates): introduce custom templates list page

* feat(custom-templates): introduce update page

* feat(stack): create template from stack

* feat(stacks): create stack from custom template

* feat(custom-templates): disable edit/delete of templates

* fix(custom-templates): fail update on non admin/owner

* fix(custom-templates): add ng-inject decorator

* chore(plop): revert template

* feat(stacks): remove actions column

* feat(stack): add button to create template from stack

* feat(stacks): add empty state for templates

* feat(custom-templates): show templates in a list

* feat(custom-template): replace table with list

* feat(custom-templates): move create template button

* refactor(custom-templates): introduce more fields

* feat(custom-templates): use stack type when creating template

* feat(custom-templates): use same type as stack

* feat(custom-templates): add edit and delete buttons to template item

* feat(custom-templates): customize stack before deploy

* feat(stack): show template details

* feat(custom-templates): move customize

* feat(custom-templates): create description required

* fix(template): show platform icon

* fix(custom-templates): show spinner when creating stack

* feat(custom-templates): prevent user from edit templates

* feat(custom-templates): use resource control for custom templates

* feat(custom-templates): show created templates

* feat(custom-templates): filter templates by stack type

* fix(custom-templates): create swarm or standalone stack

* feat(stacks): filter templates by type

* feat(resource-control): disable resource control on public

* feat(custom-template): apply access control on edit

* feat(custom-template): add form validation

* feat(stack): disable create custom template from external task

* refactor(custom-templates): create template from file and type

* feat(templates): introduce a file handler that returns template docker file

* feat(template): introduce template duplication

* feat(custom-template): enforce unique template name

* fix(template): rename copy button

* fix(custom-template): clear access control selection between templates

* fix(custom-templates): show required fields

* refactor(filesystem): use a constant for temp path
2020-07-07 11:18:39 +12:00

92 lines
3.9 KiB
JavaScript

import _ from 'lodash-es';
import { TemplateViewModel } from '../../models/template';
angular.module('portainer.app').factory('TemplateService', [
'$q',
'Templates',
'TemplateHelper',
'RegistryService',
'DockerHubService',
'ImageHelper',
'ContainerHelper',
function TemplateServiceFactory($q, Templates, TemplateHelper, RegistryService, DockerHubService, ImageHelper, ContainerHelper) {
'use strict';
var service = {};
service.templates = function () {
const deferred = $q.defer();
$q.all({
templates: Templates.query().$promise,
registries: RegistryService.registries(),
dockerhub: DockerHubService.dockerhub(),
})
.then(function success(data) {
const version = data.templates.version;
const templates = _.map(data.templates.templates, (item) => {
try {
const template = new TemplateViewModel(item, version);
const registry = RegistryService.retrievePorRegistryModelFromRepositoryWithRegistries(template.RegistryModel.Registry.URL, data.registries, data.dockerhub);
registry.Image = template.RegistryModel.Image;
template.RegistryModel = registry;
return template;
} catch (err) {
deferred.reject({ msg: 'Unable to retrieve templates', err: err });
}
});
deferred.resolve(templates);
})
.catch(function error(err) {
deferred.reject({ msg: 'Unable to retrieve templates', err: err });
});
return deferred.promise;
};
service.templateFile = templateFile;
function templateFile(repositoryUrl, composeFilePathInRepository) {
return Templates.file({ repositoryUrl, composeFilePathInRepository }).$promise;
}
service.createTemplateConfiguration = function (template, containerName, network) {
var imageConfiguration = ImageHelper.createImageConfigForContainer(template.RegistryModel);
var containerConfiguration = createContainerConfiguration(template, containerName, network);
containerConfiguration.Image = imageConfiguration.fromImage;
return containerConfiguration;
};
function createContainerConfiguration(template, containerName, network) {
var configuration = TemplateHelper.getDefaultContainerConfiguration();
configuration.HostConfig.NetworkMode = network.Name;
configuration.HostConfig.Privileged = template.Privileged;
configuration.HostConfig.RestartPolicy = { Name: template.RestartPolicy };
configuration.HostConfig.ExtraHosts = template.Hosts ? template.Hosts : [];
configuration.name = containerName;
configuration.Hostname = template.Hostname;
configuration.Env = TemplateHelper.EnvToStringArray(template.Env);
configuration.Cmd = ContainerHelper.commandStringToArray(template.Command);
var portConfiguration = TemplateHelper.portArrayToPortConfiguration(template.Ports);
configuration.HostConfig.PortBindings = portConfiguration.bindings;
configuration.ExposedPorts = portConfiguration.exposedPorts;
var consoleConfiguration = TemplateHelper.getConsoleConfiguration(template.Interactive);
configuration.OpenStdin = consoleConfiguration.openStdin;
configuration.Tty = consoleConfiguration.tty;
configuration.Labels = TemplateHelper.updateContainerConfigurationWithLabels(template.Labels);
return configuration;
}
service.updateContainerConfigurationWithVolumes = function (configuration, template, generatedVolumesPile) {
var volumes = template.Volumes;
TemplateHelper.createVolumeBindings(volumes, generatedVolumesPile);
volumes.forEach(function (volume) {
if (volume.binding) {
configuration.Volumes[volume.container] = {};
configuration.HostConfig.Binds.push(volume.binding);
}
});
};
return service;
},
]);