From 08eb67e0d479bb978e67bc88f45c4517118a93f7 Mon Sep 17 00:00:00 2001 From: matthewalanpenning Date: Sat, 11 Nov 2023 13:34:27 -0500 Subject: [PATCH] v0.4.0 --- lxconsole/api/access_controls.py | 8 --- lxconsole/api/instance.py | 74 +++++++++----------------- lxconsole/templates/instance.html | 86 +++++++------------------------ lxconsole/templates/main.html | 2 - lxconsole/templates/server.html | 3 ++ 5 files changed, 46 insertions(+), 127 deletions(-) diff --git a/lxconsole/api/access_controls.py b/lxconsole/api/access_controls.py index af8e740..1b75edd 100644 --- a/lxconsole/api/access_controls.py +++ b/lxconsole/api/access_controls.py @@ -40,7 +40,6 @@ def privilege_check(privilege, server_id = 0): #'change_cluster_member_state', #'change_instance_state', #'copy_instance', - 'copy_instance_proc_meminfo', 'copy_instance_proc_stat', #'create_instance_backup', #'create_instance_snapshot_instance', @@ -89,7 +88,6 @@ def privilege_check(privilege, server_id = 0): 'get_instance_gpu_devices', 'get_instance_interfaces', 'get_instance_network_devices', - 'get_instance_proc_meminfo', 'get_instance_proc_stat', 'get_instance_proxy_devices', 'get_instance_state', @@ -208,7 +206,6 @@ def privilege_check(privilege, server_id = 0): 'change_cluster_member_state', 'change_instance_state', 'copy_instance', - 'copy_instance_proc_meminfo', 'copy_instance_proc_stat', 'create_instance_backup', 'create_instance_snapshot_instance', @@ -257,7 +254,6 @@ def privilege_check(privilege, server_id = 0): 'get_instance_gpu_devices', 'get_instance_interfaces', 'get_instance_network_devices', - 'get_instance_proc_meminfo', 'get_instance_proc_stat', 'get_instance_proxy_devices', 'get_instance_state', @@ -376,7 +372,6 @@ def privilege_check(privilege, server_id = 0): 'change_cluster_member_state', 'change_instance_state', 'copy_instance', - 'copy_instance_proc_meminfo', 'copy_instance_proc_stat', 'create_instance_backup', 'create_instance_snapshot_instance', @@ -425,7 +420,6 @@ def privilege_check(privilege, server_id = 0): 'get_instance_gpu_devices', 'get_instance_interfaces', 'get_instance_network_devices', - 'get_instance_proc_meminfo', 'get_instance_proc_stat', 'get_instance_proxy_devices', 'get_instance_state', @@ -544,7 +538,6 @@ def privilege_check(privilege, server_id = 0): 'change_cluster_member_state', 'change_instance_state', 'copy_instance', - 'copy_instance_proc_meminfo', 'copy_instance_proc_stat', 'create_instance_backup', 'create_instance_snapshot_instance', @@ -593,7 +586,6 @@ def privilege_check(privilege, server_id = 0): 'get_instance_gpu_devices', 'get_instance_interfaces', 'get_instance_network_devices', - 'get_instance_proc_meminfo', 'get_instance_proc_stat', 'get_instance_proxy_devices', 'get_instance_state', diff --git a/lxconsole/api/instance.py b/lxconsole/api/instance.py index de416ea..f0a5de6 100644 --- a/lxconsole/api/instance.py +++ b/lxconsole/api/instance.py @@ -625,8 +625,9 @@ def api_instance_endpoint(endpoint): # Unable to read /proc/stat directly on virtual machines use lxd files api...getting an EOF error # So we will copy /proc/stat to /tmp/stat and then read that file as a work around data = {} - #data.update({'command': ['/bin/sh', '-c', 'cat /proc/stat \u003e /tmp/stat' ]}) - data.update({'command': ['cp', '/proc/stat', '/tmp/stat']}) + data.update({'command': ['/bin/sh', '-c', 'cat /proc/stat \u003e /tmp/stat' ]}) + #data.update({'command': ['cat', '/proc/stat']}) + #data.update({'command': ['cp', '/proc/stat', '/tmp/stat']}) data.update({'wait-for-websocket': False}) data.update({'interactive': False}) data.update({'width': 80 }) @@ -639,6 +640,25 @@ def api_instance_endpoint(endpoint): url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/exec?project=' + project results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data) + + #Using record-output no longer appears to work, but it looks like lxd has code to use a new method of recording logs with exec-output as an option in the near future + #Set record-output: true in command + #exec_rtn = json.dumps(results.json()) + #exec_rtn = json.loads(exec_rtn) + #Use operation to check for return value and get log output information + #operation = exec_rtn['operation'] + #Check the logs/exec-ouput with get request to see if log exists /1.0/instances/{name}/logs/exec-output + #url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/logs/exec-output?project=' + project + #results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key)) + #results return a list of urls of exec-output files. Should be able to match operation to a file in the list + #example url: url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/test/logs/exec-output/exec_fea46679-fdaa-48f4-9079-502a090c4fb5.stdout' + #results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key)) + #The returned value should be text: return results.text + #Check stdout log with get request "/1.0/instances/foo/logs/exec-output/exec_d0a89537-0617-4ed6-a79b-c2e88a970965.stdout", + #return results.text + #Check stderr log with get request "/1.0/instances/foo/logs/exec-output/exec_d0a89537-0617-4ed6-a79b-c2e88a970965.stderr", + #Else delete to delete log at /1.0/instances/{name}/logs/exec-output/{filename} + return jsonify(results.json()) # Virtual Machine only @@ -662,55 +682,7 @@ def api_instance_endpoint(endpoint): system_time= int(stats[3]) idle_time = int(stats[4]) return jsonify({'user_time':user_time, 'system_time':system_time, 'idle_time':idle_time}) - return jsonify({'user_time':0, 'system_time':0, 'idle_time':1}) - - # Virtual Machine only - if endpoint == 'copy_instance_proc_meminfo': - id = request.args.get('id') - project = request.args.get('project') - server = Server.query.filter_by(id=id).first() - name = request.args.get('name') - client_cert = get_client_crt() - client_key = get_client_key() - - # Unable to read /proc/stat directly on virtual machines use lxd files api...getting an EOF error - # So we will copy /proc/stat to /tmp/stat and then read that file as a work around - data = {} - #data.update({'command': ['/bin/sh', '-c', 'cat /proc/meminfo \u003e /tmp/meminfo' ]}) - data.update({'command': ['cp', '/proc/meminfo', '/tmp/meminfo']}) - data.update({'wait-for-websocket': False}) - data.update({'interactive': False}) - data.update({'width': 80 }) - data.update({'height': 24 }) - data.update({'user': 0 }) - data.update({'group': 0 }) - data.update({'cwd': "/" }) - data.update({'record-output': False }) - data.update({'environment': {} }) - - url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/exec?project=' + project - results = requests.post(url, verify=server.ssl_verify, cert=(client_cert, client_key), json=data) - return jsonify(results.json()) - - # Virtual Machine only - if endpoint == 'get_instance_proc_meminfo': - id = request.args.get('id') - project = request.args.get('project') - server = Server.query.filter_by(id=id).first() - name = request.args.get('name') - client_cert = get_client_crt() - client_key = get_client_key() - - #Get /proc/meminfo information but from /tmp/meminfo - url = 'https://' + server.addr + ':' + str(server.port) + '/1.0/instances/' + name + '/files?project=' + project + '&path=/tmp/meminfo' - results = requests.get(url, verify=server.ssl_verify, cert=(client_cert, client_key)) - if 'MemTotal' in results.text: - results = results.text.split('\n') - mem_total = results[0].split() - mem_available = results[2].split() - percentage = 100 * ( 1 - ( int(mem_available[1]) / int(mem_total[1]) ) ) - return jsonify({'mem_total':int(mem_total[1]), 'mem_available':int(mem_available[1]), 'percentage':percentage}) - return jsonify({'mem_total':0, 'mem_available':0, 'percentage':0}) + return jsonify({'user_time':0, 'system_time':0, 'idle_time':0}) if endpoint == 'get_instance_cpu_usage': diff --git a/lxconsole/templates/instance.html b/lxconsole/templates/instance.html index 28340e5..eeb99a7 100644 --- a/lxconsole/templates/instance.html +++ b/lxconsole/templates/instance.html @@ -740,26 +740,6 @@ pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime); } - - function getInstanceProcMeminfo() { - $.get("../api/instance/get_instance_proc_meminfo?id="+serverId+"&project="+project+"&name="+instance, function (data) { - if (data.mem_total > 0){ - percentage = parseFloat(100 * ( 1 - parseInt(data.mem_available) / parseInt(data.mem_total))).toFixed(2) - } - else { - percentage = parseFloat(0).toFixed(2) - } - - //Update Memory progress bar - $('#memPercentage').text(percentage) - $('#memPercentageBar').css('width', percentage + '%'); - $('#memPercentageBar').attr('aria-valuenow', percentage + '%'); - if (percentage > 90.00) - $('#memPercentageBar').attr('class', 'progress-bar bg-danger'); - else - $('#memPercentageBar').attr('class', 'progress-bar bg-primary'); - }); - } function getInstanceProcStat() { $.get("../api/instance/get_instance_proc_stat?id="+serverId+"&project="+project+"&name="+instance, function (data) { @@ -770,6 +750,10 @@ // If we have existing session values, find the difference else just use data values if (session_user_time + session_system_time + session_idle_time > 0){ + //If session values equal data values end function + if (data.user_time == session_user_time && data.system_time == session_system_time && data.idle_time == session_idle_time) { + return + } // If difference between data and session values is greater than zero then calculate if (data.user_time - session_user_time + data.system_time - session_system_time + data.idle_time - session_idle_time > 0) { percentage = parseFloat(100 * (1 - (data.idle_time - session_idle_time) / (data.user_time - session_user_time + data.system_time - session_system_time + data.idle_time - session_idle_time))).toFixed(2) @@ -980,53 +964,23 @@ $("#swap").text(parseFloat(parseInt(data.memory.swap_usage) / 1024 / 1024 / 1024).toFixed(2) + ' GiB') $("#pid").text(data.pid) $("#processes").text(data.processes) + + if (data.memory.usage && data.memory.total && data.memory.total > 0){ + percentage = parseFloat(100 * (data.memory.usage / data.memory.total)).toFixed(2) + } + else { + percentage = parseFloat(0).toFixed(2) + } + + $('#memPercentage').text(percentage) + $('#memPercentageBar').css('width', percentage + '%'); + $('#memPercentageBar').attr('aria-valuenow', percentage + '%'); + if (percentage > 90.00) + $('#memPercentageBar').attr('class', 'progress-bar bg-danger'); + else + $('#memPercentageBar').attr('class', 'progress-bar bg-primary'); - //Update Memory Bar based on container or virtual-machine - if (instanceType == "container") { - instance_memory = parseInt(data.memory.usage) - //Set host_memory in sessionStorage if it has not yet been set else read from sessionstorage - if (sessionStorage.getItem("host_memory") === null) { - $.get("../api/server/get_server_resources?id="+serverId, function (data) { - data = data.metadata - host_memory = parseInt(data['memory']['total']) - //Store stats for page reload - sessionStorage.setItem('host_memory', host_memory) - percentage = parseFloat(100 * (instance_memory / host_memory)).toFixed(2) - $('#memPercentage').text(percentage) - $('#memPercentageBar').css('width', percentage + '%'); - $('#memPercentageBar').attr('aria-valuenow', percentage + '%'); - if (percentage > 90.00) - $('#memPercentageBar').attr('class', 'progress-bar bg-danger'); - else - $('#memPercentageBar').attr('class', 'progress-bar bg-primary'); - }) - } - else { - host_memory = parseInt(sessionStorage.getItem('host_memory')) - if (host_memory <= 0){ - $.get("../api/server/get_server_resources?id="+serverId, function (data) { - data = data.metadata - host_memory = parseInt(data['memory']['total']) - //Store stats for page reload - sessionStorage.setItem('host_memory', host_memory) - }) - } - percentage = parseFloat(100 * (instance_memory / host_memory)).toFixed(2) - $('#memPercentage').text(percentage) - $('#memPercentageBar').css('width', percentage + '%'); - $('#memPercentageBar').attr('aria-valuenow', percentage + '%'); - if (percentage > 90.00) - $('#memPercentageBar').attr('class', 'progress-bar bg-danger'); - else - $('#memPercentageBar').attr('class', 'progress-bar bg-primary'); - } - } - if (instanceType == 'virtual-machine') { - $.get("../api/instance/copy_instance_proc_meminfo?id="+serverId+"&project="+project+"&name="+instance, function (data) { - //Get instance /proc/meminfo - setTimeout(() => { getInstanceProcMeminfo(); }, reloadTime / 2); - }); - } + }); } diff --git a/lxconsole/templates/main.html b/lxconsole/templates/main.html index 093bf84..bea0e41 100644 --- a/lxconsole/templates/main.html +++ b/lxconsole/templates/main.html @@ -130,8 +130,6 @@ }) } - - function updateAccount(){ $.post("../api/users/update_user", { id: "{{ page_user_id }}", diff --git a/lxconsole/templates/server.html b/lxconsole/templates/server.html index 76b228f..d5061b3 100644 --- a/lxconsole/templates/server.html +++ b/lxconsole/templates/server.html @@ -340,6 +340,7 @@ $("#serverName").text(data.server_name); $("#storage").text(data.storage); $("#storageVersion").text(data.storage_version); + $("#addressList").text("") addresses = data.addresses; addresses.forEach(element => { $("#addressList").append('
  • '+element+'
  • '); @@ -388,11 +389,13 @@ $('#memoryPercentageProgressBar').attr('class', 'progress-bar bg-primary'); $("#memoryPercentage").text(memoryPercentage + '% of host memory used') + $("#socketList").text("") sockets = data.cpu.sockets; sockets.forEach(element => { $("#socketList").append('
  • Socket '+element.socket+': '+element.name+'
  • '); }); + $('#diskList').text(""); disks = data.storage.disks; disks.forEach(element => { if (element.type == "cdrom"){