diff --git a/websiteFunctions/dockerviews.py b/websiteFunctions/dockerviews.py
index 096ae6e05..c1d3182de 100644
--- a/websiteFunctions/dockerviews.py
+++ b/websiteFunctions/dockerviews.py
@@ -8,8 +8,6 @@ from django.shortcuts import redirect
from loginSystem.views import loadLoginPage
from django.views.decorators.csrf import csrf_exempt
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
-import requests
-import re
def require_login(view_func):
def wrapper(request, *args, **kwargs):
@@ -32,34 +30,6 @@ class DockerManager:
except Exception as e:
logging.writeToFile(f"Error getting container {container_id}: {str(e)}")
return None
-
- def get_n8n_version(self, container):
- try:
- # Execute npm list command in the container to get n8n version
- exec_result = container.exec_run(
- cmd="npm list n8n --json",
- workdir="/usr/local/lib/node_modules/n8n"
- )
- if exec_result.exit_code == 0:
- npm_output = json.loads(exec_result.output.decode())
- # Extract version from npm output
- if 'dependencies' in npm_output and 'n8n' in npm_output['dependencies']:
- return npm_output['dependencies']['n8n']['version']
- return None
- except Exception as e:
- logging.writeToFile(f"Error getting n8n version: {str(e)}")
- return None
-
- def get_latest_n8n_version(self):
- try:
- # Fetch latest version from npm registry
- response = requests.get('https://registry.npmjs.org/n8n/latest')
- if response.status_code == 200:
- return response.json()['version']
- return None
- except Exception as e:
- logging.writeToFile(f"Error fetching latest n8n version: {str(e)}")
- return None
@csrf_exempt
@require_login
@@ -201,7 +171,7 @@ def restartContainer(request):
@csrf_exempt
@require_login
-def check_n8n_version(request):
+def executeCommand(request):
try:
if request.method == 'POST':
userID = request.session['userID']
@@ -210,6 +180,7 @@ def check_n8n_version(request):
data = json.loads(request.body)
container_id = data.get('container_id')
+ command = data.get('command')
site_name = data.get('name')
# Verify Docker site ownership
@@ -235,107 +206,14 @@ def check_n8n_version(request):
'error_message': 'Container not found'
}))
- # Get current version
- current_version = docker_manager.get_n8n_version(container)
- if not current_version:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': 'Could not determine current n8n version'
- }))
-
- # Get latest version
- latest_version = docker_manager.get_latest_n8n_version()
- if not latest_version:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': 'Could not fetch latest n8n version'
- }))
-
- # Compare versions
- update_available = current_version != latest_version
-
+ # Execute the command
+ result = container.exec_run(command)
+
return HttpResponse(json.dumps({
'status': 1,
- 'current_version': current_version,
- 'latest_version': latest_version,
- 'update_available': update_available
+ 'output': result.output.decode('utf-8')
}))
- return HttpResponse('Not allowed')
- except Exception as e:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': str(e)
- }))
-
-@csrf_exempt
-@require_login
-def update_n8n(request):
- try:
- if request.method == 'POST':
- userID = request.session['userID']
- currentACL = ACLManager.loadedACL(userID)
- admin = Administrator.objects.get(pk=userID)
-
- data = json.loads(request.body)
- container_id = data.get('container_id')
- site_name = data.get('name')
-
- # Verify Docker site ownership
- try:
- docker_site = DockerSites.objects.get(SiteName=site_name)
- if currentACL['admin'] != 1 and docker_site.admin != admin and docker_site.admin.owner != admin.pk:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': 'Not authorized to access this container'
- }))
- except DockerSites.DoesNotExist:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': 'Docker site not found'
- }))
-
- docker_manager = DockerManager()
- container = docker_manager.get_container(container_id)
-
- if not container:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': 'Container not found'
- }))
-
- # Update n8n
- try:
- # Run npm update in the container
- exec_result = container.exec_run(
- cmd="npm install -g n8n@latest",
- workdir="/usr/local/lib/node_modules/n8n"
- )
-
- if exec_result.exit_code != 0:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': f'Update failed: {exec_result.output.decode()}'
- }))
-
- # Get new version after update
- new_version = docker_manager.get_n8n_version(container)
-
- # Restart the container to apply changes
- container.restart()
-
- return HttpResponse(json.dumps({
- 'status': 1,
- 'message': 'n8n updated successfully',
- 'new_version': new_version
- }))
-
- except Exception as e:
- return HttpResponse(json.dumps({
- 'status': 0,
- 'error_message': f'Update failed: {str(e)}'
- }))
-
return HttpResponse('Not allowed')
except Exception as e:
return HttpResponse(json.dumps({
diff --git a/websiteFunctions/static/websiteFunctions/DockerContainers.js b/websiteFunctions/static/websiteFunctions/DockerContainers.js
index 4614497eb..d17da0435 100644
--- a/websiteFunctions/static/websiteFunctions/DockerContainers.js
+++ b/websiteFunctions/static/websiteFunctions/DockerContainers.js
@@ -347,4 +347,99 @@ app.controller('ListDockersitecontainer', function ($scope, $http) {
// Add location service to the controller for the n8n URL
$scope.location = window.location;
+
+ // Initialize n8n version info for containers
+ $scope.initializeN8nVersion = function(container) {
+ if (!container || !container.id) return;
+
+ $http({
+ method: 'POST',
+ url: '/docker/fetchN8nVersions',
+ data: {
+ container_id: container.id
+ }
+ }).then(function(response) {
+ if (response.data.status === 1) {
+ container.n8nVersion = {
+ current: response.data.current_version,
+ latest: response.data.latest_version,
+ updateAvailable: response.data.update_available
+ };
+ } else {
+ console.error('Error fetching n8n versions:', response.data.error_message);
+ }
+ }, function(error) {
+ console.error('Error fetching n8n versions:', error);
+ });
+ };
+
+ // Update n8n function
+ $scope.updateN8n = function(container) {
+ if (!container || container.updatingN8n) return;
+
+ container.updatingN8n = true;
+
+ // First stop the container
+ $http({
+ method: 'POST',
+ url: '/docker/stopContainer',
+ data: {
+ container_id: container.id,
+ name: container.name
+ }
+ }).then(function(response) {
+ if (response.data.status === 1) {
+ // Execute update command
+ return $http({
+ method: 'POST',
+ url: '/docker/executeCommand',
+ data: {
+ container_id: container.id,
+ command: 'npm install -g n8n@latest'
+ }
+ });
+ } else {
+ throw new Error('Failed to stop container');
+ }
+ }).then(function(response) {
+ if (response.data.status === 1) {
+ // Start the container back
+ return $http({
+ method: 'POST',
+ url: '/docker/startContainer',
+ data: {
+ container_id: container.id,
+ name: container.name
+ }
+ });
+ } else {
+ throw new Error('Failed to update n8n');
+ }
+ }).then(function(response) {
+ if (response.data.status === 1) {
+ // Refresh version info
+ $scope.initializeN8nVersion(container);
+ } else {
+ throw new Error('Failed to start container');
+ }
+ }).catch(function(error) {
+ console.error('Error updating n8n:', error);
+ }).finally(function() {
+ container.updatingN8n = false;
+ });
+ };
+
+ // Hook into existing container loading
+ var originalLunchcontainer = $scope.Lunchcontainer;
+ if (originalLunchcontainer) {
+ $scope.Lunchcontainer = function(containerId) {
+ var result = originalLunchcontainer(containerId);
+ // Initialize version info after container is loaded
+ if ($scope.web && $scope.web.environment &&
+ $scope.web.environment.some(function(env) { return env.includes('n8n'); })) {
+ $scope.initializeN8nVersion($scope.web);
+ }
+ return result;
+ };
+ }
});
\ No newline at end of file
diff --git a/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html b/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html
index d7ac33948..4804b25c8 100644
--- a/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html
+++ b/websiteFunctions/templates/websiteFunctions/DockerSiteHome.html
@@ -916,7 +916,7 @@
});
// Add n8n version checking and update functionality
- angular.module('WebsitesApp').run(['$rootScope', '$http', function($rootScope, $http) {
+ angular.module('WebsitesApp').run(['$rootScope', function($rootScope) {
// Add custom icon rendering for container actions
$rootScope.renderIcon = function(iconName) {
return '';
@@ -951,49 +951,24 @@
// Initialize n8n version info for containers
$rootScope.initializeN8nVersion = function(container) {
- // Call backend to check version
- $http.post('/websiteFunctions/docker/check-n8n-version', {
- container_id: container.id,
- name: container.name
- }).then(function(response) {
- if (response.data.status === 1) {
- container.n8nVersion = {
- current: response.data.current_version,
- latest: response.data.latest_version,
- updateAvailable: response.data.update_available
- };
- } else {
- console.error('Error checking n8n version:', response.data.error_message);
- }
- }).catch(function(error) {
- console.error('Error checking n8n version:', error);
- });
+ // This would normally come from the backend
+ container.n8nVersion = {
+ current: '1.0.0',
+ latest: '1.1.0',
+ updateAvailable: true
+ };
};
// Add n8n update function
$rootScope.updateN8n = function(container) {
container.updatingN8n = true;
- $http.post('/websiteFunctions/docker/update-n8n', {
- container_id: container.id,
- name: container.name
- }).then(function(response) {
- if (response.data.status === 1) {
- container.n8nVersion.current = response.data.new_version;
- container.n8nVersion.updateAvailable = false;
- // Show success notification
- $rootScope.notify({message: response.data.message, type: 'success'});
- } else {
- // Show error notification
- $rootScope.notify({message: response.data.error_message, type: 'error'});
- }
- }).catch(function(error) {
- console.error('Error updating n8n:', error);
- // Show error notification
- $rootScope.notify({message: 'Failed to update n8n', type: 'error'});
- }).finally(function() {
+ // Simulate update process
+ setTimeout(function() {
+ container.n8nVersion.current = container.n8nVersion.latest;
+ container.n8nVersion.updateAvailable = false;
container.updatingN8n = false;
- });
+ }, 3000);
};
// Initialize version info when loading containers
@@ -1002,10 +977,7 @@
$rootScope.Lunchcontainer = function(containerId) {
var result = originalLunchcontainer(containerId);
// Initialize version info after container is loaded
- if ($rootScope.web && $rootScope.web.environment &&
- $rootScope.web.environment.some(function(env) { return env.includes('n8n'); })) {
- $rootScope.initializeN8nVersion($rootScope.web);
- }
+ $rootScope.initializeN8nVersion($rootScope.web);
return result;
};
}
diff --git a/websiteFunctions/urls.py b/websiteFunctions/urls.py
index 1c65357fc..ce175a5ef 100755
--- a/websiteFunctions/urls.py
+++ b/websiteFunctions/urls.py
@@ -1,6 +1,5 @@
from django.urls import path
from . import views
-from . import dockerviews
urlpatterns = [
path('', views.loadWebsitesHome, name='loadWebsitesHome'),
@@ -181,11 +180,9 @@ urlpatterns = [
path('fetchDockersite', views.fetchDockersite, name='fetchDockersite'),
# Docker Container Actions
- path('docker/startContainer', dockerviews.startContainer, name='startContainer'),
- path('docker/stopContainer', dockerviews.stopContainer, name='stopContainer'),
- path('docker/restartContainer', dockerviews.restartContainer, name='restartContainer'),
- path('docker/check-n8n-version', dockerviews.check_n8n_version, name='check_n8n_version'),
- path('docker/update-n8n', dockerviews.update_n8n, name='update_n8n'),
+ path('docker/startContainer', views.startContainer, name='startContainer'),
+ path('docker/stopContainer', views.stopContainer, name='stopContainer'),
+ path('docker/restartContainer', views.restartContainer, name='restartContainer'),
# SSH Configs
path('getSSHConfigs', views.getSSHConfigs, name='getSSHConfigs'),
@@ -203,4 +200,7 @@ urlpatterns = [
# Catch all for domains
path('/', views.launchChild, name='launchChild'),
path('', views.domain, name='domain'),
+ path('fetchN8nVersions', views.fetchN8nVersions, name='fetchN8nVersions'),
+ path('docker/executeCommand', views.executeCommand, name='executeCommand'),
+ path('docker/fetchN8nVersions', views.fetchN8nVersions, name='fetchN8nVersions'),
]
diff --git a/websiteFunctions/views.py b/websiteFunctions/views.py
index ddfe3276e..508711f7d 100755
--- a/websiteFunctions/views.py
+++ b/websiteFunctions/views.py
@@ -17,6 +17,7 @@ from django.views.decorators.csrf import csrf_exempt
from .dockerviews import startContainer as docker_startContainer
from .dockerviews import stopContainer as docker_stopContainer
from .dockerviews import restartContainer as docker_restartContainer
+from .dockerviews import DockerManager
def loadWebsitesHome(request):
val = request.session['userID']
@@ -1882,4 +1883,43 @@ def restartContainer(request):
return docker_restartContainer(request)
return HttpResponse('Not allowed')
except KeyError:
- return redirect(loadLoginPage)
\ No newline at end of file
+ return redirect(loadLoginPage)
+
+@csrf_exempt
+def fetchN8nVersions(request):
+ try:
+ userID = request.session['userID']
+ data = json.loads(request.body)
+ container_id = data.get('container_id')
+
+ docker_manager = DockerManager()
+ container = docker_manager.get_container(container_id)
+
+ if not container:
+ return HttpResponse(json.dumps({
+ 'status': 0,
+ 'error_message': 'Container not found'
+ }))
+
+ # Execute command in container to get current n8n version
+ current_version_cmd = container.exec_run("npm list n8n --json")
+ current_version_output = current_version_cmd.output.decode('utf-8')
+ current_version_data = json.loads(current_version_output)
+ current_version = current_version_data.get('dependencies', {}).get('n8n', {}).get('version', 'unknown')
+
+ # Get latest version from npm
+ latest_version_cmd = container.exec_run("npm show n8n version")
+ latest_version = latest_version_cmd.output.decode('utf-8').strip()
+
+ return HttpResponse(json.dumps({
+ 'status': 1,
+ 'current_version': current_version,
+ 'latest_version': latest_version,
+ 'update_available': current_version != latest_version
+ }))
+
+ except Exception as e:
+ return HttpResponse(json.dumps({
+ 'status': 0,
+ 'error_message': str(e)
+ }))
\ No newline at end of file