Commit 0ea58389 authored by Alain Takoudjou's avatar Alain Takoudjou

Update inspect software release, add Filebrowser

parent d6059404
...@@ -111,17 +111,21 @@ def run(): ...@@ -111,17 +111,21 @@ def run():
def serve(config): def serve(config):
from views import app from views import app
workdir = os.path.join(config.runner_workdir, 'project') workdir = os.path.join(config.runner_workdir, 'project')
software_link = os.path.join(config.runner_workdir, 'softwareLink')
app.config.update(**config.__dict__) app.config.update(**config.__dict__)
app.config.update( app.config.update(
software_log=config.software_root.rstrip('/') + '.log', software_log=config.software_root.rstrip('/') + '.log',
instance_log=config.instance_root.rstrip('/') + '.log', instance_log=config.instance_root.rstrip('/') + '.log',
workspace = workdir, workspace = workdir,
software_link=software_link,
instance_profile='instance.cfg', instance_profile='instance.cfg',
software_profile='software.cfg', software_profile='software.cfg',
SECRET_KEY="123456", SECRET_KEY=os.urandom(24),
PERMANENT_SESSION_LIFETIME=timedelta(days=31), PERMANENT_SESSION_LIFETIME=timedelta(days=31),
) )
if not os.path.exists(workdir): if not os.path.exists(workdir):
os.mkdir(workdir) os.mkdir(workdir)
if not os.path.exists(software_link):
os.mkdir(software_link)
app.run(host=config.runner_host, port=int(config.runner_port), app.run(host=config.runner_host, port=int(config.runner_port),
debug=config.debug, threaded=True) debug=config.debug, threaded=True)
...@@ -3,7 +3,7 @@ $(document).ready(function(){ ...@@ -3,7 +3,7 @@ $(document).ready(function(){
var hashes = window.location.href.split('#'); var hashes = window.location.href.split('#');
var fromheight = 0; var fromheight = 0;
var previoustab = null; var previoustab = null;
if (hashes.length == 2 && hashes[1] != ""){ if (hashes.length == 2 && hashes[1] !== ''){
$("#tabContaier>ul li").each(function() { $("#tabContaier>ul li").each(function() {
var $tab = $(this).find("a"); var $tab = $(this).find("a");
if($tab.hasClass("active")){ if($tab.hasClass("active")){
......
...@@ -63,15 +63,15 @@ $(document).ready(function() { ...@@ -63,15 +63,15 @@ $(document).ready(function() {
$.ajax({ $.ajax({
type: 'GET', type: 'GET',
url: $SCRIPT_ROOT + '/getParameterXml/xml', url: $SCRIPT_ROOT + '/getParameterXml/xml',
success: function(data) { success: function(data){
if (data.code == 1) { if(data.code == 1){
$('#inline_content').html(content); $("#inline_instance").html(content);
setupEditor(true); setupEditor(true);
$('.inline').colorbox({inline: true, width: '600px', height: '410px', onComplete: function() { $("a#inlineInstance").colorbox({inline:true, width: "600px", height: "410px", onComplete:function(){
editor.getSession().setValue(data.result); editor.getSession().setValue(data.result);
}}); }});
$('.inline').click(); $("a#inlineInstance").click();
$('#loadxml').click(function() { $("#loadxml").click(function(){
//Parse XML file //Parse XML file
try { try {
var xmlDoc = $.parseXML(editor.getSession().getValue()), $xml = $(xmlDoc); var xmlDoc = $.parseXML(editor.getSession().getValue()), $xml = $(xmlDoc);
...@@ -109,32 +109,20 @@ $(document).ready(function() { ...@@ -109,32 +109,20 @@ $(document).ready(function() {
} }
}); });
function setupFileTree(path) { function setupFileTree(path){
var root = $('input#root').val(); var root = $("input#root").val();
if (root == '') return; if (root === '') return;
if (path) { if (path){
root += '/' + path; root += '/' + path + '/';
$('#tab4>h2').html('File content for <strong>' + path + '</strong>');
}
else {$('#tab4>h2').html('File content for all your partitions');}
$('#fileTree').empty();
$('#fileTree').fileTree({ root: root, script: $SCRIPT_ROOT + '/readFolder', folderEvent: 'click', expandSpeed: 750,
collapseSpeed: 750, multiFolder: false, selectFolder: false }, function(file) {
}, function(file) {
//User have double click on file in to the fileTree
viewFile(file);
});
} }
else{root += '/';}
function viewFile(file) { $('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT+"/fileBrowser", root: root});
//User have double click on file in to the fileTree
loadFileContent(file);
} }
$('#parameter').load($SCRIPT_ROOT + '/getParameterXml');
$('#update').click(function() { $("#parameter").load($SCRIPT_ROOT + '/getParameterXml');
if ($('#parameter').val() == '') { $("#update").click(function(){
$('#error').Popup('Can not save empty value!', {type: 'alert', duration: 3000}); if($("#parameter").val() === ''){
$("#error").Popup("Can not save empty value!", {type:'alert', duration:3000});
} }
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
...@@ -151,47 +139,6 @@ $(document).ready(function() { ...@@ -151,47 +139,6 @@ $(document).ready(function() {
}); });
}); });
function loadFileContent(file) {
$.ajax({
type: 'POST',
url: $SCRIPT_ROOT + '/checkFileType',
data: 'path=' + file,
success: function(data) {
if (data.code == 1) {
if (data.result == 'text') {
$.ajax({
type: 'POST',
url: $SCRIPT_ROOT + '/getFileContent',
data: {file: file, truncate: 1500},
success: function(data) {
if (data.code == 1) {
$('#inline_content').empty();
$('#inline_content').append('<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">Inspect Instance Content: ' +
file + '</h2>');
$('#inline_content').append('<br/><div class="main_content"><pre id="editor"></pre></div>');
setupEditor();
$('.inline').colorbox({inline: true, width: '847px', onComplete: function() {
editor.getSession().setValue(data.result);
}});
$('.inline').click();
}
else {
$('#error').Popup('Can not load your file, please make sure that you have selected a Software Release', {type: 'alert', duration: 5000});
}
}
});
}
else {
//Can not displays binary file
$('#error').Popup(data.result, {type: 'alert', duration: 5000});
}
}
else {
$('#error').Popup(data.result, {type: 'alert', duration: 5000});
}
}
});
}
function updateParameter() { function updateParameter() {
var xml = '<?xml version="1.0" encoding="utf-8"?>\n', var xml = '<?xml version="1.0" encoding="utf-8"?>\n',
software_type = '', software_type = '',
...@@ -233,7 +180,9 @@ $(document).ready(function() { ...@@ -233,7 +180,9 @@ $(document).ready(function() {
$txt.keyup(function() { $txt.keyup(function() {
content = $txt.val().replace(/\n/g, '<br>'); content = $txt.val().replace(/\n/g, '<br>');
hiddenDiv.html(content); hiddenDiv.html(content);
if (hiddenDiv.height() > $txt.height() && hiddenDiv.height() > 120) {return} if (hiddenDiv.height() > $txt.height() && hiddenDiv.height() > 120) {
return;
}
$txt.css('height', hiddenDiv.height() + 'px'); $txt.css('height', hiddenDiv.height() + 'px');
}); });
} }
...@@ -241,15 +190,15 @@ $(document).ready(function() { ...@@ -241,15 +190,15 @@ $(document).ready(function() {
$.ajax({ $.ajax({
type: 'GET', type: 'GET',
url: $SCRIPT_ROOT + '/getParameterXml/dict', url: $SCRIPT_ROOT + '/getParameterXml/dict',
success: function(data) { success: function(data){
if (data.code == 1) { if(data.code == 1){
var dict = data.result['instance']; var dict = data.result['instance'];
for (propertie in dict) { for (var propertie in dict){
$('#add_attribute').click(); $("#add_attribute").click();
var size = Number($('#partitionParameter > tbody > tr').last().attr('id').split('_')[1]); var size = Number($("#partitionParameter > tbody > tr").last().attr('id').split('_')[1]);
$('input#txt_' + size).val(propertie); $("input#txt_"+size).val(propertie);
$('textarea#value_' + size).val(dict[propertie]); $("textarea#value_"+size).val(dict[propertie]);
$('textarea#value_' + size).keyup(); $("textarea#value_"+size).keyup();
} }
} }
else { else {
...@@ -302,10 +251,10 @@ $(document).ready(function() { ...@@ -302,10 +251,10 @@ $(document).ready(function() {
for (var i = 0; i < partitionAmount; i++) { for (var i = 0; i < partitionAmount; i++) {
var elt = $('#slappart' + i + 'Parameter'); var elt = $('#slappart' + i + 'Parameter');
var fileId = $('#slappart' + i + 'Files'); var fileId = $('#slappart' + i + 'Files');
if (elt && elt != undefined) elt.click(function() { if (elt && elt !== undefined) elt.click(function() {
alert($(this).html()); alert($(this).html());
}); });
if (fileId && fileId != undefined) fileId.click(function() { if (fileId && fileId !== undefined) fileId.click(function() {
$('#instancetabfiles').click(); $('#instancetabfiles').click();
setupFileTree($(this).attr('rel')); setupFileTree($(this).attr('rel'));
}); });
......
...@@ -2,32 +2,13 @@ $(document).ready( function() { ...@@ -2,32 +2,13 @@ $(document).ready( function() {
var editor; var editor;
var send = false; var send = false;
var runnerDir = $("input#runnerdir").val(); var runnerDir = $("input#runnerdir").val();
var ajaxRun; $("#reloadfiles").click(function(){
fillContent();
$("#softwarelist").change(function(){
$("#info").empty();
$("#info").append("Please select your file or folder into the box...");
fillContent(); fillContent();
}); });
fillContent();
function selectFile(file){
var relativeFile = file.replace(runnerDir + "/" + $("#softwarelist").val(), "");
$("#info").empty();
$("#info").append("Selection: " + relativeFile);
return;
}
function fillContent(){ function fillContent(){
var folder = $("#softwarelist").val(); $('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT+"/fileBrowser", root: runnerDir});
var elt = $("option:selected", $("#softwarelist"));
if(elt.val() !== "No Software Release found"){
$('#fileTree').fileTree({ root: runnerDir + "/" + folder, script: $SCRIPT_ROOT + '/readFolder',
folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) {
selectFile(file);
}, function(file){ viewFile(file)});
$("#softcontent").empty();
$("#softcontent").append("File content: " + elt.attr('title'));
}
} }
$("#open").click(function(){ $("#open").click(function(){
...@@ -59,33 +40,24 @@ $(document).ready( function() { ...@@ -59,33 +40,24 @@ $(document).ready( function() {
} }
if(send) return; if(send) return;
send = false; send = false;
var elt = $("option:selected", $("#softwarelist"));
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: $SCRIPT_ROOT + '/removeSoftwareDir', url: $SCRIPT_ROOT + '/removeSoftwareDir',
data: "name=" + $("#softwarelist").val(), data: {md5:$("#softwarelist").val(), title:elt.attr('title')},
success: function(data){ success: function(data){
if(data.code == 1){ if(data.code == 1){
var folder = $("#softwarelist").val();
$("input#file").val("");
$("#info").empty();
$("#info").append("Please select your file or folder into the box...");
$("#softwarelist").empty(); $("#softwarelist").empty();
for(i=0; i<data.result.length; i++){ for(var i=0; i<data.result.length; i++){
$("#softwarelist").append('<option value="' + data.result[i]["md5"] + $("#softwarelist").append('<option value="' + data.result[i]['md5'] +
'" title="' + data.result[i]["title"] +'" rel="' + '" title="' + data.result[i]['title'] +'" rel="' +
data.result[i]["path"] +'">' + data.result[i]["title"] + '</option>'); data.result[i]['path'] +'">' + data.result[i]['title'] + '</option>');
} }
if(data.result.length < 1){ if(data.result.length < 1){
$("#softwarelist").append('<option>No Software Release found</option>'); $("#softwarelist").append('<option>No Software Release found</option>');
$('#fileTree').empty(); $('#fileTree').empty();
} }
else{ fillContent();
folder = $("#softwarelist").val();
$('#fileTree').fileTree({ root: runnerDir + "/" + folder, script: $SCRIPT_ROOT + '/readFolder', folderEvent: 'click', expandSpeed: 750,
collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) {
selectFile(file);
}, function(file){ viewFile(file)});
}
$("#error").Popup("Operation complete, Selected Software Release has been delete!", {type:'confirm', duration:5000}); $("#error").Popup("Operation complete, Selected Software Release has been delete!", {type:'confirm', duration:5000});
} }
else{ else{
...@@ -97,54 +69,6 @@ $(document).ready( function() { ...@@ -97,54 +69,6 @@ $(document).ready( function() {
return false; return false;
}); });
function viewFile(file){
//User have double click on file in to the fileTree
var name = file.replace(runnerDir + "/" + $("#softwarelist").val(), "/software");
loadFileContent(file, name);
}
function loadFileContent(file, filename){
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/checkFileType',
data: "path=" + file,
success: function(data){
if(data.code == 1){
if (data.result=="text"){
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/getFileContent',
data: {file:file, truncate:1500},
success: function(data){
if(data.code == 1){
$("#inline_content").empty();
$("#inline_content").append('<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">Inspect Software Content: ' +
filename +'</h2>');
$("#inline_content").append('<br/><div class="main_content"><pre id="editor"></pre></div>');
setupEditor();
$(".inline").colorbox({inline:true, width: "847px", onComplete:function(){
editor.getSession().setValue(data.result);
}});
$(".inline").click();
}
else{
$("#error").Popup("Can not load your file, please make sure that you have selected a Software Release", {type:'alert', duration:5000});
}
}
});
}
else{
//Can not displays binary file
$("#error").Popup(data.result, {type:'alert', duration:5000});
}
}
else{
$("#error").Popup(data.result, {type:'alert', duration:5000});
}
}
});
}
function setupEditor(){ function setupEditor(){
editor = ace.edit("editor"); editor = ace.edit("editor");
editor.setTheme("ace/theme/crimson_editor"); editor.setTheme("ace/theme/crimson_editor");
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
{% block title %}Instance inspection{% endblock %} {% block title %}Instance inspection{% endblock %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<!--<link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
<script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>-->
<link href="{{ url_for('static', filename='css/jqueryTabs.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" /> <link href="{{ url_for('static', filename='css/jqueryTabs.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
<script src="{{ url_for('static', filename='js/jquery/jqueryTabs.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/jquery/jqueryTabs.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/ace/ace.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/ace/ace.js') }}" type="text/javascript" charset="utf-8"></script>
...@@ -99,7 +97,7 @@ ...@@ -99,7 +97,7 @@
</div><!-- end tab2 --> </div><!-- end tab2 -->
<div id="tab3" class="tabContents"> <div id="tab3" class="tabContents">
<div id="softwareType"> <div id="softwareType">
<h2 class='hight'>Software Type of main instance</h2> <h2 class='title'>Software Type of main instance</h2>
<input style="margin-top:5px;" type="text" name="software_type" id="software_type" size="35" value="Software Type here..." /> <input style="margin-top:5px;" type="text" name="software_type" id="software_type" size="35" value="Software Type here..." />
</div> </div>
<br/> <br/>
......
...@@ -2,19 +2,19 @@ ...@@ -2,19 +2,19 @@
{% block title %}Webrunner software Inspection{% endblock %} {% block title %}Webrunner software Inspection{% endblock %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<link href="{{ url_for('static', filename='css/jqueryFileTree.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
<script src="{{ url_for('static', filename='js/jquery/jqueryFileTree.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/ace/ace.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/ace/ace.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/ace/theme-crimson_editor.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/scripts/inspectSoftware.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/scripts/inspectSoftware.js') }}" type="text/javascript" charset="utf-8"></script>
<link href="{{ url_for('static', filename='css/colorbox.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" /> <link href="{{ url_for('static', filename='css/colorbox.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
<script src="{{ url_for('static', filename='js/jquery/jquery.colorbox-min.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/jquery/jquery.colorbox-min.js') }}" type="text/javascript" charset="utf-8"></script>
<link href="{{ url_for('static', filename='css/gsFileManager.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
<script src="{{ url_for('static', filename='js/jquery/gsFileManager.js') }}" type="text/javascript" charset="utf-8"></script>
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<h2>Inspect software</h2> <h2>Inspect software release</h2>
<input type="hidden" name="runnerdir" id="runnerdir" value="{{softwareRoot}}" /> <input type="hidden" name="runnerdir" id="runnerdir" value="{{softwareRoot}}" />
<label for='softwarelist'>Select software: </label> <label for='softwarelist'>Software Release: </label>
<select name="softwarelist" id="softwarelist"> <select name="softwarelist" id="softwarelist">
{%if not softwares %}<option >No Software Release found</option>{% endif %} {%if not softwares %}<option >No Software Release found</option>{% endif %}
{%for soft in softwares %} {%for soft in softwares %}
...@@ -24,16 +24,8 @@ ...@@ -24,16 +24,8 @@
&nbsp;&nbsp;<button id ="delete" class="button" title="Remove this software">Remove</button> &nbsp;&nbsp;<button id ="delete" class="button" title="Remove this software">Remove</button>
&nbsp;&nbsp;<button id ="open" class="button" title="Set this software as current software release">Open</button> &nbsp;&nbsp;<button id ="open" class="button" title="Set this software as current software release">Open</button>
<br/><br/> <br/><br/>
<h2 id="softcontent">No file or folder to display</h2> <div id="fileNavigator"></div>
<div id="fileTree" class="file_tree" style='height:200px;' title="Double click to open file"></div> <br/>
<div id="file_info" class="file_info"> <a href="#" id="reloadfiles" class="lshare simple">Reload Files</a>
<span id="info">Please select your file or folder into the box...</span></div>
<!-- This contains the hidden content for inline calls -->
<a class='inline' style='display:none' href="#inline_content">Inline HTML</a>
<div style='display:none'>
<div id='inline_content' style='padding:10px; background:#fff;'>
</div>
</div>
<br/> <br/>
{% endblock %} {% endblock %}
...@@ -275,27 +275,58 @@ def runSoftwareWithLock(config): ...@@ -275,27 +275,58 @@ def runSoftwareWithLock(config):
writePid(slapgrid_pid, slapgrid.pid) writePid(slapgrid_pid, slapgrid.pid)
slapgrid.wait() slapgrid.wait()
#Saves the current compile software for re-use #Saves the current compile software for re-use
#This uses the new folder create by slapgrid (if not exits yet) config_SR_folder(config)
data = loadSoftwareData(config['etc_dir'])
md5 = ""
for path in os.listdir(config['software_root']):
exist = False
for val in data:
if val['md5'] == path:
exist = True
conf = os.path.join(config['etc_dir'], ".project")
if not exist: #save this compile software folder
if os.path.exists(conf):
data.append({"title":getProjectTitle(config), "md5":path,
"path": open(os.path.join(config['etc_dir'],
".project"), 'r').read()})
writeSoftwareData(config['etc_dir'], data)
else:
shutil.rmtree(os.path.join(config['software_root'], path))
break
return True return True
return False return False
def config_SR_folder(config):
"""Create a symbolik link for each folder in software folder. That allow
user to customize software release folder"""
list = []
config_name = 'slaprunner.config'
for path in os.listdir(config['software_link']):
cfg_path = os.path.join(config['software_link'], path, config_name)
if os.path.exists(cfg_path):
cfg = open(cfg_path, 'r').read().split("#")
if len(cfg) != 2:
continue #there is a broken config file
list.append(cfg[1])
folder_list = os.listdir(config['software_root'])
if len(folder_list) < 1:
return
curent_project = open(os.path.join(config['etc_dir'], ".project"),
'r').read()
projects = curent_project.split("/")
name = projects[len(projects) - 2]
for folder in folder_list:
if folder in list:
continue #this folder is already registered
else:
if not os.path.exists(os.path.join(config['software_link'], name)):
destination = os.path.join(config['software_link'], name)
else:
destination = os.path.join(config['software_link'], folder)
source = os.path.join(config['software_root'], folder)
cfg = os.path.join(destination, config_name)
#create symlink
os.symlink(source, destination)
#write config file
cf = open(cfg, 'w')
cf.write(curent_project+"#"+folder)
cf.close()
def loadSoftwareRList(config):
"""Return list (of dict) of Software Release from symbolik SR folder"""
list = []
config_name = 'slaprunner.config'
for path in os.listdir(config['software_link']):
cfg_path = os.path.join(config['software_link'], path, config_name)
if os.path.exists(cfg_path):
cfg = open(cfg_path, 'r').read().split("#")
if len(cfg) != 2:
continue #there is a broken config file
list.append(dict(md5=cfg[1], path=cfg[0], title=path))
return list
def isInstanceRunning(config): def isInstanceRunning(config):
""" """
...@@ -535,6 +566,7 @@ def getProjectList(folder): ...@@ -535,6 +566,7 @@ def getProjectList(folder):
project = [] project = []
project_list = sorted(os.listdir(folder), key=str.lower) project_list = sorted(os.listdir(folder), key=str.lower)
for elt in project_list: for elt in project_list:
if os.path.isdir(os.path.join(folder, elt)):
project.append(elt) project.append(elt)
return project return project
...@@ -627,59 +659,26 @@ def getSoftwareReleaseName(config): ...@@ -627,59 +659,26 @@ def getSoftwareReleaseName(config):
return software.replace(' ', '_') return software.replace(' ', '_')
return "No_name" return "No_name"
def loadSoftwareData(basedir): def removeSoftwareByName(config, md5, folderName):
"""Get All Compiled Softwares Releases name and directory """Remove all content of the software release specified by md5
Agrs:
basedir: base directory of slapos web runner.
Returns:
a dictionnary that contains all compiled Software Release with path"""
import pickle
file_path = os.path.join(basedir, '.softdata')
if not os.path.exists(file_path):
return []
pkl_file = open(file_path, 'rb')
data = pickle.load(pkl_file)
pkl_file.close()
return data
def writeSoftwareData(basedir, data):
"""Save the list of compiled Software Release into a file
Args:
basedir: base directory of slapos web runner.
data: dictionnary data about real name and directory of each software release
"""
import pickle
file_path = os.path.join(basedir, '.softdata')
pkl_file = open(file_path, 'wb')
# Pickle dictionary using protocol 0.
pickle.dump(data, pkl_file)
pkl_file.close()
def removeSoftwareByName(config, folderName):
"""Remove all content of the specified software release
Args: Args:
config: slaprunner configuration config: slaprunner configuration
foldername: the name given to the software release""" foldername: the link name given to the software release
md5: the md5 filename given by slapgrid to SR folder"""
if isSoftwareRunning(config) or isInstanceRunning(config): if isSoftwareRunning(config) or isInstanceRunning(config):
raise Exception("Software installation or instantiation in progress, cannot remove") raise Exception("Software installation or instantiation in progress, cannot remove")
path = os.path.join(config['software_root'], folderName) path = os.path.join(config['software_root'], md5)
linkpath = os.path.join(config['software_link'], folderName)
if not os.path.exists(path): if not os.path.exists(path):
raise Exception("Cannot remove software Release: No such file or directory") raise Exception("Cannot remove software Release: No such file or directory")
if not os.path.exists(linkpath):
raise Exception("Cannot remove software Release: No such file or directory %s" %
('software_root/'+folderName))
svcStopAll(config) svcStopAll(config)
os.unlink(linkpath)
shutil.rmtree(path) shutil.rmtree(path)
#update compiled software list return loadSoftwareRList(config)
data = loadSoftwareData(config['etc_dir'])
i = 0
for p in data:
if p['md5'] == folderName:
del data[i]
writeSoftwareData(config['etc_dir'], data)
break
i = i+1
return data
def tail(f, lines=20): def tail(f, lines=20):
""" """
...@@ -775,7 +774,8 @@ def realpath(config, path, check_exist=True): ...@@ -775,7 +774,8 @@ def realpath(config, path, check_exist=True):
split_path = path.split('/') split_path = path.split('/')
key = split_path[0] key = split_path[0]
allow_list = {'software_root':config['software_root'], 'instance_root': allow_list = {'software_root':config['software_root'], 'instance_root':
config['instance_root'], 'workspace': config['workspace']} config['instance_root'], 'workspace': config['workspace'],
'software_link':config['software_link']}
if allow_list.has_key(key): if allow_list.has_key(key):
del split_path[0] del split_path[0]
path = os.path.join(allow_list[key], *split_path) path = os.path.join(allow_list[key], *split_path)
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from flask import Flask, request, redirect, url_for, \ from flask import Flask, request, redirect, url_for, \
render_template, g, flash, jsonify, session render_template, g, flash, jsonify, session, abort, send_file
from utils import * from utils import *
import os import os
import shutil import shutil
...@@ -9,10 +9,14 @@ import md5 ...@@ -9,10 +9,14 @@ import md5
from gittools import cloneRepo, gitStatus, switchBranch, addBranch, getDiff, \ from gittools import cloneRepo, gitStatus, switchBranch, addBranch, getDiff, \
gitPush, gitPull gitPush, gitPull
from flaskext.auth import Auth, AuthUser, login_required, logout from flaskext.auth import Auth, AuthUser, login_required, logout
from fileBrowser import fileBrowser
import urllib
app = Flask(__name__) app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 20 * 1024 * 1024
auth = Auth(app, login_url_name='login') auth = Auth(app, login_url_name='login')
auth.user_timeout = 0 auth.user_timeout = 0
file_request = fileBrowser(app.config)
# Setup default flask (werkzeug) parser # Setup default flask (werkzeug) parser
import logging import logging
...@@ -95,8 +99,8 @@ def inspectSoftware(): ...@@ -95,8 +99,8 @@ def inspectSoftware():
result = "" result = ""
else: else:
result = app.config['software_root'] result = app.config['software_root']
return render_template('runResult.html', softwareRoot='software_root', return render_template('runResult.html', softwareRoot='software_link/',
softwares=loadSoftwareData(app.config['etc_dir'])) softwares=loadSoftwareRList(app.config))
#remove content of compiled software release #remove content of compiled software release
@login_required() @login_required()
...@@ -147,7 +151,8 @@ def inspectInstance(): ...@@ -147,7 +151,8 @@ def inspectInstance():
if len(result) == 0: if len(result) == 0:
result = [] result = []
return render_template('instanceInspect.html', return render_template('instanceInspect.html',
file_path=file_content, supervisor=result, slap_status=getSlapStatus(app.config), file_path=file_content, supervisor=result,
slap_status=getSlapStatus(app.config),
supervisore=result, partition_amount=app.config['partition_amount']) supervisore=result, partition_amount=app.config['partition_amount'])
#Reload instance process ans returns new value to ajax #Reload instance process ans returns new value to ajax
...@@ -304,7 +309,8 @@ def removeFile(): ...@@ -304,7 +309,8 @@ def removeFile():
@login_required() @login_required()
def removeSoftwareDir(): def removeSoftwareDir():
try: try:
data = removeSoftwareByName(app.config, request.form['name']) data = removeSoftwareByName(app.config, request.form['md5'],
request.form['title'])
return jsonify(code=1, result=data) return jsonify(code=1, result=data)
except Exception, e: except Exception, e:
return jsonify(code=0, result=str(e)) return jsonify(code=0, result=str(e))
...@@ -505,7 +511,8 @@ def configAccount(): ...@@ -505,7 +511,8 @@ def configAccount():
account.append(request.form['email'].strip()) account.append(request.form['email'].strip())
account.append(request.form['name'].strip()) account.append(request.form['name'].strip())
code = request.form['rcode'].strip() code = request.form['rcode'].strip()
recovery_code = open(os.path.join(app.config['etc_dir'], ".rcode"), "r").read() recovery_code = open(os.path.join(app.config['etc_dir'], ".rcode"),
"r").read()
if code != recovery_code: if code != recovery_code:
return jsonify(code=0, result="Your password recovery code is not valid!") return jsonify(code=0, result="Your password recovery code is not valid!")
result = saveSession(app.config, account) result = saveSession(app.config, account)
...@@ -515,6 +522,78 @@ def configAccount(): ...@@ -515,6 +522,78 @@ def configAccount():
return jsonify(code=1, result="") return jsonify(code=1, result="")
return jsonify(code=0, result="Unable to respond to your request, permission denied.") return jsonify(code=0, result="Unable to respond to your request, permission denied.")
#Global File Manager
@login_required()
def fileBrowser():
if request.method == 'POST':
filename = request.form.get('filename', '').encode('utf-8')
dir = request.form['dir'].encode('utf-8')
newfilename = request.form.get('newfilename', '').encode('utf-8')
files = request.form.get('files', '').encode('utf-8')
if not request.form.has_key('opt') or not request.form['opt']:
opt = 1
else:
opt = int(request.form['opt'])
else:
opt = int(request.args.get('opt'))
try:
if opt == 1:
#list files and directories
result = file_request.listDirs(dir)
elif opt == 2:
#Create file
result = file_request.makeFile(dir, filename)
elif opt == 3:
#Create directory
result = file_request.makeDirectory(dir, filename)
elif opt == 4:
#Delete a list of files or/and directories
result = file_request.deleteItem(dir, files)
elif opt == 5:
#copy a lis of files or/and directories
result = file_request.copyItem(dir, files)
elif opt == 6:
#rename file or directory
result = file_request.rename(dir, filename, newfilename)
elif opt == 7:
result = file_request.copyItem(dir, files, del_source=True)
elif opt == 8:
#donwload file
filename = request.args.get('filename').encode('utf-8')
result = file_request.downloadFile(request.args.get('dir').encode('utf-8'),
filename)
try:
return send_file(result, attachment_filename=filename, as_attachment=True)
except:
abort(404)
elif opt == 9:
truncateTo = int(request.form.get('truncate', '0'))
result = file_request.readFile(dir, filename)
elif opt == 11:
#Upload file
result = file_request.uploadFile(dir, request.files)
elif opt == 14:
#Copy file or directory as ...
result = file_request.copyAsFile(dir, filename, newfilename)
elif opt == 16:
#zip file
result = file_request.zipFile(dir, filename, newfilename)
elif opt == 17:
#zip file
result = file_request.unzipFile(dir, filename, newfilename)
else:
result = "ARGS PARSE ERROR: Bad option..."
except Exception, e:
return str(e)
return result
@login_required()
def editFile():
return render_template('editFile.html', workDir='workspace',
profile=urllib.unquote(request.args.get('profile', '')),
projectList=getProjectList(app.config['workspace']),
filename=urllib.unquote(request.args.get('filename', '')))
#Setup List of URLs #Setup List of URLs
app.add_url_rule('/', 'home', home) app.add_url_rule('/', 'home', home)
app.add_url_rule('/editSoftwareProfile', 'editSoftwareProfile', editSoftwareProfile) app.add_url_rule('/editSoftwareProfile', 'editSoftwareProfile', editSoftwareProfile)
...@@ -561,3 +640,5 @@ app.add_url_rule("/saveParameterXml", 'saveParameterXml', saveParameterXml, meth ...@@ -561,3 +640,5 @@ app.add_url_rule("/saveParameterXml", 'saveParameterXml', saveParameterXml, meth
app.add_url_rule("/getPath", 'getPath', getPath, methods=['POST']) app.add_url_rule("/getPath", 'getPath', getPath, methods=['POST'])
app.add_url_rule("/myAccount", 'myAccount', myAccount) app.add_url_rule("/myAccount", 'myAccount', myAccount)
app.add_url_rule("/updateAccount", 'updateAccount', updateAccount, methods=['POST']) app.add_url_rule("/updateAccount", 'updateAccount', updateAccount, methods=['POST'])
app.add_url_rule("/fileBrowser", 'fileBrowser', fileBrowser, methods=['GET', 'POST'])
app.add_url_rule("/editFile", 'editFile', editFile, methods=['GET'])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment