1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

Implemented remaining container creation options.

This commit is contained in:
Kevan Ahlquist 2015-01-25 15:52:40 -06:00
parent c8213bbf33
commit 4682ae4ca7
8 changed files with 351 additions and 201 deletions

View file

@ -1,4 +1,4 @@
angular.module('startContainer', [])
angular.module('startContainer', ['ui.bootstrap'])
.controller('StartContainerController', ['$scope', '$routeParams', '$location', 'Container', 'Messages', 'containernameFilter',
function($scope, $routeParams, $location, Container, Messages, containernameFilter) {
$scope.template = 'app/components/startContainer/startcontainer.html';
@ -10,81 +10,94 @@ function($scope, $routeParams, $location, Container, Messages, containernameFilt
});
$scope.config = {
name: '',
memory: 0,
memorySwap: 0,
cpuShares: 1024,
env: [],
commands: '',
volumesFrom: [],
portBindings: []
Env: [],
Volumes: [],
SecurityOpts: [],
PortBindings: [],
HostConfig: {
Binds: [],
Links: [],
Dns: [],
DnsSearch: [],
VolumesFrom: [],
CapAdd: [],
CapDrop: []
}
};
$scope.commandPlaceholder = '["/bin/echo", "Hello world"]';
function failedRequestHandler(e, Messages) {
Messages.send({class: 'text-error', data: e.data});
}
$scope.create = function() {
var cmds = null;
if ($scope.config.commands !== '') {
cmds = angular.fromJson($scope.config.commands);
function rmEmptyKeys(col) {
for (var key in col) {
if (col[key] === null || col[key] === undefined || col[key] === '' || $.isEmptyObject(col[key]) || col[key].length === 0) {
delete col[key];
}
}
var id = $routeParams.id;
var ctor = Container;
var loc = $location;
var s = $scope;
}
var volumesFrom = $scope.config.volumesFrom.map(function(volume) {
return volume.name;
});
function getNames(arr) {
return arr.map(function(item) {return item.name;});
}
var env = $scope.config.env.map(function(envar) {
return envar.name + '=' + envar.value;
});
$scope.create = function() {
// Copy the config before transforming fields to the remote API format
var config = angular.copy($scope.config);
var exposedPorts = {};
var portBindings = {};
config.Image = $routeParams.id;
if (config.Cmd && config.Cmd[0] === "[") {
config.Cmd = angular.fromJson(config.Cmd);
}
config.Env = config.Env.map(function(envar) {return envar.name + '=' + envar.value;});
config.Volumes = getNames(config.Volumes);
config.SecurityOpts = getNames(config.SecurityOpts);
config.HostConfig.VolumesFrom = getNames(config.HostConfig.VolumesFrom);
config.HostConfig.Binds = getNames(config.HostConfig.Binds);
config.HostConfig.Links = getNames(config.HostConfig.Links);
config.HostConfig.Dns = getNames(config.HostConfig.Dns);
config.HostConfig.DnsSearch = getNames(config.HostConfig.DnsSearch);
config.HostConfig.CapAdd = getNames(config.HostConfig.CapAdd);
config.HostConfig.CapDrop = getNames(config.HostConfig.CapDrop);
var ExposedPorts = {};
var PortBindings = {};
// TODO: consider using compatibility library
$scope.config.portBindings.forEach(function(portBinding) {
config.PortBindings.forEach(function(portBinding) {
var intPort = portBinding.intPort + "/tcp";
var binding = {
HostIp: portBinding.ip,
HostPort: portBinding.extPort
};
if (portBinding.intPort) {
exposedPorts[intPort] = {};
if (intPort in portBindings) {
portBindings[intPort].push(binding);
ExposedPorts[intPort] = {};
if (intPort in PortBindings) {
PortBindings[intPort].push(binding);
} else {
portBindings[intPort] = [binding];
PortBindings[intPort] = [binding];
}
} else {
// TODO: Send warning message? Internal port need to be specified.
}
});
config.ExposedPorts = ExposedPorts;
delete config.PortBindings;
config.HostConfig.PortBindings = PortBindings;
Container.create({
Image: id,
name: $scope.config.name,
Memory: $scope.config.memory,
MemorySwap: $scope.config.memorySwap,
CpuShares: $scope.config.cpuShares,
Cmd: cmds,
VolumesFrom: volumesFrom,
Env: env,
ExposedPorts: exposedPorts,
HostConfig: {
PortBindings: portBindings
}
}, function(d) {
// Remove empty fields from the request to avoid overriding defaults
rmEmptyKeys(config.HostConfig);
rmEmptyKeys(config);
var ctor = Container;
var loc = $location;
var s = $scope;
Container.create(config, function(d) {
if (d.Id) {
ctor.start({
id: d.Id,
HostConfig: {
PortBindings: portBindings
}
}, function(cd) {
ctor.start({id: d.Id}, function(cd) {
$('#create-modal').modal('hide');
loc.path('/containers/' + d.Id + '/');
}, function(e) {
@ -99,29 +112,39 @@ function($scope, $routeParams, $location, Container, Messages, containernameFilt
};
$scope.addPortBinding = function() {
$scope.config.portBindings.push({ip: '', extPort: '', intPort: ''});
$scope.config.PortBindings.push({ip: '', extPort: '', intPort: ''});
};
$scope.removePortBinding = function(portBinding) {
var idx = $scope.config.portBindings.indexOf(portBinding);
$scope.config.portBindings.splice(idx, 1);
var idx = $scope.config.PortBindings.indexOf(portBinding);
$scope.config.PortBindings.splice(idx, 1);
};
// TODO: refactor out
$scope.addEnv = function() {
$scope.config.env.push({name: '', value: ''});
$scope.config.Env.push({name: '', value: ''});
};
$scope.removeEnv = function(envar) {
var idx = $scope.config.env.indexOf(envar);
$scope.config.env.splice(idx, 1);
$scope.config.Env.splice(idx, 1);
};
$scope.addVolume = function() {
$scope.config.volumesFrom.push({name: ''});
// Todo: refactor out
$scope.addVolumeFrom = function() {
$scope.config.HostConfig.volumesFrom.push({name: ''});
};
$scope.removeVolume = function(volume) {
var idx = $scope.config.volumesFrom.indexOf(volume);
$scope.config.volumesFrom.splice(idx, 1);
$scope.removeVolumeFrom = function(volume) {
var idx = $scope.config.HostConfig.volumesFrom.indexOf(volume);
$scope.config.HostConfig.volumesFrom.splice(idx, 1);
};
$scope.addEntry = function(array, entry) {
array.push(entry);
};
$scope.rmEntry = function(array, entry) {
var idx = array.indexOf(entry);
array.splice(idx, 1);
};
}]);

View file

@ -18,19 +18,28 @@ describe('startContainerController', function() {
$httpBackend = _$httpBackend_;
});
}));
function expectGetContainers() {
$httpBackend.expectGET('dockerapi/containers/json?all=1').respond([{
"Command": "./dockerui -e /docker.sock",
"Created": 1421817232,
"Id": "b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f",
"Image": "dockerui:latest",
"Names": ["/dockerui"],
"Ports": [{
"IP": "0.0.0.0",
"PrivatePort": 9000,
"PublicPort": 9000,
"Type": "tcp"
}],
"Status": "Up 2 minutes"
}]);
}
describe('Create and start a container with port bindings', function() {
it('should issue a correct create request to the Docker remote API', function() {
var controller = createController();
var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c';
var expectedBody = {
"name": "container-name",
"Memory": 0,
"MemorySwap": 0,
"CpuShares": 1024,
"Cmd": null,
"VolumesFrom": [],
"Env": [],
"ExposedPorts": {
"9000/tcp": {},
},
@ -44,32 +53,19 @@ describe('startContainerController', function() {
}
};
$httpBackend.expectGET('/dockerapi/containers/json?all=1').respond([{
"Command": "./dockerui -e /docker.sock",
"Created": 1421817232,
"Id": "b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f",
"Image": "dockerui:latest",
"Names": ["/dockerui"],
"Ports": [{
"IP": "0.0.0.0",
"PrivatePort": 9000,
"PublicPort": 9000,
"Type": "tcp"
}],
"Status": "Up 2 minutes"
}]);
expectGetContainers();
$httpBackend.expectPOST('/dockerapi/containers/create?name=container-name', expectedBody).respond({
$httpBackend.expectPOST('dockerapi/containers/create?name=container-name', expectedBody).respond({
"Id": id,
"Warnings": null
});
$httpBackend.expectPOST('/dockerapi/containers/' + id + '/start?').respond({
$httpBackend.expectPOST('dockerapi/containers/' + id + '/start?').respond({
"Id": id,
"Warnings": null
});
scope.config.name = 'container-name';
scope.config.portBindings = [{
scope.config.PortBindings = [{
ip: '10.20.10.15',
extPort: '9999',
intPort: '9000'
@ -86,44 +82,22 @@ describe('startContainerController', function() {
var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c';
var expectedBody = {
"name": "container-name",
"Memory": 0,
"MemorySwap": 0,
"CpuShares": 1024,
"Cmd": null,
"VolumesFrom": [],
"Env": ["SHELL=/bin/bash", "TERM=xterm-256color"],
"ExposedPorts": {},
"HostConfig": {
"PortBindings": {}
}
"Env": ["SHELL=/bin/bash", "TERM=xterm-256color"]
};
$httpBackend.expectGET('/dockerapi/containers/json?all=1').respond([{
"Command": "./dockerui -e /docker.sock",
"Created": 1421817232,
"Id": "b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f",
"Image": "dockerui:latest",
"Names": ["/dockerui"],
"Ports": [{
"IP": "0.0.0.0",
"PrivatePort": 9000,
"PublicPort": 9000,
"Type": "tcp"
}],
"Status": "Up 2 minutes"
}]);
expectGetContainers();
$httpBackend.expectPOST('/dockerapi/containers/create?name=container-name', expectedBody).respond({
$httpBackend.expectPOST('dockerapi/containers/create?name=container-name', expectedBody).respond({
"Id": id,
"Warnings": null
});
$httpBackend.expectPOST('/dockerapi/containers/' + id + '/start?').respond({
$httpBackend.expectPOST('dockerapi/containers/' + id + '/start?').respond({
"Id": id,
"Warnings": null
});
scope.config.name = 'container-name';
scope.config.env = [{
scope.config.Env = [{
name: 'SHELL',
value: '/bin/bash'
}, {
@ -141,45 +115,26 @@ describe('startContainerController', function() {
var controller = createController();
var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c';
var expectedBody = {
"name": "container-name",
"Memory": 0,
"MemorySwap": 0,
"CpuShares": 1024,
"Cmd": null,
"VolumesFrom": ["parent", "other:ro"],
"Env": [],
"ExposedPorts": {},
"HostConfig": {
"PortBindings": {}
}
HostConfig: {
"VolumesFrom": ["parent", "other:ro"]
},
"name": "container-name"
};
$httpBackend.expectGET('/dockerapi/containers/json?all=1').respond([{
"Command": "./dockerui -e /docker.sock",
"Created": 1421817232,
"Id": "b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f",
"Image": "dockerui:latest",
"Names": ["/dockerui"],
"Ports": [{
"IP": "0.0.0.0",
"PrivatePort": 9000,
"PublicPort": 9000,
"Type": "tcp"
}],
"Status": "Up 2 minutes"
}]);
expectGetContainers();
$httpBackend.expectPOST('/dockerapi/containers/create?name=container-name', expectedBody).respond({
$httpBackend.expectPOST('dockerapi/containers/create?name=container-name', expectedBody).respond({
"Id": id,
"Warnings": null
});
$httpBackend.expectPOST('/dockerapi/containers/' + id + '/start?').respond({
$httpBackend.expectPOST('dockerapi/containers/' + id + '/start?').respond({
"Id": id,
"Warnings": null
});
scope.config.name = 'container-name';
scope.config.volumesFrom = [{name: "parent"}, {name:"other:ro"}];
scope.config.HostConfig.VolumesFrom = [{name: "parent"}, {name:"other:ro"}];
scope.create();
$httpBackend.flush();

View file

@ -6,40 +6,106 @@
<h3>Create And Start Container From Image</h3>
</div>
<div class="modal-body">
<form role="form">
<form role="form">
<accordion close-others="true">
<accordion-group heading="Container options">
<fieldset>
<div class="form-group">
<label>Cmd:</label>
<input type="text" placeholder="{{ commandPlaceholder }}" ng-model="config.commands" class="form-control"/>
<small>Input commands as an array</small>
</div>
<div class="form-group">
<label>Name:</label>
<input type="text" ng-model="config.name" class="form-control"/>
</div>
<div class="form-group">
<label>Memory:</label>
<input type="number" ng-model="config.memory" class="form-control"/>
</div>
<div class="form-group">
<label>Memory Swap:</label>
<input type="number" ng-model="config.memorySwap" class="form-control"/>
</div>
<div class="form-group">
<label>CPU Shares:</label>
<input type="number" ng-model="config.cpuShares" class="form-control"/>
</div>
<div class="form-group">
<label>Mount Volumes From other containers:</label>
<div ng-repeat="volume in config.volumesFrom" class="form-inline">
<select ng-model="volume.name" ng-options="name for name in containerNames track by name"/>
<button class="btn btn-danger btn-xs form-control" ng-click="removeVolume($index)">Remove</button>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label>Cmd:</label>
<input type="text" placeholder='["/bin/echo", "Hello world"]' ng-model="config.Cmd" class="form-control"/>
<small>Input commands as a raw string or JSON array</small>
</div>
<div class="form-group">
<label>Entrypoint:</label>
<input type="text" ng-model="config.Entrypoint" class="form-control" placeholder="./entrypoint.sh"/>
</div>
<div class="form-group">
<label>Name:</label>
<input type="text" ng-model="config.name" class="form-control"/>
</div>
<div class="form-group">
<label>Hostname:</label>
<input type="text" ng-model="config.Hostname" class="form-control"/>
</div>
<div class="form-group">
<label>Domainname:</label>
<input type="text" ng-model="config.Domainname" class="form-control"/>
</div>
<div class="form-group">
<label>User:</label>
<input type="text" ng-model="config.User" class="form-control"/>
</div>
<div class="form-group">
<label>Memory:</label>
<input type="number" ng-model="config.Memory" class="form-control"/>
</div>
<div class="form-group">
<label>Volumes:</label>
<div ng-repeat="volume in config.Volumes">
<div class="form-group form-inline">
<input type="text" ng-model="volume.name" class="form-control" placeholder="/var/data"/>
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.Volumes, volume)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.Volumes, {name: ''})">Add Volume</button>
</div>
<button type="button" class="btn btn-success" ng-click="addVolume()">Add volume</button>
</div>
<div class="form-group">
<label>Environment Variables:</label>
<div ng-repeat="envar in config.env" class="form-inline">
<div class="col-xs-6">
<div class="form-group">
<label>Memory Swap:</label>
<input type="number" ng-model="config.MemorySwap" class="form-control"/>
</div>
<div class="form-group">
<label>CPU Shares:</label>
<input type="number" ng-model="config.CpuShares" class="form-control"/>
</div>
<div class="form-group">
<label>Cpuset:</label>
<input type="text" ng-model="config.Cpuset" class="form-control" placeholder="1,2"/>
<small>Input as comma-separated list of numbers</small>
</div>
<div class="form-group">
<label>WorkingDir:</label>
<input type="text" ng-model="config.WorkingDir" class="form-control" placeholder="/app"/>
</div>
<div class="form-group">
<label>MacAddress:</label>
<input type="text" ng-model="config.MacAddress" class="form-control" placeholder="12:34:56:78:9a:bc"/>
</div>
<div class="form-group">
<label for="networkDisabled">NetworkDisabled:</label>
<input id="networkDisabled" type="checkbox" ng-model="config.NetworkDisabled"/>
</div>
<div class="form-group">
<label for="tty">Tty:</label>
<input id="tty" type="checkbox" ng-model="config.Tty"/>
</div>
<div class="form-group">
<label for="openStdin">OpenStdin:</label>
<input id="openStdin" type="checkbox" ng-model="config.OpenStdin"/>
</div>
<div class="form-group">
<label for="stdinOnce">StdinOnce:</label>
<input id="stdinOnce" type="checkbox" ng-model="config.StdinOnce"/>
</div>
<div class="form-group">
<label>Security Options:</label>
<div ng-repeat="opt in config.SecurityOpts">
<div class="form-group form-inline">
<input type="text" ng-model="opt.name" class="form-control" placeholder="???"/>
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.SecurityOpts, opt)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.SecurityOpts, {name: ''})">Add Option</button>
</div>
</div>
</div>
<div class="form-group">
<label>Environment Variables:</label>
<div ng-repeat="envar in config.Env">
<div class="form-inline">
<div class="form-group">
<label class="sr-only">Variable Name:</label>
<input type="text" ng-model="envar.name" class="form-control" placeholder="NAME"/>
@ -52,34 +118,134 @@
<button class="btn btn-danger btn-xs form-control" ng-click="removeEnv(portBinding)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success" ng-click="addEnv()">Add ENV variable</button>
</div>
<div class="form-group">
<label>Port bindings:</label>
<div ng-repeat="portBinding in config.portBindings" class="form-inline">
<div class="form-group">
<label class="sr-only">Host IP:</label>
<input type="text" ng-model="portBinding.ip" class="form-control" placeholder="Host IP Address"/>
</div>
<div class="form-group">
<label class="sr-only">Host Port:</label>
<input type="text" ng-model="portBinding.extPort" class="form-control" placeholder="Host Port"/>
</div>
<div class="form-group">
<label class="sr-only">Container port:</label>
<input type="text" ng-model="portBinding.intPort" class="form-control" placeholder="Container Port"/>
</div>
<div class="form-group">
<button class="btn btn-danger btn-xs form-control" ng-click="removePortBinding(portBinding)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success" ng-click="addPortBinding()">Add Port Binding</button>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEnv()">Add ENV variable</button>
</div>
</fieldset>
</accordion-group>
<accordion-group heading="HostConfig options">
<fieldset>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label>Binds:</label>
<div ng-repeat="bind in config.HostConfig.Binds">
<div class="form-group form-inline">
<input type="text" ng-model="bind.name" class="form-control" placeholder="???"/>
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.HostConfig.Binds, bind)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.HostConfig.Binds, {name: ''})">Add Bind</button>
</div>
<div class="form-group">
<label>Links:</label>
<div ng-repeat="link in config.HostConfig.Links">
<div class="form-group form-inline">
<input type="text" ng-model="link.name" class="form-control" placeholder="web:db">
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.HostConfig.Links, link)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.HostConfig.Links, {name: ''})">Add Link</button>
</div>
<div class="form-group">
<label>DNS:</label>
<div ng-repeat="entry in config.HostConfig.Dns">
<div class="form-group form-inline">
<input type="text" ng-model="entry.name" class="form-control" placeholder="8.8.8.8"/>
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.HostConfig.Dns, entry)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.HostConfig.Dns, {name: ''})">Add</button>
</div>
<div class="form-group">
<label>DnsSearch:</label>
<div ng-repeat="entry in config.HostConfig.DnsSearch">
<div class="form-group form-inline">
<input type="text" ng-model="entry.name" class="form-control" placeholder="???"/>
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.HostConfig.DnsSearch, entry)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.HostConfig.DnsSearch, {name: ''})">Add</button>
</div>
<div class="form-group">
<label>CapAdd:</label>
<div ng-repeat="entry in config.HostConfig.CapAdd">
<div class="form-group form-inline">
<input type="text" ng-model="entry.name" class="form-control" placeholder="???"/>
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.HostConfig.CapAdd, entry)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.HostConfig.CapAdd, {name: ''})">Add</button>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label>CapDrop:</label>
<div ng-repeat="entry in config.HostConfig.CapDrop">
<div class="form-group form-inline">
<input type="text" ng-model="entry.name" class="form-control" placeholder="???"/>
<button type="button" class="btn btn-danger btn-sm" ng-click="rmEntry(config.HostConfig.CapDrop, entry)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addEntry(config.HostConfig.CapDrop, {name: ''})">Add</button>
</div>
<div class="form-group">
<label>NetworkMode:</label>
<input type="text" ng-model="config.HostConfig.NetworkMode" class="form-control" placeholder="bridge"/>
</div>
<div class="form-group">
<label for="publishAllPorts">PublishAllPorts:</label>
<input id="publishAllPorts" type="checkbox" ng-model="config.HostConfig.PublishAllPorts"/>
</div>
<div class="form-group">
<label for="privileged">Privileged:</label>
<input id="privileged" type="checkbox" ng-model="config.HostConfig.Privileged"/>
</div>
<div class="form-group">
<label>Mount Volumes From other containers:</label>
<div ng-repeat="volume in config.HostConfig.VolumesFrom">
<div class="form-inline">
<select ng-model="volume.name" ng-options="name for name in containerNames track by name" class="form-control"/>
<button class="btn btn-danger btn-xs form-control" ng-click="removeVolumeFrom($index)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addVolumeFrom()">Add volume</button>
</div>
<!--
<div class="form-group">
RestartPolicy unimplemented...
</div>
<div class="form-group">
Devices unimplemented...
</div>
<div class="form-group">
LxcConf unimplemented...
</div>
-->
</div>
</div>
<div class="form-group">
<label>Port bindings:</label>
<div ng-repeat="portBinding in config.PortBindings">
<div class="form-group form-inline">
<label class="sr-only">Host IP:</label>
<input type="text" ng-model="portBinding.ip" class="form-control" placeholder="Host IP Address"/>
<label class="sr-only">Host Port:</label>
<input type="text" ng-model="portBinding.extPort" class="form-control" placeholder="Host Port"/>
<label class="sr-only">Container port:</label>
<input type="text" ng-model="portBinding.intPort" class="form-control" placeholder="Container Port"/>
<button class="btn btn-danger btn-xs form-control" ng-click="removePortBinding(portBinding)">Remove</button>
</div>
</div>
<button type="button" class="btn btn-success btn-sm" ng-click="addPortBinding()">Add Port Binding</button>
</div>
</fieldset>
</accordion-group>
</accordion>
</form>
</div>
<div class="modal-footer">
<a href="" class="btn btn-primary" ng-click="create()">Create</a>
<a href="" class="btn btn-primary btn-lg" ng-click="create()">Create</a>
</div>
</div>
</div>