diff --git a/app-backend/dist/js/dashboard.min.js b/app-backend/dist/js/dashboard.min.js
index a13e967..900ae4a 100644
--- a/app-backend/dist/js/dashboard.min.js
+++ b/app-backend/dist/js/dashboard.min.js
@@ -641,124 +641,6 @@ angular.module('RDash')
}
});
-/**
- * File Upload Read Directive
- */
-
-angular
- .module('RDash')
- .directive("fileread", [function () {
- return {
- scope: {
- fileread: "="
- },
- link: function (scope, element, attributes) {
- element.bind("change", function (changeEvent) {
- scope.$apply(function () {
- scope.fileread = changeEvent.target.files[0];
- // or all selected files:
- // scope.fileread = changeEvent.target.files;
- });
- });
- }
- }
- }]);
-/**
- * Loading Directive
- * @see http://tobiasahlin.com/spinkit/
- */
-
-angular
- .module('RDash')
- .directive('rdLoading', rdLoading);
-
-function rdLoading() {
- var directive = {
- restrict: 'AE',
- template: '
'
- };
- return directive;
-};
-/**
- * Widget Body Directive
- */
-
-angular
- .module('RDash')
- .directive('rdWidgetBody', rdWidgetBody);
-
-function rdWidgetBody() {
- var directive = {
- requires: '^rdWidget',
- scope: {
- loading: '=?',
- classes: '@?'
- },
- transclude: true,
- template: '',
- restrict: 'E'
- };
- return directive;
-};
-
-/**
- * Widget Footer Directive
- */
-
-angular
- .module('RDash')
- .directive('rdWidgetFooter', rdWidgetFooter);
-
-function rdWidgetFooter() {
- var directive = {
- requires: '^rdWidget',
- transclude: true,
- template: '',
- restrict: 'E'
- };
- return directive;
-};
-/**
- * Widget Header Directive
- */
-
-angular
- .module('RDash')
- .directive('rdWidgetHeader', rdWidgetTitle);
-
-function rdWidgetTitle() {
- var directive = {
- requires: '^rdWidget',
- scope: {
- title: '@',
- icon: '@'
- },
- transclude: true,
- template: '',
- restrict: 'E'
- };
- return directive;
-};
-/**
- * Widget Directive
- */
-
-angular
- .module('RDash')
- .directive('rdWidget', rdWidget);
-
-function rdWidget() {
- var directive = {
- transclude: true,
- template: '',
- restrict: 'EA'
- };
- return directive;
-
- function link(scope, element, attrs) {
- /* */
- }
-};
/**
* Alerts Controller
*/
@@ -1616,4 +1498,122 @@ function SettingsCtrl($scope, $cookieStore, $rootScope, pageDefinitions,
}());
-}
\ No newline at end of file
+}
+/**
+ * File Upload Read Directive
+ */
+
+angular
+ .module('RDash')
+ .directive("fileread", [function () {
+ return {
+ scope: {
+ fileread: "="
+ },
+ link: function (scope, element, attributes) {
+ element.bind("change", function (changeEvent) {
+ scope.$apply(function () {
+ scope.fileread = changeEvent.target.files[0];
+ // or all selected files:
+ // scope.fileread = changeEvent.target.files;
+ });
+ });
+ }
+ }
+ }]);
+/**
+ * Loading Directive
+ * @see http://tobiasahlin.com/spinkit/
+ */
+
+angular
+ .module('RDash')
+ .directive('rdLoading', rdLoading);
+
+function rdLoading() {
+ var directive = {
+ restrict: 'AE',
+ template: ''
+ };
+ return directive;
+};
+/**
+ * Widget Body Directive
+ */
+
+angular
+ .module('RDash')
+ .directive('rdWidgetBody', rdWidgetBody);
+
+function rdWidgetBody() {
+ var directive = {
+ requires: '^rdWidget',
+ scope: {
+ loading: '=?',
+ classes: '@?'
+ },
+ transclude: true,
+ template: '',
+ restrict: 'E'
+ };
+ return directive;
+};
+
+/**
+ * Widget Footer Directive
+ */
+
+angular
+ .module('RDash')
+ .directive('rdWidgetFooter', rdWidgetFooter);
+
+function rdWidgetFooter() {
+ var directive = {
+ requires: '^rdWidget',
+ transclude: true,
+ template: '',
+ restrict: 'E'
+ };
+ return directive;
+};
+/**
+ * Widget Header Directive
+ */
+
+angular
+ .module('RDash')
+ .directive('rdWidgetHeader', rdWidgetTitle);
+
+function rdWidgetTitle() {
+ var directive = {
+ requires: '^rdWidget',
+ scope: {
+ title: '@',
+ icon: '@'
+ },
+ transclude: true,
+ template: '',
+ restrict: 'E'
+ };
+ return directive;
+};
+/**
+ * Widget Directive
+ */
+
+angular
+ .module('RDash')
+ .directive('rdWidget', rdWidget);
+
+function rdWidget() {
+ var directive = {
+ transclude: true,
+ template: '',
+ restrict: 'EA'
+ };
+ return directive;
+
+ function link(scope, element, attrs) {
+ /* */
+ }
+};
\ No newline at end of file
diff --git a/app-backend/dist/oneclick-apps/adminer.js b/app-backend/dist/oneclick-apps/adminer.js
new file mode 100644
index 0000000..4b5881c
--- /dev/null
+++ b/app-backend/dist/oneclick-apps/adminer.js
@@ -0,0 +1,151 @@
+
+(function () {
+
+ var SUCCESS = 'success';
+ var ERROR = 'danger';
+ var INFO = 'info';
+
+ oneClickAppsRepository["adminer"] = function (apiManager) {
+
+ var getErrorMessageIfExists = apiManager.getErrorMessageIfExists;
+
+ var ADMINER_DESIGN = 'ADMINER_DESIGN';
+ var ADMINER_PLUGINS = 'ADMINER_PLUGINS';
+
+ var CONTAINER_NAME = 'CONTAINER_NAME';
+
+ var step1next = {};
+
+ step1next.data = [];
+ step1next.data.push({
+ label: 'Container Name',
+ id: CONTAINER_NAME,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'OPTINAL: Adminer design',
+ id: ADMINER_DESIGN,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'OPTINAL: Adminer plugins (space separated)',
+ id: ADMINER_PLUGINS,
+ type: 'text'
+ });
+
+ step1next.process = function (data, step1Callback) {
+
+ // create container and set persistent
+ // set env vars and volumes
+ // deploy image via dockerfile
+
+ function endWithSuccess() {
+
+ step1Callback({
+ message: {
+ text: 'Adminer is deployed and available as http://srv-captain--' + data[CONTAINER_NAME]
+ + ' to other apps.',
+ type: SUCCESS
+ },
+ next: null // this can be similar to step1next, in that case the flow continues...
+ });
+ }
+
+ function endWithError(errorMessage) {
+ step1Callback({
+ message: {
+ text: errorMessage,
+ type: ERROR
+ },
+ next: step1next
+ });
+ }
+
+ // process the inputs:
+
+ var errorMessage = null;
+
+
+ if (!data[CONTAINER_NAME]) {
+ errorMessage = 'Container name is required!';
+ }
+
+ if (errorMessage) {
+ endWithError(errorMessage);
+ return;
+ }
+
+ var appName = data[CONTAINER_NAME];
+ var envVars = [{
+ key: ADMINER_PLUGINS,
+ value: data[ADMINER_PLUGINS]
+ }, {
+ key: ADMINER_DESIGN,
+ value: data[ADMINER_DESIGN]
+ }];
+ var volumes = [];
+
+ function createContainer() {
+
+ var hasPersistentData = false;
+
+ apiManager.registerNewApp(appName, hasPersistentData, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ setupAppDefinition();
+ });
+ }
+
+ function setupAppDefinition() {
+ apiManager.updateConfigAndSave(appName, 1, envVars, false, volumes, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ deployDockerfile();
+ });
+ }
+
+ function deployDockerfile() {
+
+ var captainDefinitionContent = {
+ schemaVersion: 1,
+ dockerfileLines: [
+ "FROM adminer:4.3",
+ 'USER root',
+ 'CMD [ "php", "-S", "[::]:80", "-t", "/var/www/html" ]',
+ 'EXPOSE 80'
+ ]
+ }
+
+ apiManager.uploadCaptainDefinitionContent(appName,
+ JSON.stringify(captainDefinitionContent), function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ endWithSuccess();
+ });
+ }
+
+ createContainer();
+
+ }
+
+ var step1 = {};
+ step1.message = {
+ type: INFO,
+ text: 'Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consist of a single file ready to deploy to the target server. Adminer is available for MySQL, PostgreSQL, SQLite, MS SQL, Oracle, Firebird, SimpleDB, Elasticsearch and MongoDB. ' +
+ 'Enter your Adminer Configuration parameters and click on next. It will take about a minute for the process to finish.'
+ }
+ step1.next = step1next;
+ return step1;
+
+ }
+
+})();
\ No newline at end of file
diff --git a/app-backend/dist/oneclick-apps/postgres.js b/app-backend/dist/oneclick-apps/postgres.js
new file mode 100644
index 0000000..38802ba
--- /dev/null
+++ b/app-backend/dist/oneclick-apps/postgres.js
@@ -0,0 +1,179 @@
+
+(function () {
+
+ var SUCCESS = 'success';
+ var ERROR = 'danger';
+ var INFO = 'info';
+
+ oneClickAppsRepository["postgres"] = function (apiManager) {
+
+ var getErrorMessageIfExists = apiManager.getErrorMessageIfExists;
+
+ var POSTGRES_USER = 'POSTGRES_USER';
+ var POSTGRES_PASSWORD = 'POSTGRES_PASSWORD';
+ var POSTGRES_DB = 'POSTGRES_DB';
+ var POSTGRES_INITDB_ARGS = 'POSTGRES_INITDB_ARGS';
+
+ var CONTAINER_NAME = 'CONTAINER_NAME';
+
+ var step1next = {};
+
+ step1next.data = [];
+ step1next.data.push({
+ label: 'Container Name',
+ id: CONTAINER_NAME,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'Postgres Root Username',
+ id: POSTGRES_USER,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'Postgres Root Password',
+ id: POSTGRES_PASSWORD,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'Postgres Default Database',
+ id: POSTGRES_DB,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'OPTIONAL: Arguments for "postgres initdb", e.g. --data-checksums',
+ id: POSTGRES_INITDB_ARGS,
+ type: 'text'
+ });
+
+ step1next.process = function (data, step1Callback) {
+
+ // create container and set persistent
+ // set env vars and volumes
+ // deploy image via dockerfile
+
+ function endWithSuccess() {
+
+ var nodejsCode = 'const client = new Client({ user: "' + data[POSTGRES_USER]
+ + '", host: "srv-captain--' + data[CONTAINER_NAME]
+ + '", database: "' + data[POSTGRES_DB]
+ + '", password: "********", port: 5432})';
+
+ step1Callback({
+ message: {
+ text: 'Postgres is deployed and available as srv-captain--' + data[CONTAINER_NAME]
+ + ':5432 to other apps. For example with NodeJS: ' + nodejsCode,
+ type: SUCCESS
+ },
+ next: null // this can be similar to step1next, in that case the flow continues...
+ });
+ }
+
+ function endWithError(errorMessage) {
+ step1Callback({
+ message: {
+ text: errorMessage,
+ type: ERROR
+ },
+ next: step1next
+ });
+ }
+
+ // process the inputs:
+
+ var errorMessage = null;
+
+
+ if (!data[CONTAINER_NAME]) {
+ errorMessage = 'Container name is required!';
+ } else if (!data[POSTGRES_USER]) {
+ errorMessage = 'Root username is required!';
+ } else if (!data[POSTGRES_PASSWORD]) {
+ errorMessage = 'Root password is required!';
+ } else if (!data[POSTGRES_DB]) {
+ errorMessage = 'Default DB is required!';
+ }
+
+ if (errorMessage) {
+ endWithError(errorMessage);
+ return;
+ }
+
+ var appName = data[CONTAINER_NAME];
+ var envVars = [{
+ key: POSTGRES_USER,
+ value: data[POSTGRES_USER]
+ }, {
+ key: POSTGRES_PASSWORD,
+ value: data[POSTGRES_PASSWORD]
+ }, {
+ key: POSTGRES_DB,
+ value: data[POSTGRES_DB]
+ }, {
+ key: POSTGRES_INITDB_ARGS,
+ value: data[POSTGRES_INITDB_ARGS]
+ }];
+ var volumes = [{
+ volumeName: appName + '-postgres',
+ containerPath: '/var/lib/postgresql/data'
+ }];
+
+ function createContainer() {
+
+ var hasPersistentData = true;
+
+ apiManager.registerNewApp(appName, hasPersistentData, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ setupAppDefinition();
+ });
+ }
+
+ function setupAppDefinition() {
+ apiManager.updateConfigAndSave(appName, 1, envVars, true, volumes, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ deployDockerfile();
+ });
+ }
+
+ function deployDockerfile() {
+
+ var captainDefinitionContent = {
+ schemaVersion: 1,
+ dockerfileLines: [
+ "FROM postgres:latest"
+ ]
+ }
+
+ apiManager.uploadCaptainDefinitionContent(appName,
+ JSON.stringify(captainDefinitionContent), function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ endWithSuccess();
+ });
+ }
+
+ createContainer();
+
+ }
+
+ var step1 = {};
+ step1.message = {
+ type: INFO,
+ text: 'Enter your Postgres Configuration parameters and click on next. It will take about a minute for the process to finish.'
+ }
+ step1.next = step1next;
+ return step1;
+
+ }
+
+})();
\ No newline at end of file
diff --git a/app-frontend/src/oneclick-apps/adminer.js b/app-frontend/src/oneclick-apps/adminer.js
new file mode 100644
index 0000000..4b5881c
--- /dev/null
+++ b/app-frontend/src/oneclick-apps/adminer.js
@@ -0,0 +1,151 @@
+
+(function () {
+
+ var SUCCESS = 'success';
+ var ERROR = 'danger';
+ var INFO = 'info';
+
+ oneClickAppsRepository["adminer"] = function (apiManager) {
+
+ var getErrorMessageIfExists = apiManager.getErrorMessageIfExists;
+
+ var ADMINER_DESIGN = 'ADMINER_DESIGN';
+ var ADMINER_PLUGINS = 'ADMINER_PLUGINS';
+
+ var CONTAINER_NAME = 'CONTAINER_NAME';
+
+ var step1next = {};
+
+ step1next.data = [];
+ step1next.data.push({
+ label: 'Container Name',
+ id: CONTAINER_NAME,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'OPTINAL: Adminer design',
+ id: ADMINER_DESIGN,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'OPTINAL: Adminer plugins (space separated)',
+ id: ADMINER_PLUGINS,
+ type: 'text'
+ });
+
+ step1next.process = function (data, step1Callback) {
+
+ // create container and set persistent
+ // set env vars and volumes
+ // deploy image via dockerfile
+
+ function endWithSuccess() {
+
+ step1Callback({
+ message: {
+ text: 'Adminer is deployed and available as http://srv-captain--' + data[CONTAINER_NAME]
+ + ' to other apps.',
+ type: SUCCESS
+ },
+ next: null // this can be similar to step1next, in that case the flow continues...
+ });
+ }
+
+ function endWithError(errorMessage) {
+ step1Callback({
+ message: {
+ text: errorMessage,
+ type: ERROR
+ },
+ next: step1next
+ });
+ }
+
+ // process the inputs:
+
+ var errorMessage = null;
+
+
+ if (!data[CONTAINER_NAME]) {
+ errorMessage = 'Container name is required!';
+ }
+
+ if (errorMessage) {
+ endWithError(errorMessage);
+ return;
+ }
+
+ var appName = data[CONTAINER_NAME];
+ var envVars = [{
+ key: ADMINER_PLUGINS,
+ value: data[ADMINER_PLUGINS]
+ }, {
+ key: ADMINER_DESIGN,
+ value: data[ADMINER_DESIGN]
+ }];
+ var volumes = [];
+
+ function createContainer() {
+
+ var hasPersistentData = false;
+
+ apiManager.registerNewApp(appName, hasPersistentData, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ setupAppDefinition();
+ });
+ }
+
+ function setupAppDefinition() {
+ apiManager.updateConfigAndSave(appName, 1, envVars, false, volumes, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ deployDockerfile();
+ });
+ }
+
+ function deployDockerfile() {
+
+ var captainDefinitionContent = {
+ schemaVersion: 1,
+ dockerfileLines: [
+ "FROM adminer:4.3",
+ 'USER root',
+ 'CMD [ "php", "-S", "[::]:80", "-t", "/var/www/html" ]',
+ 'EXPOSE 80'
+ ]
+ }
+
+ apiManager.uploadCaptainDefinitionContent(appName,
+ JSON.stringify(captainDefinitionContent), function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ endWithSuccess();
+ });
+ }
+
+ createContainer();
+
+ }
+
+ var step1 = {};
+ step1.message = {
+ type: INFO,
+ text: 'Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consist of a single file ready to deploy to the target server. Adminer is available for MySQL, PostgreSQL, SQLite, MS SQL, Oracle, Firebird, SimpleDB, Elasticsearch and MongoDB. ' +
+ 'Enter your Adminer Configuration parameters and click on next. It will take about a minute for the process to finish.'
+ }
+ step1.next = step1next;
+ return step1;
+
+ }
+
+})();
\ No newline at end of file
diff --git a/app-frontend/src/oneclick-apps/postgres.js b/app-frontend/src/oneclick-apps/postgres.js
new file mode 100644
index 0000000..38802ba
--- /dev/null
+++ b/app-frontend/src/oneclick-apps/postgres.js
@@ -0,0 +1,179 @@
+
+(function () {
+
+ var SUCCESS = 'success';
+ var ERROR = 'danger';
+ var INFO = 'info';
+
+ oneClickAppsRepository["postgres"] = function (apiManager) {
+
+ var getErrorMessageIfExists = apiManager.getErrorMessageIfExists;
+
+ var POSTGRES_USER = 'POSTGRES_USER';
+ var POSTGRES_PASSWORD = 'POSTGRES_PASSWORD';
+ var POSTGRES_DB = 'POSTGRES_DB';
+ var POSTGRES_INITDB_ARGS = 'POSTGRES_INITDB_ARGS';
+
+ var CONTAINER_NAME = 'CONTAINER_NAME';
+
+ var step1next = {};
+
+ step1next.data = [];
+ step1next.data.push({
+ label: 'Container Name',
+ id: CONTAINER_NAME,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'Postgres Root Username',
+ id: POSTGRES_USER,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'Postgres Root Password',
+ id: POSTGRES_PASSWORD,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'Postgres Default Database',
+ id: POSTGRES_DB,
+ type: 'text'
+ });
+ step1next.data.push({
+ label: 'OPTIONAL: Arguments for "postgres initdb", e.g. --data-checksums',
+ id: POSTGRES_INITDB_ARGS,
+ type: 'text'
+ });
+
+ step1next.process = function (data, step1Callback) {
+
+ // create container and set persistent
+ // set env vars and volumes
+ // deploy image via dockerfile
+
+ function endWithSuccess() {
+
+ var nodejsCode = 'const client = new Client({ user: "' + data[POSTGRES_USER]
+ + '", host: "srv-captain--' + data[CONTAINER_NAME]
+ + '", database: "' + data[POSTGRES_DB]
+ + '", password: "********", port: 5432})';
+
+ step1Callback({
+ message: {
+ text: 'Postgres is deployed and available as srv-captain--' + data[CONTAINER_NAME]
+ + ':5432 to other apps. For example with NodeJS: ' + nodejsCode,
+ type: SUCCESS
+ },
+ next: null // this can be similar to step1next, in that case the flow continues...
+ });
+ }
+
+ function endWithError(errorMessage) {
+ step1Callback({
+ message: {
+ text: errorMessage,
+ type: ERROR
+ },
+ next: step1next
+ });
+ }
+
+ // process the inputs:
+
+ var errorMessage = null;
+
+
+ if (!data[CONTAINER_NAME]) {
+ errorMessage = 'Container name is required!';
+ } else if (!data[POSTGRES_USER]) {
+ errorMessage = 'Root username is required!';
+ } else if (!data[POSTGRES_PASSWORD]) {
+ errorMessage = 'Root password is required!';
+ } else if (!data[POSTGRES_DB]) {
+ errorMessage = 'Default DB is required!';
+ }
+
+ if (errorMessage) {
+ endWithError(errorMessage);
+ return;
+ }
+
+ var appName = data[CONTAINER_NAME];
+ var envVars = [{
+ key: POSTGRES_USER,
+ value: data[POSTGRES_USER]
+ }, {
+ key: POSTGRES_PASSWORD,
+ value: data[POSTGRES_PASSWORD]
+ }, {
+ key: POSTGRES_DB,
+ value: data[POSTGRES_DB]
+ }, {
+ key: POSTGRES_INITDB_ARGS,
+ value: data[POSTGRES_INITDB_ARGS]
+ }];
+ var volumes = [{
+ volumeName: appName + '-postgres',
+ containerPath: '/var/lib/postgresql/data'
+ }];
+
+ function createContainer() {
+
+ var hasPersistentData = true;
+
+ apiManager.registerNewApp(appName, hasPersistentData, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ setupAppDefinition();
+ });
+ }
+
+ function setupAppDefinition() {
+ apiManager.updateConfigAndSave(appName, 1, envVars, true, volumes, function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ deployDockerfile();
+ });
+ }
+
+ function deployDockerfile() {
+
+ var captainDefinitionContent = {
+ schemaVersion: 1,
+ dockerfileLines: [
+ "FROM postgres:latest"
+ ]
+ }
+
+ apiManager.uploadCaptainDefinitionContent(appName,
+ JSON.stringify(captainDefinitionContent), function (data) {
+ if (getErrorMessageIfExists(data)) {
+ endWithError(getErrorMessageIfExists(data));
+ return;
+ }
+
+ endWithSuccess();
+ });
+ }
+
+ createContainer();
+
+ }
+
+ var step1 = {};
+ step1.message = {
+ type: INFO,
+ text: 'Enter your Postgres Configuration parameters and click on next. It will take about a minute for the process to finish.'
+ }
+ step1.next = step1next;
+ return step1;
+
+ }
+
+})();
\ No newline at end of file