views.py 25.6 KB
Newer Older
1
# -*- coding: utf-8 -*-
2
# vim: set et sts=2:
Marco Mariani's avatar
Marco Mariani committed
3 4
# pylint: disable-msg=W0311,C0301,C0103,C0111

5

Łukasz Nowak's avatar
Łukasz Nowak committed
6 7
import os
import shutil
8
import urllib
Łukasz Nowak's avatar
Łukasz Nowak committed
9

Marco Mariani's avatar
Marco Mariani committed
10 11 12 13
from flaskext.auth import Auth, AuthUser, login_required, logout
from flask import (Flask, request, redirect, url_for, render_template,
                   g, flash, jsonify, session, abort, send_file)

14
from slapos.runner.process import killRunningProcess
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
15 16 17 18 19 20 21 22 23 24 25 26
from slapos.runner.utils import (checkSoftwareFolder, configNewSR, getFolder,
                                 getFolderContent, getProfilePath,
                                 getProjectList, getProjectTitle, getSession,
                                 getSlapStatus, getSvcStatus,
                                 getSvcTailProcess, isInstanceRunning,
                                 isSoftwareRunning, isText,
                                 loadSoftwareRList, md5sum, newSoftware,
                                 readFileFrom, readParameters, realpath,
                                 removeInstanceRoot, removeProxyDb,
                                 removeSoftwareByName, runInstanceWithLock,
                                 runSoftwareWithLock, saveSession,
                                 svcStartStopProcess, svcStopAll, tail,
Marco Mariani's avatar
Marco Mariani committed
27
                                 updateInstanceParameter)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
28

Marco Mariani's avatar
Marco Mariani committed
29
from slapos.runner.fileBrowser import FileBrowser
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
30 31
from slapos.runner.gittools import (cloneRepo, gitStatus, switchBranch,
                                    addBranch, getDiff, gitPush, gitPull)
Marco Mariani's avatar
Marco Mariani committed
32 33


Łukasz Nowak's avatar
Łukasz Nowak committed
34
app = Flask(__name__)
35
app.config['MAX_CONTENT_LENGTH'] = 20 * 1024 * 1024
36 37
auth = Auth(app, login_url_name='login')
auth.user_timeout = 0
Marco Mariani's avatar
Marco Mariani committed
38
file_request = FileBrowser(app.config)
39

40 41 42 43
# Setup default flask (werkzeug) parser
import logging
logger = logging.getLogger('werkzeug')

Marco Mariani's avatar
Marco Mariani committed
44

45 46
def login_redirect(*args, **kwargs):
  return redirect(url_for('login'))
Łukasz Nowak's avatar
Łukasz Nowak committed
47

Marco Mariani's avatar
Marco Mariani committed
48

49
#Access Control: Only static files and login pages are allowed to guest
50 51
@app.before_request
def before_request():
52 53 54 55 56 57 58 59 60 61 62 63 64 65
  if request.path.startswith('/static'):
    return

  account = getSession(app.config)
  if account:
    user = AuthUser(username=account[0])
    user.set_and_encrypt_password(account[1], "123400ZYX")
    session['title'] = getProjectTitle(app.config)
    g.users = {account[0]: user}
  else:
    session['title'] = "No account is defined"
    if request.path != "/setAccount" and request.path != "/configAccount":
      return redirect(url_for('setAccount'))

66

Łukasz Nowak's avatar
Łukasz Nowak committed
67
# general views
68
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
69 70 71
def home():
  return render_template('index.html')

Marco Mariani's avatar
Marco Mariani committed
72

73 74 75 76 77
# general views
@login_required()
def browseWorkspace():
  return render_template('workspace.html')

Marco Mariani's avatar
Marco Mariani committed
78

79 80 81 82
@app.route("/login")
def login():
  return render_template('login.html')

Marco Mariani's avatar
Marco Mariani committed
83

84 85 86 87
@app.route("/setAccount")
def setAccount():
  account = getSession(app.config)
  if not account:
88
    return render_template('account.html')
89 90
  return redirect(url_for('login'))

Marco Mariani's avatar
Marco Mariani committed
91

92 93 94 95 96
@login_required()
def myAccount():
  account = getSession(app.config)
  return render_template('account.html', username=account[0],
          email=account[2], name=account[3].decode('utf-8'))
97

Marco Mariani's avatar
Marco Mariani committed
98

99 100
@app.route("/dologout")
def dologout():
Marco Mariani's avatar
Marco Mariani committed
101
  _ = logout()
102 103
  return redirect(url_for('login'))

Marco Mariani's avatar
Marco Mariani committed
104

105
@login_required()
106
def configRepo():
107
  public_key = open(app.config['public_key']).read()
108
  account = getSession(app.config)
109
  return render_template('cloneRepository.html', workDir='workspace',
110 111
            public_key=public_key, name=account[3].decode('utf-8'),
            email=account[2])
112

Marco Mariani's avatar
Marco Mariani committed
113

114 115
@app.route("/doLogin", methods=['POST'])
def doLogin():
116 117 118 119 120
  username = request.form['clogin']
  if username in g.users:
    # Authenticate and log in!
    if g.users[username].authenticate(request.form['cpwd']):
      return jsonify(code=1, result="")
121
  return jsonify(code=0, result="Login or password is incorrect, please check it!"), 401
122

Marco Mariani's avatar
Marco Mariani committed
123

Łukasz Nowak's avatar
Łukasz Nowak committed
124
# software views
125
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
126
def editSoftwareProfile():
127
  profile = getProfilePath(app.config['etc_dir'], app.config['software_profile'])
128 129
  if profile == "":
    flash('Error: can not open profile, please select your project first')
130 131
  return render_template('updateSoftwareProfile.html', workDir='workspace',
      profile=profile, projectList=getProjectList(app.config['workspace']))
Łukasz Nowak's avatar
Łukasz Nowak committed
132

Marco Mariani's avatar
Marco Mariani committed
133

134
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
135
def inspectSoftware():
136 137
  return render_template('runResult.html', softwareRoot='software_link/',
                         softwares=loadSoftwareRList(app.config))
Łukasz Nowak's avatar
Łukasz Nowak committed
138

Marco Mariani's avatar
Marco Mariani committed
139

Alain Takoudjou's avatar
Alain Takoudjou committed
140
#remove content of compiled software release
141
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
142 143 144
def removeSoftware():
  if isSoftwareRunning(app.config) or isInstanceRunning(app.config):
    flash('Software installation or instantiation in progress, cannot remove')
145
  elif os.path.exists(app.config['software_root']):
Łukasz Nowak's avatar
Łukasz Nowak committed
146 147
    svcStopAll(app.config)
    shutil.rmtree(app.config['software_root'])
148 149
    for link in os.listdir(app.config['software_link']):
      os.remove(os.path.join(app.config['software_link'], link))
Łukasz Nowak's avatar
Łukasz Nowak committed
150 151 152
    flash('Software removed')
  return redirect(url_for('inspectSoftware'))

Marco Mariani's avatar
Marco Mariani committed
153

154
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
155 156
def runSoftwareProfile():
  if runSoftwareWithLock(app.config):
Marco Mariani's avatar
Marco Mariani committed
157
    return jsonify(result=True)
Łukasz Nowak's avatar
Łukasz Nowak committed
158
  else:
Marco Mariani's avatar
Marco Mariani committed
159 160
    return jsonify(result=False)

Łukasz Nowak's avatar
Łukasz Nowak committed
161

162
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
163 164
def viewSoftwareLog():
  if os.path.exists(app.config['software_log']):
165
    result = tail(open(app.config['software_log']), lines=1500)
Łukasz Nowak's avatar
Łukasz Nowak committed
166 167
  else:
    result = 'Not found yet'
168
  return render_template('viewLog.html', type='software',
169
      result=result.encode("utf-8"))
Łukasz Nowak's avatar
Łukasz Nowak committed
170

Marco Mariani's avatar
Marco Mariani committed
171

Łukasz Nowak's avatar
Łukasz Nowak committed
172
# instance views
173
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
174
def editInstanceProfile():
175
  profile = getProfilePath(app.config['etc_dir'], app.config['instance_profile'])
176
  if profile == "":
177 178 179
    flash('Error: can not open instance profile for this Software Release')
  return render_template('updateInstanceProfile.html', workDir='workspace',
      profile=profile, projectList=getProjectList(app.config['workspace']))
Łukasz Nowak's avatar
Łukasz Nowak committed
180

Marco Mariani's avatar
Marco Mariani committed
181

Alain Takoudjou's avatar
Alain Takoudjou committed
182
# get status of all computer partitions and process state
183
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
184 185
def inspectInstance():
  if os.path.exists(app.config['instance_root']):
186 187 188 189 190
    file_path = 'instance_root'
    supervisor = getSvcStatus(app.config)
  else:
    file_path = ''
    supervisor = []
Łukasz Nowak's avatar
Łukasz Nowak committed
191
  return render_template('instanceInspect.html',
192 193 194 195
                         file_path=file_path,
                         supervisor=supervisor,
                         slap_status=getSlapStatus(app.config),
                         partition_amount=app.config['partition_amount'])
Łukasz Nowak's avatar
Łukasz Nowak committed
196

Marco Mariani's avatar
Marco Mariani committed
197

Alain Takoudjou's avatar
Alain Takoudjou committed
198
#Reload instance process ans returns new value to ajax
199
@login_required()
200 201
def supervisordStatus():
  result = getSvcStatus(app.config)
202
  if not result:
203
    return jsonify(code=0, result="")
204
  # XXX-Marco -> template
205 206 207
  html = "<tr><th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th></tr>"
  for item in result:
    html += "<tr>"
208 209
    html += "<td  class='first'><b><a href='" + url_for('tailProcess', process=item[0]) + "'>" + item[0] + "</a></b></td>"
    html += "<td align='center'><a href='" + url_for('startStopProccess', process=item[0], action=item[1]) + "'>" + item[1] + "</a></td>"
Marco Mariani's avatar
Marco Mariani committed
210
    html += "<td align='center'>" + item[3] + "</td><td>" + item[5] + "</td>"
211
    html += "<td align='center'><a href='" + url_for('startStopProccess', process=item[0], action='RESTART') + "'>Restart</a></td>"
Marco Mariani's avatar
Marco Mariani committed
212
    html += "</tr>"
213 214
  return jsonify(code=1, result=html)

Marco Mariani's avatar
Marco Mariani committed
215

216
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
217 218 219
def removeInstance():
  if isInstanceRunning(app.config):
    flash('Instantiation in progress, cannot remove')
220
  else:
221
    removeProxyDb(app.config)
Marco Mariani's avatar
Marco Mariani committed
222
    svcStopAll(app.config)  # Stop All instance process
223
    removeInstanceRoot(app.config)
224
    param_path = os.path.join(app.config['etc_dir'], ".parameter.xml")
225 226
    if os.path.exists(param_path):
      os.remove(param_path)
Łukasz Nowak's avatar
Łukasz Nowak committed
227 228 229
    flash('Instance removed')
  return redirect(url_for('inspectInstance'))

Marco Mariani's avatar
Marco Mariani committed
230

231
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
232 233 234 235
def runInstanceProfile():
  if not os.path.exists(app.config['instance_root']):
    os.mkdir(app.config['instance_root'])
  if runInstanceWithLock(app.config):
Marco Mariani's avatar
Marco Mariani committed
236
    return jsonify(result=True)
Łukasz Nowak's avatar
Łukasz Nowak committed
237
  else:
Marco Mariani's avatar
Marco Mariani committed
238 239
    return jsonify(result=False)

Łukasz Nowak's avatar
Łukasz Nowak committed
240

241
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
242 243
def viewInstanceLog():
  if os.path.exists(app.config['instance_log']):
244
    result = open(app.config['instance_log']).read()
Łukasz Nowak's avatar
Łukasz Nowak committed
245 246
  else:
    result = 'Not found yet'
247
  return render_template('viewLog.html', type='instance',
248
      result=result.encode("utf-8"))
Łukasz Nowak's avatar
Łukasz Nowak committed
249

Marco Mariani's avatar
Marco Mariani committed
250

251
@login_required()
Łukasz Nowak's avatar
Łukasz Nowak committed
252 253 254
def stopAllPartition():
  svcStopAll(app.config)
  return redirect(url_for('inspectInstance'))
255

Marco Mariani's avatar
Marco Mariani committed
256

257
@login_required(login_redirect)
258 259 260 261
def tailProcess(process):
  return render_template('processTail.html',
      process_log=getSvcTailProcess(app.config, process), process=process)

Marco Mariani's avatar
Marco Mariani committed
262

263
@login_required(login_redirect)
264 265 266 267
def startStopProccess(process, action):
  svcStartStopProcess(app.config, process, action)
  return redirect(url_for('inspectInstance'))

Marco Mariani's avatar
Marco Mariani committed
268

269
@login_required(login_redirect)
270
def openProject(method):
271 272
  return render_template('projectFolder.html', method=method,
                         workDir='workspace')
273

Marco Mariani's avatar
Marco Mariani committed
274

275
@login_required()
276
def cloneRepository():
277
  path = realpath(app.config, request.form['name'], False)
Marco Mariani's avatar
Marco Mariani committed
278 279 280 281 282 283
  data = {
    'repo': request.form['repo'],
    'user': request.form['user'],
    'email': request.form['email'],
    'path': path
  }
284
  return cloneRepo(data)
285

Marco Mariani's avatar
Marco Mariani committed
286

287
@login_required()
288
def readFolder():
289
  return getFolderContent(app.config, request.form['dir'])
290

Marco Mariani's avatar
Marco Mariani committed
291

292
@login_required()
293
def openFolder():
294
  return getFolder(app.config, request.form['dir'])
295

Marco Mariani's avatar
Marco Mariani committed
296

297
@login_required()
298
def createSoftware():
299
  return newSoftware(request.form['folder'], app.config, session)
300

Marco Mariani's avatar
Marco Mariani committed
301

302
@login_required()
303 304 305
def checkFolder():
  return checkSoftwareFolder(request.form['path'], app.config)

Marco Mariani's avatar
Marco Mariani committed
306

307
@login_required()
308 309
def setCurrentProject():
  if configNewSR(app.config, request.form['path']):
310 311 312
    session['title'] = getProjectTitle(app.config)
    return jsonify(code=1, result="")
  else:
313
    return jsonify(code=0, result=("Can not setup this Software Release"))
314

Marco Mariani's avatar
Marco Mariani committed
315

316
@login_required()
317
def manageProject():
318
  return render_template('manageProject.html', workDir='workspace',
319 320
                         project=getProjectList(app.config['workspace']))

Marco Mariani's avatar
Marco Mariani committed
321

322
@login_required()
323
def getProjectStatus():
324 325 326 327 328
  path = realpath(app.config, request.form['project'])
  if path:
    return gitStatus(path)
  else:
    return jsonify(code=0, result="Can not read folder: Permission Denied")
329

Marco Mariani's avatar
Marco Mariani committed
330

Alain Takoudjou's avatar
Alain Takoudjou committed
331
#view for current software release files
332
@login_required()
333
def editCurrentProject():
334
  project = os.path.join(app.config['etc_dir'], ".project")
335
  if os.path.exists(project):
336 337 338
    return render_template('softwareFolder.html', workDir='workspace',
                           project=open(project).read(),
                           projectList=getProjectList(app.config['workspace']))
339 340
  return redirect(url_for('configRepo'))

Marco Mariani's avatar
Marco Mariani committed
341

Alain Takoudjou's avatar
Alain Takoudjou committed
342
#create file or directory
343
@login_required()
344
def createFile():
345 346
  path = realpath(app.config, request.form['file'], False)
  if not path:
347
    return jsonify(code=0, result="Error when creating your %s: Permission Denied" % request.form['type'])
348 349
  try:
    if request.form['type'] == "file":
Marco Mariani's avatar
Marco Mariani committed
350
      open(path, 'w')
351
    else:
352
      os.mkdir(path)
353
    return jsonify(code=1, result="")
354
  except Exception as e:
355 356
    return jsonify(code=0, result=str(e))

Marco Mariani's avatar
Marco Mariani committed
357

Alain Takoudjou's avatar
Alain Takoudjou committed
358
#remove file or directory
359
@login_required()
360 361 362 363 364 365 366
def removeFile():
  try:
    if request.form['type'] == "folder":
      shutil.rmtree(request.form['path'])
    else:
      os.remove(request.form['path'])
    return jsonify(code=1, result="")
367
  except Exception as e:
368
    return jsonify(code=0, result=str(e))
369

Marco Mariani's avatar
Marco Mariani committed
370

371
@login_required()
372
def removeSoftwareDir():
373
  try:
374 375
    data = removeSoftwareByName(app.config, request.form['md5'],
            request.form['title'])
376
    return jsonify(code=1, result=data)
377
  except Exception as e:
378
    return jsonify(code=0, result=str(e))
379

Marco Mariani's avatar
Marco Mariani committed
380

Alain Takoudjou's avatar
Alain Takoudjou committed
381
#read file and return content to ajax
382
@login_required()
383
def getFileContent():
384 385
  file_path = realpath(app.config, request.form['file'])
  if file_path:
Alain Takoudjou's avatar
Alain Takoudjou committed
386 387 388
    if not isText(file_path):
      return jsonify(code=0,
            result="Can not open a binary file, please select a text file!")
Marco Mariani's avatar
Marco Mariani committed
389
    if 'truncate' in request.form:
390
      content = tail(open(file_path), int(request.form['truncate']))
391
      return jsonify(code=1, result=content)
Marco Mariani's avatar
Marco Mariani committed
392
    else:
393
      return jsonify(code=1, result=open(file_path).read())
394 395
  else:
    return jsonify(code=0, result="Error: No such file!")
396

Marco Mariani's avatar
Marco Mariani committed
397

398
@login_required()
399
def saveFileContent():
400 401
  file_path = realpath(app.config, request.form['file'])
  if file_path:
402
    open(file_path, 'w').write(request.form['content'].encode("utf-8"))
403 404
    return jsonify(code=1, result="")
  else:
405 406
    return jsonify(code=0, result="Error: No such file!")

Marco Mariani's avatar
Marco Mariani committed
407

408
@login_required()
409
def changeBranch():
410 411 412 413 414
  path = realpath(app.config, request.form['project'])
  if path:
    return switchBranch(path, request.form['name'])
  else:
    return jsonify(code=0, result="Can not read folder: Permission Denied")
415

Marco Mariani's avatar
Marco Mariani committed
416

417
@login_required()
418
def newBranch():
419 420 421 422 423 424 425 426
  path = realpath(app.config, request.form['project'])
  if path:
    if request.form['create'] == '1':
      return addBranch(path, request.form['name'])
    else:
      return addBranch(path, request.form['name'], True)
  else:
    return jsonify(code=0, result="Can not read folder: Permission Denied")
427

Marco Mariani's avatar
Marco Mariani committed
428

429
@login_required(login_redirect)
430 431 432 433 434
def getProjectDiff(project):
  path = os.path.join(app.config['workspace'], project)
  return render_template('projectDiff.html', project=project,
                           diff=getDiff(path))

Marco Mariani's avatar
Marco Mariani committed
435

436
@login_required()
437
def pushProjectFiles():
438 439 440 441 442
  path = realpath(app.config, request.form['project'])
  if path:
    return gitPush(path, request.form['msg'])
  else:
    return jsonify(code=0, result="Can not read folder: Permission Denied")
443

Marco Mariani's avatar
Marco Mariani committed
444

445
@login_required()
446
def pullProjectFiles():
447 448 449 450 451
  path = realpath(app.config, request.form['project'])
  if path:
    return gitPull(path)
  else:
    return jsonify(code=0, result="Can not read folder: Permission Denied")
452

Marco Mariani's avatar
Marco Mariani committed
453

454
@login_required()
455
def checkFileType():
456 457 458
  path = realpath(app.config, request.form['path'])
  if not path:
    return jsonify(code=0, result="Can not open file: Permission Denied!")
459 460 461
  if isText(path):
    return jsonify(code=1, result="text")
  else:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
462 463
    return jsonify(code=0,
                   result="Can not open a binary file, please select a text file!")
464

Marco Mariani's avatar
Marco Mariani committed
465

466
@login_required()
467
def getmd5sum():
468 469 470 471
  realfile = realpath(app.config, request.form['file'])
  if not realfile:
    return jsonify(code=0, result="Can not open file: Permission Denied!")
  md5 = md5sum(realfile)
472 473 474
  if md5:
    return jsonify(code=1, result=md5)
  else:
475 476
    return jsonify(code=0, result="Can not get md5sum for this file!")

Marco Mariani's avatar
Marco Mariani committed
477

Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
478
#return information about state of slapgrid process
479
@login_required()
480 481 482
def slapgridResult():
  software_state = isSoftwareRunning(app.config)
  instance_state = isInstanceRunning(app.config)
Marco Mariani's avatar
Marco Mariani committed
483 484 485 486 487
  log_result = {
    'content': '',
    'position': 0,
    'truncated': False
  }
Marco Mariani's avatar
Marco Mariani committed
488
  if request.form['log'] in ['software', 'instance']:
489 490
    log_file = request.form['log'] + "_log"
    if os.path.exists(app.config[log_file]):
491 492
      log_result = readFileFrom(open(app.config[log_file]),
                                int(request.form['position']))
Marco Mariani's avatar
Marco Mariani committed
493 494 495
  return jsonify(software=software_state, instance=instance_state,
                 result=(instance_state or software_state), content=log_result)

496

497
@login_required()
498
def stopSlapgrid():
499
  result = killRunningProcess(request.form['type'])
500 501
  return jsonify(result=result)

Marco Mariani's avatar
Marco Mariani committed
502

503
@login_required()
504 505 506 507 508 509 510 511 512 513
def getPath():
  files = request.form['file'].split('#')
  list = []
  for p in files:
    path = realpath(app.config, p)
    if not p:
      list = []
      break
    else:
      list.append(path)
Marco Mariani's avatar
Marco Mariani committed
514
  realfile = '#'.join(list)
515
  if not realfile:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
516 517
    return jsonify(code=0,
                   result="Can not access to this file: Permission Denied!")
518
  else:
519 520
    return jsonify(code=1, result=realfile)

Marco Mariani's avatar
Marco Mariani committed
521

522
@login_required()
523
def saveParameterXml():
524 525 526
  """
  Update instance parameter into a local xml file.
  """
527
  project = os.path.join(app.config['etc_dir'], ".project")
528 529
  if not os.path.exists(project):
    return jsonify(code=0, result="Please first open a Software Release")
530
  content = request.form['parameter'].encode("utf-8")
531
  param_path = os.path.join(app.config['etc_dir'], ".parameter.xml")
532
  try:
533 534
    with open(param_path, 'w') as f:
      f.write(content)
535
    result = readParameters(param_path)
536
  except Exception as e:
537
    result = str(e)
538
  software_type = None
539
  if request.form['software_type']:
540
    software_type = request.form['software_type']
541
  if type(result) == type(''):
542
    return jsonify(code=0, result=result)
543
  else:
544
    try:
545
      updateInstanceParameter(app.config, software_type)
546
    except Exception as e:
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
547 548
      return jsonify(
        code=0,
549
        result="An error occurred while applying your settings!<br/>%s" % e)
550 551
    return jsonify(code=1, result="")

Marco Mariani's avatar
Marco Mariani committed
552

553 554 555 556
@login_required()
def getSoftwareType():
  software_type_path = os.path.join(app.config['etc_dir'], ".software_type.xml")
  if os.path.exists(software_type_path):
557
    return jsonify(code=1, result=open(software_type_path).read())
558 559
  return jsonify(code=1, result="default")

Marco Mariani's avatar
Marco Mariani committed
560

Alain Takoudjou's avatar
Alain Takoudjou committed
561
#read instance parameters into the local xml file and return a dict
562
@login_required()
563
def getParameterXml(request):
564
  param_path = os.path.join(app.config['etc_dir'], ".parameter.xml")
565
  if not os.path.exists(param_path):
566
    default = '<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>'
567 568
    return jsonify(code=1, result=default)
  if request == "xml":
569
    parameters = open(param_path).read()
570 571 572 573
  else:
    parameters = readParameters(param_path)
  if type(parameters) == type('') and request != "xml":
    return jsonify(code=0, result=parameters)
574
  else:
575 576
    return jsonify(code=1, result=parameters)

577

578
#update user account data
579
@login_required()
580
def updateAccount():
581 582 583 584
  code = request.form['rcode'].strip()
  recovery_code = open(os.path.join(app.config['etc_dir'], ".rcode"), "r").read()
  if code != recovery_code:
    return jsonify(code=0, result="Your password recovery code is not valid!")
585 586 587 588 589 590 591

  account = [
    request.form['username'].strip(),
    request.form['password'].strip(),
    request.form['email'].strip(),
    request.form['name'].strip()
  ]
592
  result = saveSession(app.config, account)
593 594 595
  if type(result) == type(""):
    return jsonify(code=0, result=result)
  else:
596 597
    return jsonify(code=1, result="")

598

599 600 601 602
#update user account data
@app.route("/configAccount", methods=['POST'])
def configAccount():
  last_account = getSession(app.config)
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
  if last_account:
    return jsonify(code=0,
                   result="Unable to respond to your request, permission denied.")

  account = []
  account.append(request.form['username'].strip())
  account.append(request.form['password'].strip())
  account.append(request.form['email'].strip())
  account.append(request.form['name'].strip())
  code = request.form['rcode'].strip()
  recovery_code = open(os.path.join(app.config['etc_dir'], ".rcode"),
                      "r").read()
  if code != recovery_code:
    return jsonify(code=0, result="Your password recovery code is not valid!")
  result = saveSession(app.config, account)
  if type(result) == type(""):
    return jsonify(code=0, result=result)
  else:
    return jsonify(code=1, result="")

623

624 625 626 627 628 629 630 631 632 633 634 635 636 637
#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'))
638

639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
  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:
670
      result = file_request.readFile(dir, filename, False)
671 672 673 674 675 676 677 678 679 680 681 682 683 684
    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..."
685
  except Exception as e:
686 687 688
    return str(e)
  return result

Marco Mariani's avatar
Marco Mariani committed
689

690 691 692 693 694 695 696
@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', '')))

Marco Mariani's avatar
Marco Mariani committed
697

698 699
#Setup List of URLs
app.add_url_rule('/', 'home', home)
700 701 702
app.add_url_rule('/browseWorkspace', 'browseWorkspace', browseWorkspace)
app.add_url_rule('/editSoftwareProfile', 'editSoftwareProfile',
                editSoftwareProfile)
703 704
app.add_url_rule('/inspectSoftware', 'inspectSoftware', inspectSoftware)
app.add_url_rule('/removeSoftware', 'removeSoftware', removeSoftware)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
705
app.add_url_rule('/runSoftwareProfile', 'runSoftwareProfile',
706
                 runSoftwareProfile, methods=['GET', 'POST'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
707 708 709 710 711 712 713 714 715
app.add_url_rule('/viewSoftwareLog', 'viewSoftwareLog',
                 viewSoftwareLog, methods=['GET'])
app.add_url_rule('/editInstanceProfile', 'editInstanceProfile',
                 editInstanceProfile)
app.add_url_rule('/inspectInstance', 'inspectInstance',
                 inspectInstance, methods=['GET'])
app.add_url_rule('/supervisordStatus', 'supervisordStatus',
                 supervisordStatus, methods=['GET'])
app.add_url_rule('/runInstanceProfile', 'runInstanceProfile',
716
                 runInstanceProfile, methods=['GET', 'POST'])
717
app.add_url_rule('/removeInstance', 'removeInstance', removeInstance)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
718 719 720 721 722 723 724 725 726 727
app.add_url_rule('/viewInstanceLog', 'viewInstanceLog',
                 viewInstanceLog, methods=['GET'])
app.add_url_rule('/stopAllPartition', 'stopAllPartition',
                 stopAllPartition, methods=['GET'])
app.add_url_rule('/tailProcess/name/<process>', 'tailProcess',
                 tailProcess, methods=['GET'])
app.add_url_rule('/startStopProccess/name/<process>/cmd/<action>',
                 'startStopProccess', startStopProccess, methods=['GET'])
app.add_url_rule("/getParameterXml/<request>", 'getParameterXml',
                 getParameterXml, methods=['GET'])
728 729
app.add_url_rule('/getSoftwareType', 'getSoftwareType',
                 getSoftwareType, methods=['GET'])
730
app.add_url_rule("/stopSlapgrid", 'stopSlapgrid', stopSlapgrid, methods=['POST'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
731 732
app.add_url_rule("/slapgridResult", 'slapgridResult',
                 slapgridResult, methods=['POST'])
733
app.add_url_rule("/getmd5sum", 'getmd5sum', getmd5sum, methods=['POST'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
734 735 736 737 738 739 740 741
app.add_url_rule("/checkFileType", 'checkFileType', checkFileType,
                 methods=['POST'])
app.add_url_rule("/pullProjectFiles", 'pullProjectFiles', pullProjectFiles,
                 methods=['POST'])
app.add_url_rule("/pushProjectFiles", 'pushProjectFiles', pushProjectFiles,
                 methods=['POST'])
app.add_url_rule("/getProjectDiff/<project>", 'getProjectDiff', getProjectDiff,
                 methods=['GET'])
742 743
app.add_url_rule("/newBranch", 'newBranch', newBranch, methods=['POST'])
app.add_url_rule("/changeBranch", 'changeBranch', changeBranch, methods=['POST'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
744 745 746 747 748 749
app.add_url_rule("/saveFileContent", 'saveFileContent', saveFileContent,
                 methods=['POST'])
app.add_url_rule("/removeSoftwareDir", 'removeSoftwareDir', removeSoftwareDir,
                 methods=['POST'])
app.add_url_rule("/getFileContent", 'getFileContent', getFileContent,
                 methods=['POST'])
750 751 752
app.add_url_rule("/removeFile", 'removeFile', removeFile, methods=['POST'])
app.add_url_rule("/createFile", 'createFile', createFile, methods=['POST'])
app.add_url_rule("/editCurrentProject", 'editCurrentProject', editCurrentProject)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
753 754 755 756
app.add_url_rule("/getProjectStatus", 'getProjectStatus', getProjectStatus,
                 methods=['POST'])
app.add_url_rule('/openProject/<method>', 'openProject', openProject,
                 methods=['GET'])
757
app.add_url_rule("/manageProject", 'manageProject', manageProject, methods=['GET'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
758 759
app.add_url_rule("/setCurrentProject", 'setCurrentProject', setCurrentProject,
                 methods=['POST'])
760
app.add_url_rule("/checkFolder", 'checkFolder', checkFolder, methods=['POST'])
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
761 762 763 764
app.add_url_rule('/createSoftware', 'createSoftware', createSoftware,
                 methods=['POST'])
app.add_url_rule('/cloneRepository', 'cloneRepository', cloneRepository,
                 methods=['POST'])
765 766 767
app.add_url_rule('/openFolder', 'openFolder', openFolder, methods=['POST'])
app.add_url_rule('/readFolder', 'readFolder', readFolder, methods=['POST'])
app.add_url_rule('/configRepo', 'configRepo', configRepo)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
768 769
app.add_url_rule("/saveParameterXml", 'saveParameterXml', saveParameterXml,
                 methods=['POST'])
770 771
app.add_url_rule("/getPath", 'getPath', getPath, methods=['POST'])
app.add_url_rule("/myAccount", 'myAccount', myAccount)
Cédric Le Ninivin's avatar
Cédric Le Ninivin committed
772 773 774 775
app.add_url_rule("/updateAccount", 'updateAccount', updateAccount,
                 methods=['POST'])
app.add_url_rule("/fileBrowser", 'fileBrowser', fileBrowser,
                 methods=['GET', 'POST'])
776
app.add_url_rule("/editFile", 'editFile', editFile, methods=['GET'])