Commit 9f6f9673 authored by Cédric de Saint Martin's avatar Cédric de Saint Martin

Merge branch 'slaprunner'

Conflicts:
	slapos/pubsub/notifier.py
parents 415e50cf fbeebb8b
...@@ -60,22 +60,22 @@ setup(name=name, ...@@ -60,22 +60,22 @@ setup(name=name,
'cloudmgr = slapos.cloudmgr.cloudmgr:main', 'cloudmgr = slapos.cloudmgr.cloudmgr:main',
'cloudstart = slapos.cloudmgr.start:main', 'cloudstart = slapos.cloudmgr.start:main',
'cloudstop = slapos.cloudmgr.stop:main', 'cloudstop = slapos.cloudmgr.stop:main',
'onetimeupload = slapos.onetimeupload:main', 'equeue = slapos.equeue:main',
'killpidfromfile = slapos.systool:killpidfromfile',
'lampconfigure = slapos.lamp:run [lampconfigure]',
'onetimedownload = slapos.onetimedownload:main', 'onetimedownload = slapos.onetimedownload:main',
'onetimeupload = slapos.onetimeupload:main',
'pubsubnotifier = slapos.pubsub.notifier:main',
'pubsubserver = slapos.pubsub:main',
'shacache = slapos.shacache:main', 'shacache = slapos.shacache:main',
'slapbuilder = slapos.builder:main', 'slapbuilder = slapos.builder:main',
'slapcontainer = slapos.container:main',
'slapmonitor = slapos.monitor:run_slapmonitor', 'slapmonitor = slapos.monitor:run_slapmonitor',
'slapmonitor-xml = slapos.monitor:run_slapmonitor_xml', 'slapmonitor-xml = slapos.monitor:run_slapmonitor_xml',
'slapreport = slapos.monitor:run_slapreport', 'slapreport = slapos.monitor:run_slapreport',
'slaprunner = slapos.runner:run', 'slaprunner = slapos.runner:run',
'killpidfromfile = slapos.systool:killpidfromfile',
'lampconfigure = slapos.lamp:run [lampconfigure]',
'equeue = slapos.equeue:main',
'pubsubserver = slapos.pubsub:main',
'pubsubnotifier = slapos.pubsub.notifier:main',
'slaprunnertest = slapos.runner.runnertest:main', 'slaprunnertest = slapos.runner.runnertest:main',
'zodbpack = slapos.zodbpack:run [zodbpack]', 'zodbpack = slapos.zodbpack:run [zodbpack]',
'slapcontainer = slapos.container:main',
] ]
}, },
) )
...@@ -152,19 +152,19 @@ def run(config): ...@@ -152,19 +152,19 @@ def run(config):
fdisk_output_path = "/tmp/a_generated_file" fdisk_output_path = "/tmp/a_generated_file"
try: try:
if not config.virtual: if not config.virtual:
offset = 0 offset = 0
fdisk_output_file = open(fdisk_output_path, 'w') fdisk_output_file = open(fdisk_output_path, 'w')
_call(['sfdisk', '-d', '-uS', config.system_path], stdout=fdisk_output_file) _call(['sfdisk', '-d', '-uS', config.system_path], stdout=fdisk_output_file)
fdisk_output_file.close() fdisk_output_file.close()
fdisk_output_file = open(fdisk_output_path, 'r') fdisk_output_file = open(fdisk_output_path, 'r')
for line in fdisk_output_file: for line in fdisk_output_file:
line = line.rstrip().replace(' ', '') line = line.rstrip().replace(' ', '')
if line.endswith("bootable"): if line.endswith("bootable"):
offset = int(line.split(':')[1].split(',')[0].split('=')[1]) offset = int(line.split(':')[1].split(',')[0].split('=')[1])
fdisk_output_file.close() fdisk_output_file.close()
offset = offset * 512 offset = offset * 512
_call(['mount', '-o', 'loop,offset=%i' % offset, config.system_path, _call(['mount', '-o', 'loop,offset=%i' % offset, config.system_path,
mount_dir_path], dry_run=dry_run) mount_dir_path], dry_run=dry_run)
# Call vmware-mount to mount Virtual disk image # Call vmware-mount to mount Virtual disk image
else: else:
print "Mount Virtual Image" print "Mount Virtual Image"
...@@ -191,7 +191,7 @@ def run(config): ...@@ -191,7 +191,7 @@ def run(config):
cert_file])) cert_file]))
for (src, dst) in [(config.key_file, key_file_dest), (config.cert_file, for (src, dst) in [(config.key_file, key_file_dest), (config.cert_file,
cert_file_dest)]: cert_file_dest)]:
print "Coping %r to %r, and setting minimum privileges" % (src, dst) print "Coping %r to %r, and setting minimal privileges" % (src, dst)
if not dry_run: if not dry_run:
shutil.copy(src, dst) shutil.copy(src, dst)
os.chmod(dst, 0600) os.chmod(dst, 0600)
...@@ -302,16 +302,16 @@ def run(config): ...@@ -302,16 +302,16 @@ def run(config):
# Adding slapos_firstboot in case of MultiDisk usage # Adding slapos_firstboot in case of MultiDisk usage
if not config.one_disk : if not config.one_disk :
for script in ['slapos_firstboot']: for script in ['slapos_firstboot']:
path = os.path.join(mount_dir_path, 'etc', 'init.d', script) path = os.path.join(mount_dir_path, 'etc', 'init.d', script)
print "Creating %r" % path print "Creating %r" % path
if not dry_run: if not dry_run:
open(path, 'w').write(pkg_resources.resource_stream(__name__, open(path, 'w').write(pkg_resources.resource_stream(__name__,
'script/%s' % script).read()) 'script/%s' % script).read())
os.chmod(path, 0755) os.chmod(path, 0755)
else: else:
for script in ['slapos_firstboot']: for script in ['slapos_firstboot']:
path = os.path.join(mount_dir_path, 'etc', 'init.d', script) path = os.path.join(mount_dir_path, 'etc', 'init.d', script)
if os.path.exists(path): if os.path.exists(path):
print "Removing %r" % path print "Removing %r" % path
os.remove(path) os.remove(path)
......
File mode changed from 100644 to 100755
from optparse import OptionParser, Option # -*- coding: utf-8 -*-
# vim: set et sts=2:
# pylint: disable-msg=W0311,C0301,C0103,C0111,R0904,R0903
import ConfigParser import ConfigParser
import datetime
import logging import logging
import logging.handlers import logging.handlers
from optparse import OptionParser, Option
import os import os
import slapos.runner.process
import sys import sys
import subprocess from slapos.runner.utils import runInstanceWithLock
from datetime import timedelta
class Parser(OptionParser): class Parser(OptionParser):
""" """
...@@ -13,7 +19,7 @@ class Parser(OptionParser): ...@@ -13,7 +19,7 @@ class Parser(OptionParser):
""" """
def __init__(self, usage=None, version=None): def __init__(self, usage=None, version=None):
""" """
Initialize all options possibles. Initialize all possible options.
""" """
OptionParser.__init__(self, usage=usage, version=version, OptionParser.__init__(self, usage=usage, version=version,
option_list=[ option_list=[
...@@ -45,6 +51,13 @@ class Parser(OptionParser): ...@@ -45,6 +51,13 @@ class Parser(OptionParser):
return options, args[0] return options, args[0]
class Config: class Config:
def __init__(self):
self.configuration_file_path = None
self.console = None
self.log_file = None
self.logger = None
self.verbose = None
def setConfig(self, option_dict, configuration_file_path): def setConfig(self, option_dict, configuration_file_path):
""" """
Set options given by parameters. Set options given by parameters.
...@@ -100,9 +113,13 @@ def run(): ...@@ -100,9 +113,13 @@ def run():
config = Config() config = Config()
config.setConfig(*Parser(usage=usage).check_args()) config.setConfig(*Parser(usage=usage).check_args())
if os.getuid() == 0:
# avoid mistakes (mainly in development mode)
raise Exception('Do not run SlapRunner as root.')
serve(config) serve(config)
return_code = 0 return_code = 0
except SystemExit, err: except SystemExit as err:
# Catch exception raise by optparse # Catch exception raise by optparse
return_code = err return_code = err
...@@ -121,11 +138,13 @@ def serve(config): ...@@ -121,11 +138,13 @@ def serve(config):
instance_profile='instance.cfg', instance_profile='instance.cfg',
software_profile='software.cfg', software_profile='software.cfg',
SECRET_KEY=os.urandom(24), SECRET_KEY=os.urandom(24),
PERMANENT_SESSION_LIFETIME=timedelta(days=31), PERMANENT_SESSION_LIFETIME=datetime.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): if not os.path.exists(software_link):
os.mkdir(software_link) os.mkdir(software_link)
slapos.runner.process.setHandler()
runInstanceWithLock(app.config)
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)
# -*- coding: utf-8 -*-
# vim: set et sts=2:
#pylint: disable-all
import json
from flask import Response
def as_json(f):
def inner(*args, **kwargs):
return Response(json.dumps(f(*args, **kwargs)), mimetype='application/json')
return inner
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: set et sts=2:
# pylint: disable-msg=W0311,C0301,C0103,C0111
import os
import urllib
from flask import jsonify
from werkzeug import secure_filename
import shutil
import datetime import datetime
import hashlib import md5
from utils import realpath, tail, isText import os
import re import re
import shutil
import urllib
import zipfile import zipfile
class fileBrowser(object): import werkzeug
from slapos.runner.utils import realpath, tail, isText
class FileBrowser(object):
"""This class contain all bases function for file browser""" """This class contain all bases function for file browser"""
def __init__(self, config): def __init__(self, config):
self.config = config self.config = config
def _realdir(self, dir):
realdir = realpath(self.config, urllib.unquote(dir))
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
return realdir
def listDirs(self, dir, all=False): def listDirs(self, dir, all=False):
"""List elements of directory 'dir' taken""" """List elements of directory 'dir' taken"""
html = '' html = 'var gsdirs = [], gsfiles = [];'
html += 'var gsdirs = new Array();'
html += 'var gsfiles = new Array();' dir = urllib.unquote(dir)
dir = urllib.unquote(str(dir)) # 'dir' is used below. XXX should not shadow a builtin name
realdir = realpath(self.config, dir) realdir = realpath(self.config, dir)
if not realdir: if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir) raise NameError('Could not load directory %s: Permission denied' % dir)
...@@ -31,33 +40,31 @@ class fileBrowser(object): ...@@ -31,33 +40,31 @@ class fileBrowser(object):
for f in ldir: for f in ldir:
if f.startswith('.') and not all: #do not display this file/folder if f.startswith('.') and not all: #do not display this file/folder
continue continue
ff = os.path.join(dir,f) ff = os.path.join(dir, f)
realfile = os.path.join(realdir, f) realfile = os.path.join(realdir, f)
mdate = datetime.datetime.fromtimestamp(os.path.getmtime(realfile) mdate = datetime.datetime.fromtimestamp(os.path.getmtime(realfile)
).strftime("%Y-%d-%m %I:%M") ).strftime("%Y-%d-%m %I:%M")
md5 = hashlib.md5(realfile).hexdigest() md5sum = md5.md5(realfile).hexdigest()
if not os.path.isdir(realfile): if not os.path.isdir(realfile):
size = os.path.getsize(realfile) size = os.path.getsize(realfile)
regex = re.compile("(^.*)\.(.*)", re.VERBOSE) regex = re.compile("(^.*)\.(.*)", re.VERBOSE)
ext = regex.sub(r'\2', f) ext = regex.sub(r'\2', f)
if ext == f: if ext == f:
ext = "unknow" ext = "unknow"
else: else:
ext = str.lower(ext) ext = str.lower(ext)
html += 'gsfiles.push(new gsItem("1", "' + f + '", "' + \ html += 'gsfiles.push(new gsItem("1", "' + f + '", "' + \
ff + '", "' + str(size) + '", "' + md5 + \ ff + '", "' + str(size) + '", "' + md5sum + \
'", "' + ext + '", "' + mdate + '"));'; '", "' + ext + '", "' + mdate + '"));'
else: else:
html += 'gsdirs.push(new gsItem("2", "' + f + '", "' + \ html += 'gsdirs.push(new gsItem("2", "' + f + '", "' + \
ff + '", "0", "' + md5 + '", "dir", "' + mdate + '"));'; ff + '", "0", "' + md5sum + '", "dir", "' + mdate + '"));'
return html return html
def makeDirectory(self, dir, filename): def makeDirectory(self, dir, filename):
"""Create a directory""" """Create a directory"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
folder = os.path.join(realdir, filename) folder = os.path.join(realdir, filename)
if not os.path.exists(folder): if not os.path.exists(folder):
os.mkdir(folder, 0744) os.mkdir(folder, 0744)
...@@ -65,23 +72,20 @@ class fileBrowser(object): ...@@ -65,23 +72,20 @@ class fileBrowser(object):
else: else:
return '{result: \'0\'}' return '{result: \'0\'}'
def makeFile(self, dir, filename): def makeFile(self, dir, filename):
"""Create a file in a directory dir taken""" """Create a file in a directory dir taken"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir: fout = os.path.join(realdir, filename)
raise NameError('Could not load directory %s: Permission denied' % dir) if not os.path.exists(fout):
file = os.path.join(realdir, filename) open(fout, 'w')
if not os.path.exists(file):
open(file, 'w').write('')
return 'var responce = {result: \'1\'}' return 'var responce = {result: \'1\'}'
else: else:
return '{result: \'0\'}' return '{result: \'0\'}'
def deleteItem(self, dir, files): def deleteItem(self, dir, files):
"""Delete a list of files or directories""" """Delete a list of files or directories"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
lfiles = urllib.unquote(files).split(',,,') lfiles = urllib.unquote(files).split(',,,')
try: try:
for file in lfiles: for file in lfiles:
...@@ -89,22 +93,20 @@ class fileBrowser(object): ...@@ -89,22 +93,20 @@ class fileBrowser(object):
if not os.path.exists(file): if not os.path.exists(file):
continue #silent skip file.... continue #silent skip file....
details = file.split('/') details = file.split('/')
last = details[len(details) - 1] last = details[-1]
if last and last.startswith('.'): if last and last.startswith('.'):
continue #cannot delete this file/directory, to prevent security continue #cannot delete this file/directory, to prevent security
if os.path.isdir(file): if os.path.isdir(file):
shutil.rmtree(file) shutil.rmtree(file)
else: else:
os.unlink(file) os.unlink(file)
except Exception, e: except Exception as e:
return str(e) return str(e)
return '{result: \'1\'}' return '{result: \'1\'}'
def copyItem(self, dir, files, del_source=False): def copyItem(self, dir, files, del_source=False):
"""Copy a list of files or directory to dir""" """Copy a list of files or directory to dir"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
lfiles = urllib.unquote(files).split(',,,') lfiles = urllib.unquote(files).split(',,,')
try: try:
for file in lfiles: for file in lfiles:
...@@ -113,7 +115,7 @@ class fileBrowser(object): ...@@ -113,7 +115,7 @@ class fileBrowser(object):
raise NameError('Could not load file or directory %s: Permission denied' % file) raise NameError('Could not load file or directory %s: Permission denied' % file)
#prepare destination file #prepare destination file
details = realfile.split('/') details = realfile.split('/')
dest = os.path.join(realdir, details[len(details) - 1]) dest = os.path.join(realdir, details[-1])
if os.path.exists(dest): if os.path.exists(dest):
raise NameError('NOT ALLOWED OPERATION : File or directory already exist') raise NameError('NOT ALLOWED OPERATION : File or directory already exist')
if os.path.isdir(realfile): if os.path.isdir(realfile):
...@@ -124,15 +126,13 @@ class fileBrowser(object): ...@@ -124,15 +126,13 @@ class fileBrowser(object):
shutil.copy(realfile, dest) shutil.copy(realfile, dest)
if del_source: if del_source:
os.unlink(realfile) os.unlink(realfile)
except Exception, e: except Exception as e:
return str(e) return str(e)
return '{result: \'1\'}' return '{result: \'1\'}'
def rename(self, dir, filename, newfilename): def rename(self, dir, filename, newfilename):
"""Rename file or directory to dir/filename""" """Rename file or directory to dir/filename"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
realfile = realpath(self.config, urllib.unquote(filename)) realfile = realpath(self.config, urllib.unquote(filename))
if not realfile: if not realfile:
raise NameError('Could not load directory %s: Permission denied' % filename) raise NameError('Could not load directory %s: Permission denied' % filename)
...@@ -144,9 +144,7 @@ class fileBrowser(object): ...@@ -144,9 +144,7 @@ class fileBrowser(object):
def copyAsFile(self, dir, filename, newfilename): def copyAsFile(self, dir, filename, newfilename):
"""Copy file or directory to dir/filename""" """Copy file or directory to dir/filename"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
fromfile = os.path.join(realdir, filename) fromfile = os.path.join(realdir, filename)
tofile = os.path.join(realdir, newfilename) tofile = os.path.join(realdir, newfilename)
if not os.path.exists(fromfile): if not os.path.exists(fromfile):
...@@ -158,21 +156,17 @@ class fileBrowser(object): ...@@ -158,21 +156,17 @@ class fileBrowser(object):
def uploadFile(self, dir, files): def uploadFile(self, dir, files):
"""Upload a list of file in directory dir""" """Upload a list of file in directory dir"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
for file in files: for file in files:
if files[file]: if files[file]:
filename = secure_filename(files[file].filename) filename = werkzeug.secure_filename(files[file].filename)
if not os.path.exists(os.path.join(dir, filename)): if not os.path.exists(os.path.join(dir, filename)):
files[file].save(os.path.join(realdir, filename)) files[file].save(os.path.join(realdir, filename))
return '{result: \'1\'}' return '{result: \'1\'}'
def downloadFile(self, dir, filename): def downloadFile(self, dir, filename):
"""Download file dir/filename""" """Download file dir/filename"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
file = os.path.join(realdir, urllib.unquote(filename)) file = os.path.join(realdir, urllib.unquote(filename))
if not os.path.exists(file): if not os.path.exists(file):
raise NameError('NOT ALLOWED OPERATION : File or directory does not exist %s' raise NameError('NOT ALLOWED OPERATION : File or directory does not exist %s'
...@@ -181,9 +175,7 @@ class fileBrowser(object): ...@@ -181,9 +175,7 @@ class fileBrowser(object):
def zipFile(self, dir, filename, newfilename): def zipFile(self, dir, filename, newfilename):
"""Add filename to archive as newfilename""" """Add filename to archive as newfilename"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
tozip = os.path.join(realdir, newfilename) tozip = os.path.join(realdir, newfilename)
fromzip = os.path.join(realdir, filename) fromzip = os.path.join(realdir, filename)
if not os.path.exists(fromzip): if not os.path.exists(fromzip):
...@@ -192,10 +184,10 @@ class fileBrowser(object): ...@@ -192,10 +184,10 @@ class fileBrowser(object):
zip = zipfile.ZipFile(tozip, 'w', zipfile.ZIP_DEFLATED) zip = zipfile.ZipFile(tozip, 'w', zipfile.ZIP_DEFLATED)
if os.path.isdir(fromzip): if os.path.isdir(fromzip):
rootlen = len(fromzip) + 1 rootlen = len(fromzip) + 1
for base, dirs, files in os.walk(fromzip): for base, _, files in os.walk(fromzip):
for file in files: for filename in files:
fn = os.path.join(base, file).encode("utf-8") fn = os.path.join(base, filename).encode("utf-8")
zip.write(fn, fn[rootlen:]) zip.write(fn, fn[rootlen:]) # XXX can fail if 'fromzip' contains multibyte characters
else: else:
zip.write(fromzip) zip.write(fromzip)
zip.close() zip.close()
...@@ -204,9 +196,7 @@ class fileBrowser(object): ...@@ -204,9 +196,7 @@ class fileBrowser(object):
def unzipFile(self, dir, filename, newfilename): def unzipFile(self, dir, filename, newfilename):
"""Extract a zipped archive""" """Extract a zipped archive"""
realdir = realpath(self.config, urllib.unquote(dir)) realdir = self._realdir(dir)
if not realdir:
raise NameError('Could not load directory %s: Permission denied' % dir)
target = os.path.join(realdir, newfilename) target = os.path.join(realdir, newfilename)
archive = os.path.join(realdir, filename) archive = os.path.join(realdir, filename)
if not os.path.exists(archive): if not os.path.exists(archive):
...@@ -222,7 +212,7 @@ class fileBrowser(object): ...@@ -222,7 +212,7 @@ class fileBrowser(object):
return '{result: \'1\'}' return '{result: \'1\'}'
raise NameError('NOT ALLOWED OPERATION : File or directory already exist') raise NameError('NOT ALLOWED OPERATION : File or directory already exist')
def readFile(self, dir, filename, truncate=0): def readFile(self, dir, filename, truncate=False):
"""Read file dir/filename and return content""" """Read file dir/filename and return content"""
realfile = realpath(self.config, os.path.join(urllib.unquote(dir), realfile = realpath(self.config, os.path.join(urllib.unquote(dir),
urllib.unquote(filename))) urllib.unquote(filename)))
...@@ -230,7 +220,7 @@ class fileBrowser(object): ...@@ -230,7 +220,7 @@ class fileBrowser(object):
raise NameError('Could not load directory %s: Permission denied' % dir) raise NameError('Could not load directory %s: Permission denied' % dir)
if not isText(realfile): if not isText(realfile):
return "FILE ERROR: Cannot display binary file, please open a text file only!" return "FILE ERROR: Cannot display binary file, please open a text file only!"
if truncate == 0: if not truncate:
return open(realfile, 'r').read() return open(realfile, 'r').read()
else: else:
tail(open(realfile, 'r'), 0) return tail(open(realfile, 'r'), 0)
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: set et sts=2:
# pylint: disable-msg=W0311,C0301,C0103,C0111
import slapos.slap
import time
import subprocess
import os import os
import re import re
import urllib
from flask import jsonify
import shutil import shutil
import string
from git import *
class Popen(subprocess.Popen): from git import Repo
def __init__(self, *args, **kwargs): from flask import jsonify
kwargs['stdin'] = subprocess.PIPE
kwargs['stderr'] = subprocess.STDOUT
kwargs.setdefault('stdout', subprocess.PIPE)
kwargs.setdefault('close_fds', True)
subprocess.Popen.__init__(self, *args, **kwargs)
self.stdin.flush()
self.stdin.close()
self.stdin = None
def cloneRepo(data): def cloneRepo(data):
"""Clonne a repository """Clonne a repository
...@@ -49,7 +38,7 @@ def cloneRepo(data): ...@@ -49,7 +38,7 @@ def cloneRepo(data):
if data["email"] != "": if data["email"] != "":
config_writer.set_value("user", "email", data["email"]) config_writer.set_value("user", "email", data["email"])
code = 1 code = 1
except Exception, e: except Exception as e:
json = safeResult(str(e)) json = safeResult(str(e))
if os.path.exists(workDir): if os.path.exists(workDir):
shutil.rmtree(workDir) shutil.rmtree(workDir)
...@@ -70,7 +59,7 @@ def gitStatus(project): ...@@ -70,7 +59,7 @@ def gitStatus(project):
branch = git.branch().replace(' ', '').split('\n') branch = git.branch().replace(' ', '').split('\n')
isdirty = repo.is_dirty(untracked_files=True) isdirty = repo.is_dirty(untracked_files=True)
code = 1 code = 1
except Exception, e: except Exception as e:
json = safeResult(str(e)) json = safeResult(str(e))
return jsonify(code=code, result=json, branch=branch, dirty=isdirty) return jsonify(code=code, result=json, branch=branch, dirty=isdirty)
...@@ -85,7 +74,6 @@ def switchBranch(project, name): ...@@ -85,7 +74,6 @@ def switchBranch(project, name):
json = "" json = ""
try: try:
repo = Repo(project) repo = Repo(project)
branches = repo.branches
current_branch = repo.active_branch.name current_branch = repo.active_branch.name
if name == current_branch: if name == current_branch:
json = "This is already your active branch for this project" json = "This is already your active branch for this project"
...@@ -93,7 +81,7 @@ def switchBranch(project, name): ...@@ -93,7 +81,7 @@ def switchBranch(project, name):
git = repo.git git = repo.git
git.checkout(name) git.checkout(name)
code = 1 code = 1
except Exception, e: except Exception as e:
json = safeResult(str(e)) json = safeResult(str(e))
return jsonify(code=code, result=json) return jsonify(code=code, result=json)
...@@ -115,7 +103,7 @@ def addBranch(project, name, onlyCheckout=False): ...@@ -115,7 +103,7 @@ def addBranch(project, name, onlyCheckout=False):
else: else:
git.checkout(name) git.checkout(name)
code = 1 code = 1
except Exception, e: except Exception as e:
json = safeResult(str(e)) json = safeResult(str(e))
return jsonify(code=code, result=json) return jsonify(code=code, result=json)
...@@ -127,7 +115,7 @@ def getDiff(project): ...@@ -127,7 +115,7 @@ def getDiff(project):
git = repo.git git = repo.git
current_branch = repo.active_branch.name current_branch = repo.active_branch.name
result = git.diff(current_branch) result = git.diff(current_branch)
except Exception, e: except Exception as e:
result = safeResult(str(e)) result = safeResult(str(e))
return result return result
...@@ -157,7 +145,7 @@ def gitPush(project, msg): ...@@ -157,7 +145,7 @@ def gitPush(project, msg):
else: else:
json = "Nothing to be commited" json = "Nothing to be commited"
code = 1 code = 1
except Exception, e: except Exception as e:
if undo_commit: if undo_commit:
git.reset("HEAD~") #undo previous commit git.reset("HEAD~") #undo previous commit
json = safeResult(str(e)) json = safeResult(str(e))
...@@ -169,14 +157,13 @@ def gitPull(project): ...@@ -169,14 +157,13 @@ def gitPull(project):
try: try:
repo = Repo(project) repo = Repo(project)
git = repo.git git = repo.git
current_branch = repo.active_branch.name
git.pull() git.pull()
code = 1 code = 1
except Exception, e: except Exception as e:
result = safeResult(str(e)) result = safeResult(str(e))
return jsonify(code=code, result=result) return jsonify(code=code, result=result)
def safeResult(result): def safeResult(result):
"""Parse string and remove credential of the user""" """Parse string and remove credential of the user"""
regex=re.compile("(https:\/\/)([\w\d\._-]+:[\w\d\._-]+)\@([\S]+\s)", re.VERBOSE) regex = re.compile("(https:\/\/)([\w\d\._-]+:[\w\d\._-]+)\@([\S]+\s)", re.VERBOSE)
return regex.sub(r'\1\3', result) return regex.sub(r'\1\3', result)
\ No newline at end of file
import os
import psutil
import signal
import subprocess
import sys
SLAPRUNNER_PROCESS_LIST = []
class Popen(subprocess.Popen):
"""
Extension of Popen to launch and kill process in a clean way
"""
def __init__(self, *args, **kwargs):
"""
Launch process and add object to process list for handler
"""
self.name = kwargs.pop('name', None)
kwargs['stdin'] = subprocess.PIPE
kwargs['stderr'] = subprocess.STDOUT
kwargs.setdefault('stdout', subprocess.PIPE)
kwargs.setdefault('close_fds', True)
subprocess.Popen.__init__(self, *args, **kwargs)
SLAPRUNNER_PROCESS_LIST.append(self)
self.stdin.flush()
self.stdin.close()
self.stdin = None
def kill(self, sig=signal.SIGTERM, recursive=False):
"""
Kill process and all its descendant if recursive
"""
if self.poll() is None:
if recursive:
childs_pids = pidppid(self.pid)
for pid in childs_pids:
killNoFail(pid, sig)
killNoFail(self.pid, sig)
if self.poll() is not None:
SLAPRUNNER_PROCESS_LIST.remove(self)
def __del__(self):
"""
Del function, try to kill process group
and process if its group does not exist
"""
for pid in (-self.pid, self.pid):
try:
os.kill(-self.pid, 15)
except OSError:
pass
subprocess.Popen.__del__(self)
def pidppid(pid, recursive=True):
"""
Return a list of all children of pid
"""
return [p.pid for p in psutil.Process(pid).get_children(recursive=recursive)]
def killNoFail(pid, sig):
"""
function to kill without failing. Return True if kill do not fail
"""
try:
os.kill(pid, sig)
return True
except OSError:
return False
def isRunning(name):
"""
Return True if a process with this name is running
"""
for process in SLAPRUNNER_PROCESS_LIST:
if process.name == name:
if process.poll() is None:
return True
return False
def killRunningProcess(name, recursive=False):
"""
Kill all process with name
"""
for process in SLAPRUNNER_PROCESS_LIST:
if process.name == name:
process.kill(recursive=recursive)
def handler(sig, frame):
"""
Signal handler to kill all process
"""
pid = os.getpid()
os.kill(-pid, sig)
sys.exit()
def setHandler(sig_list=None):
if sig_list is None:
sig_list = [signal.SIGTERM]
for sig in sig_list:
signal.signal(sig, handler)
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os # vim: set et sts=2:
import sys # pylint: disable-msg=W0311,C0301,C0103,C0111,R0904
import views
import unittest import argparse
import tempfile
from optparse import OptionParser, Option
import ConfigParser import ConfigParser
import shutil import datetime
from gittools import cloneRepo, gitStatus, switchBranch, addBranch, getDiff, \
gitPush, gitPull
from flaskext.auth import Auth, AuthUser, login_required, logout
from utils import *
import json import json
from datetime import timedelta import os
import shutil
import time
import unittest
import hashlib
from slapos.runner.utils import (getProfilePath, getSession, isInstanceRunning,
isSoftwareRunning, startProxy)
from slapos.runner.process import killRunningProcess, isRunning
from slapos.runner import views
import slapos.slap
#Helpers
def loadJson(response):
return json.loads(response.data)
class Config: class Config:
def __init__(self):
self.runner_workdir = None
self.software_root = None
self.instance_root = None
self.configuration_file_path = None
def setConfig(self): def setConfig(self):
""" """
Set options given by parameters. Set options given by parameters.
...@@ -41,22 +56,33 @@ class SlaprunnerTestCase(unittest.TestCase): ...@@ -41,22 +56,33 @@ class SlaprunnerTestCase(unittest.TestCase):
self.users = ["slapuser", "slappwd", "slaprunner@nexedi.com", "SlapOS web runner"] self.users = ["slapuser", "slappwd", "slaprunner@nexedi.com", "SlapOS web runner"]
self.updateUser = ["newslapuser", "newslappwd", "slaprunner@nexedi.com", "SlapOS web runner"] self.updateUser = ["newslapuser", "newslappwd", "slaprunner@nexedi.com", "SlapOS web runner"]
self.rcode = "41bf2657" self.rcode = "41bf2657"
self.repo = 'http://git.erp5.org/repos/slapos.git'
self.software = "workspace/slapos/software/" #relative directory fo SR
self.project = 'slapos' #Default project name
self.template = 'template.cfg'
self.partitionPrefix = 'slappart'
self.slaposBuildout = "1.6.0-dev-SlapOS-010"
#create slaprunner configuration #create slaprunner configuration
config = Config() config = Config()
config.setConfig() config.setConfig()
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')
views.app.config.update(**config.__dict__) views.app.config.update(**config.__dict__)
#update or create all runner base directory to test_dir #update or create all runner base directory to test_dir
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)
views.app.config.update( views.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="123456",
PERMANENT_SESSION_LIFETIME=timedelta(days=31), PERMANENT_SESSION_LIFETIME=datetime.timedelta(days=31),
) )
self.app = views.app.test_client() self.app = views.app.test_client()
self.app.config = views.app.config self.app.config = views.app.config
...@@ -69,46 +95,28 @@ class SlaprunnerTestCase(unittest.TestCase): ...@@ -69,46 +95,28 @@ class SlaprunnerTestCase(unittest.TestCase):
"""Remove all test data""" """Remove all test data"""
os.unlink(os.path.join(self.app.config['etc_dir'], '.rcode')) os.unlink(os.path.join(self.app.config['etc_dir'], '.rcode'))
project = os.path.join(self.app.config['etc_dir'], '.project') project = os.path.join(self.app.config['etc_dir'], '.project')
sr_data = project = os.path.join(self.app.config['etc_dir'], '.softdata')
proxy = os.path.join(self.app.config['etc_dir'], '.proxy.pid')
slapgrid_cp = os.path.join(self.app.config['etc_dir'], '.slapgrid-cp.pid')
slapgrid_sr = os.path.join(self.app.config['etc_dir'], '.slapgrid-sr.pid')
users = os.path.join(self.app.config['etc_dir'], '.users') users = os.path.join(self.app.config['etc_dir'], '.users')
if os.path.exists(users): if os.path.exists(users):
os.unlink(users) os.unlink(users)
if os.path.exists(project): if os.path.exists(project):
os.unlink(project) os.unlink(project)
if os.path.exists(sr_data):
os.unlink(sr_data)
if os.path.exists(proxy):
os.unlink(proxy)
if os.path.exists(slapgrid_cp):
os.unlink(slapgrid_cp)
if os.path.exists(slapgrid_sr):
os.unlink(slapgrid_sr)
if os.path.exists(self.app.config['workspace']): if os.path.exists(self.app.config['workspace']):
shutil.rmtree(self.app.config['workspace']) shutil.rmtree(self.app.config['workspace'])
if os.path.exists(self.app.config['software_root']): if os.path.exists(self.app.config['software_root']):
shutil.rmtree(self.app.config['software_root']) shutil.rmtree(self.app.config['software_root'])
if os.path.exists(self.app.config['instance_root']): if os.path.exists(self.app.config['instance_root']):
shutil.rmtree(self.app.config['instance_root']) shutil.rmtree(self.app.config['instance_root'])
if os.path.exists(self.app.config['software_link']):
shutil.rmtree(self.app.config['software_link'])
self.logout()
#Stop process
killRunningProcess('slapproxy', recursive=True)
killRunningProcess('slapgrid-cp', recursive=True)
killRunningProcess('slapgrid-sr', recursive=True)
#Helpers
def loadJson(self, response):
return json.loads(response.data)
def configAccount(self, username, password, email, name, rcode):
"""Helper for configAccoun"""
return self.app.post('/configAccount', data=dict(
username=username,
password=password,
email=email,
name=name,
rcode=rcode
), follow_redirects=True)
def configAccount(self, username, password, email, name, rcode): def configAccount(self, username, password, email, name, rcode):
"""Helper for configAccoun""" """Helper for configAccount"""
return self.app.post('/configAccount', data=dict( return self.app.post('/configAccount', data=dict(
username=username, username=username,
password=password, password=password,
...@@ -126,9 +134,9 @@ class SlaprunnerTestCase(unittest.TestCase): ...@@ -126,9 +134,9 @@ class SlaprunnerTestCase(unittest.TestCase):
def setAccount(self): def setAccount(self):
"""Initialize user account and log user in""" """Initialize user account and log user in"""
response = self.loadJson(self.configAccount(self.users[0], self.users[1], response = loadJson(self.configAccount(self.users[0], self.users[1],
self.users[2], self.users[3], self.rcode)) self.users[2], self.users[3], self.rcode))
response2 = self.loadJson(self.login(self.users[0], self.users[1])) response2 = loadJson(self.login(self.users[0], self.users[1]))
self.assertEqual(response['result'], "") self.assertEqual(response['result'], "")
self.assertEqual(response2['result'], "") self.assertEqual(response2['result'], "")
...@@ -146,6 +154,60 @@ class SlaprunnerTestCase(unittest.TestCase): ...@@ -146,6 +154,60 @@ class SlaprunnerTestCase(unittest.TestCase):
rcode=rcode rcode=rcode
), follow_redirects=True) ), follow_redirects=True)
def getCurrentSR(self):
return getProfilePath(self.app.config['etc_dir'],
self.app.config['software_profile'])
def proxyStatus(self, status=True, sleep_time=0):
"""Helper for testslapproxy status"""
proxy = isRunning('slapproxy')
if proxy != status and sleep_time != 0:
time.sleep(sleep_time)
proxy = isRunning('slapproxy')
self.assertEqual(proxy, status)
def setupProjectFolder(self, withSoftware=False):
"""Helper for create a project folder as for slapos.git"""
base = os.path.join(self.app.config['workspace'], 'slapos')
software = os.path.join(base, 'software')
os.mkdir(base)
os.mkdir(software)
if withSoftware:
testSoftware = os.path.join(software, 'slaprunner-test')
sr = "[buildout]\n\n"
sr += "parts = command\n\nunzip = true\nnetworkcache-section = networkcache\n\n"
sr += "find-links += http://www.nexedi.org/static/packages/source/slapos.buildout/\n\n"
sr += "[networkcache]\ndownload-cache-url = http://www.shacache.org/shacache"
sr += "\ndownload-dir-url = http://www.shacache.org/shadir\n\n"
sr += "[command]\nrecipe = zc.recipe.egg\neggs = plone.recipe.command\n\n"
sr += "[versions]\nzc.buildout = %s\n" % self.slaposBuildout
os.mkdir(testSoftware)
open(os.path.join(testSoftware, self.app.config['software_profile']),
'w').write(sr)
def setupSoftwareFolder(self):
"""Helper for setup compiled software release dir"""
self.setupProjectFolder(withSoftware=True)
md5 = hashlib.md5(os.path.join(self.app.config['workspace'],
"slapos/software/slaprunner-test", self.app.config['software_profile'])
).hexdigest()
base = os.path.join(self.app.config['software_root'], md5)
template = os.path.join(base, self.template)
content = "[buildout]\n"
content += "parts = \n create-file\n\n"
content += "eggs-directory = %s\n" % os.path.join(base, 'eggs')
content += "develop-eggs-directory = %s\n\n" % os.path.join(base, 'develop-eggs')
content += "[create-file]\nrecipe = plone.recipe.command\n"
content += "filename = ${buildout:directory}/etc\n"
content += "command = mkdir ${:filename} && echo 'simple file' > ${:filename}/testfile\n"
os.mkdir(self.app.config['software_root'])
os.mkdir(base)
open(template, "w").write(content)
def stopSlapproxy(self):
"""Kill slapproxy process"""
killRunningProcess('slapproxy', recursive=True)
#Begin test case here #Begin test case here
def test_wrong_login(self): def test_wrong_login(self):
...@@ -158,22 +220,22 @@ class SlaprunnerTestCase(unittest.TestCase): ...@@ -158,22 +220,22 @@ class SlaprunnerTestCase(unittest.TestCase):
"""For the first lauch of slaprunner user need do create first account""" """For the first lauch of slaprunner user need do create first account"""
result = self.configAccount(self.users[0], self.users[1], self.users[2], result = self.configAccount(self.users[0], self.users[1], self.users[2],
self.users[3], self.rcode) self.users[3], self.rcode)
response = self.loadJson(result) response = loadJson(result)
self.assertEqual(response['code'], 1) self.assertEqual(response['code'], 1)
account = getSession(self.app.config) account = getSession(self.app.config)
self.assertEqual(account, self.users) self.assertEqual(account, self.users)
def test_login_logout(self): def test_login_logout(self):
"""test login with good and wrong values, test logout""" """test login with good and wrong values, test logout"""
response = self.loadJson(self.configAccount(self.users[0], self.users[1], response = loadJson(self.configAccount(self.users[0], self.users[1],
self.users[2], self.users[3], self.rcode)) self.users[2], self.users[3], self.rcode))
self.assertEqual(response['result'], "") self.assertEqual(response['result'], "")
result = self.loadJson(self.login(self.users[0], "wrongpwd")) result = loadJson(self.login(self.users[0], "wrongpwd"))
self.assertEqual(result['result'], "Login or password is incorrect, please check it!") self.assertEqual(result['result'], "Login or password is incorrect, please check it!")
resultwr = self.loadJson(self.login("wronglogin", "wrongpwd")) resultwr = loadJson(self.login("wronglogin", "wrongpwd"))
self.assertEqual(resultwr['result'], "Login or password is incorrect, please check it!") self.assertEqual(resultwr['result'], "Login or password is incorrect, please check it!")
#try now with true values #try now with true values
resultlg = self.loadJson(self.login(self.users[0], self.users[1])) resultlg = loadJson(self.login(self.users[0], self.users[1]))
self.assertEqual(resultlg['result'], "") self.assertEqual(resultlg['result'], "")
#after login test logout #after login test logout
result = self.logout() result = self.logout()
...@@ -182,21 +244,206 @@ class SlaprunnerTestCase(unittest.TestCase): ...@@ -182,21 +244,206 @@ class SlaprunnerTestCase(unittest.TestCase):
def test_updateAccount(self): def test_updateAccount(self):
"""test Update accound, this need user to loging in""" """test Update accound, this need user to loging in"""
self.setAccount() self.setAccount()
response = self.loadJson(self.updateAccount(self.updateUser, self.rcode)) response = loadJson(self.updateAccount(self.updateUser, self.rcode))
self.assertEqual(response['code'], 1) self.assertEqual(response['code'], 1)
result = self.logout() result = self.logout()
assert "<h2>Login to Slapos Web Runner</h2>" in result.data assert "<h2>Login to Slapos Web Runner</h2>" in result.data
#retry login with new values #retry login with new values
response = self.loadJson(self.login(self.updateUser[0], self.updateUser[1])) response = loadJson(self.login(self.updateUser[0], self.updateUser[1]))
self.assertEqual(response['result'], "") self.assertEqual(response['result'], "")
#log out now! #log out now!
self.logout() self.logout()
def test_startProxy(self):
"""Test slapproxy"""
self.proxyStatus(False)
startProxy(self.app.config)
self.proxyStatus(True)
self.stopSlapproxy()
self.proxyStatus(False, sleep_time=1)
def test_cloneProject(self):
"""Start scenario 1 for deploying SR: Clone a project from git repository"""
self.setAccount()
folder = 'workspace/' + self.project
data = {"repo":self.repo, "user":'Slaprunner test',
"email":'slaprunner@nexedi.com', "name":folder}
response = loadJson(self.app.post('/cloneRepository', data=data,
follow_redirects=True))
self.assertEqual(response['result'], "")
#Get realpath of create project
path_data = dict(file=folder)
response = loadJson(self.app.post('/getPath', data=path_data,
follow_redirects=True))
self.assertEqual(response['code'], 1)
realFolder = response['result'].split('#')[0]
#Check git configuration
config = open(os.path.join(realFolder, '.git/config'), 'r').read()
assert "slaprunner@nexedi.com" in config and "Slaprunner test" in config
#Checkout to slaprunner branch, this supose that branch slaprunner exit
response = loadJson(self.app.post('/newBranch', data=dict(
project=folder,
create='0',
name='slaprunner'),
follow_redirects=True))
self.assertEqual(response['result'], "")
self.logout()
def test_createSR(self):
"""Scenario 2: Create a new software release"""
self.setAccount()
#setup project directory
self.setupProjectFolder()
newSoftware = os.path.join(self.software, 'slaprunner-test')
response = loadJson(self.app.post('/createSoftware',
data=dict(folder=newSoftware),
follow_redirects=True))
self.assertEqual(response['result'], "")
currentSR = self.getCurrentSR()
assert newSoftware in currentSR
self.logout()
def test_openSR(self):
"""Scenario 3: Open software release"""
self.test_cloneProject()
#Login
self.login(self.users[0], self.users[1])
software = os.path.join(self.software, 'drupal') #Drupal SR must exist in SR folder
response = loadJson(self.app.post('/setCurrentProject',
data=dict(path=software),
follow_redirects=True))
self.assertEqual(response['result'], "")
currentSR = self.getCurrentSR()
assert software in currentSR
self.assertFalse(isInstanceRunning(self.app.config))
self.assertFalse(isSoftwareRunning(self.app.config))
#Slapproxy process is supose to be started
#newSoftware = os.path.join(self.software, 'slaprunner-test')
self.proxyStatus(True)
self.stopSlapproxy()
self.logout()
def test_runSoftware(self):
"""Scenario 4: CReate empty SR and save software.cfg file
then run slapgrid-sr
"""
#Call config account
#call create software Release
self.test_createSR()
#Login
self.login(self.users[0], self.users[1])
newSoftware = self.getCurrentSR()
softwareRelease = "[buildout]\n\nparts =\n test-application\n"
softwareRelease += "#Test download git web repos éè@: utf-8 caracters\n"
softwareRelease += "[test-application]\nrecipe = hexagonit.recipe.download\n"
softwareRelease += "url = http://git.erp5.org/gitweb/slapos.git\n"
softwareRelease += "filename = slapos.git\n"
softwareRelease += "download-only = true\n"
response = loadJson(self.app.post('/saveFileContent',
data=dict(file=newSoftware,
content=softwareRelease),
follow_redirects=True))
self.assertEqual(response['result'], "")
#Compile software and wait until slapgrid it end
#this is supose to use curent SR
response = loadJson(self.app.post('/runSoftwareProfile',
data=dict(),
follow_redirects=True))
self.assertTrue(response['result'])
self.assertTrue(os.path.exists(self.app.config['software_root']))
self.assertTrue(os.path.exists(self.app.config['software_log']))
assert "test-application" in open(self.app.config['software_log'], 'r').read()
sr_dir = os.listdir(self.app.config['software_root'])
self.assertEqual(len(sr_dir), 1)
createdFile = os.path.join(self.app.config['software_root'], sr_dir[0],
'parts', 'test-application', 'slapos.git')
self.assertTrue(os.path.exists(createdFile))
self.proxyStatus(True)
self.stopSlapproxy()
self.logout()
def test_updateInstanceParameter(self):
"""Scenarion 5: Update parameters of current sofware profile"""
self.setAccount()
self.setupSoftwareFolder()
#Set current projet and run Slapgrid-cp
software = os.path.join(self.software, 'slaprunner-test')
response = loadJson(self.app.post('/setCurrentProject',
data=dict(path=software),
follow_redirects=True))
self.assertEqual(response['result'], "")
self.proxyStatus(True)
#Send paramters for the instance
parameterDict = dict(appname='slaprunnerTest', cacountry='France')
parameterXml = '<?xml version="1.0" encoding="utf-8"?>\n<instance>'
parameterXml += '<parameter id="appname">slaprunnerTest</parameter>\n'
parameterXml += '<parameter id="cacountry">France</parameter>\n</instance>'
software_type = 'production'
response = loadJson(self.app.post('/saveParameterXml',
data=dict(parameter=parameterXml,
software_type=software_type),
follow_redirects=True))
self.assertEqual(response['result'], "")
slap = slapos.slap.slap()
slap.initializeConnection(self.app.config['master_url'])
computer = slap.registerComputer(self.app.config['computer_id'])
partitionList = computer.getComputerPartitionList()
self.assertNotEqual(partitionList, [])
#Assume that the requested partition is partition 0
slapParameterDict = partitionList[0].getInstanceParameterDict()
self.assertTrue(slapParameterDict.has_key('appname'))
self.assertTrue(slapParameterDict.has_key('cacountry'))
self.assertEqual(slapParameterDict['appname'], 'slaprunnerTest')
self.assertEqual(slapParameterDict['cacountry'], 'France')
self.assertEqual(slapParameterDict['slap_software_type'], 'production')
#test getParameterXml for webrunner UI
response = loadJson(self.app.get('/getParameterXml/xml'))
self.assertEqual(parameterXml, response['result'])
response = loadJson(self.app.get('/getParameterXml/dict'))
self.assertEqual(parameterDict, response['result']['instance'])
self.stopSlapproxy()
self.logout()
def test_requestInstance(self):
"""Scenarion 6: request software instance"""
self.test_updateInstanceParameter()
#Login
self.login(self.users[0], self.users[1])
self.proxyStatus(False, sleep_time=1)
#run Software profile
response = loadJson(self.app.post('/runSoftwareProfile',
data=dict(),
follow_redirects=True))
self.assertTrue(response['result'])
#run instance profile
response = loadJson(self.app.post('/runInstanceProfile',
data=dict(),
follow_redirects=True))
self.assertTrue(response['result'])
#Check that all partitions has been created
assert "create-file" in open(self.app.config['instance_log'], 'r').read()
instanceDir = os.listdir(self.app.config['instance_root'])
for num in range(int(self.app.config['partition_amount'])):
partition = os.path.join(self.app.config['instance_root'],
self.partitionPrefix + str(num))
self.assertTrue(os.path.exists(partition))
#Go to partition 0
instancePath = os.path.join(self.app.config['instance_root'],
self.partitionPrefix + '0')
createdFile = os.path.join(instancePath, 'etc', 'testfile')
self.assertTrue(os.path.exists(createdFile))
assert 'simple file' in open(createdFile).read()
self.proxyStatus(True)
self.stopSlapproxy()
self.logout()
def main(): def main():
argv = ['', 'test_wrong_login', 'test_configAccount', # Empty parser for now - so that erp5testnode is happy when doing --help
'test_login_logout', 'test_updateAccount'] parser = argparse.ArgumentParser()
unittest.main(module=SlaprunnerTestCase, argv=argv) parser.parse_args()
unittest.main(module=__name__)
if __name__ == '__main__': if __name__ == '__main__':
main() main()
\ No newline at end of file
UL.jqueryFileTree { UL.jqueryFileTree {
font-family: Verdana, sans-serif; font-family: Verdana, sans-serif;
font-size: 12px; font-size: 12px;
line-height: 18px; line-height: 18px;
padding: 0px; padding: 0px;
...@@ -60,6 +60,7 @@ UL.jqueryFileTree A:hover { ...@@ -60,6 +60,7 @@ UL.jqueryFileTree A:hover {
background-color: white; background-color: white;
border: 1px solid #BBBBBB; border: 1px solid #BBBBBB;
} }
div.browser div.gs_dir_content_files{min-height:330px;}
#curDir { #curDir {
height: 30px; height: 30px;
...@@ -124,7 +125,7 @@ UL.jqueryFileTree A:hover { ...@@ -124,7 +125,7 @@ UL.jqueryFileTree A:hover {
font-weight: bold; font-weight: bold;
} }
.gs_head{padding: 10px 5px 10px 0;} .gs_head{padding: 10px 5px 10px 0;}
.gs_title{padding-left: 10px; margin:5px 5px 0 0; background: #e4e4e4;} .gs_title{padding-left: 10px; margin:5px 5px 0 0; background: #e4e4e4; height:30px;}
.rowSelected { .rowSelected {
color: #FFF; color: #FFF;
background-color: #c2c2c2; background-color: #c2c2c2;
...@@ -133,6 +134,7 @@ UL.jqueryFileTree A:hover { ...@@ -133,6 +134,7 @@ UL.jqueryFileTree A:hover {
.rowSelected a { .rowSelected a {
color: #FFF; color: #FFF;
} }
.pathlink {cursor: pointer; font-size: 13px; margin-right: 2px; margin-left: 2px;}
.gs_delimiter { .gs_delimiter {
height: 16px; height: 16px;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
background: #e4e4e4; background: #e4e4e4;
padding:3px; padding:3px;
/*position:relative;*/ /*position:relative;*/
width:757px; width:930px;
font-size: 14px; font-size: 14px;
border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0;
} }
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#tabContaier textarea { #tabContaier textarea {
width:702px; width:702px;
} }
#tabContaier textarea.slap{white-space: pre-wrap;word-wrap: break-word;overflow: hidden;color: #6F6F6F;width:430px; max-height:120px; #tabContaier textarea.slap{white-space: pre-wrap;word-wrap: break-word;overflow: hidden;color: #6F6F6F;width:616px; max-height:120px;
resize: none; height:18px;padding:3px;min-height:18px;font-size: 13px;} resize: none; height:18px;padding:3px;min-height:18px;font-size: 13px;}
#tabContaier textarea.mb_style{width:560px;} #tabContaier textarea.mb_style{width:713px;}
#tabContaier > ul{ #tabContaier > ul{
overflow:hidden; overflow:hidden;
height:34px; height:34px;
......
...@@ -28,7 +28,7 @@ td{ ...@@ -28,7 +28,7 @@ td{
border-right: 1px solid #A8A8A8; border-right: 1px solid #A8A8A8;
} }
td.propertie{padding-left:10px; color:blue;width: 178px;} td.propertie{padding-left:10px; color:blue;width: 178px;}
.slapvalues{display:block;width: 375px;word-wrap: break-word} .slapvalues{display:block;width: 522px;word-wrap: break-word}
td.first{border-left: 1px solid #A8A8A8;} td.first{border-left: 1px solid #A8A8A8;}
th{ th{
background: #2281C1; background: #2281C1;
...@@ -39,7 +39,7 @@ th{ ...@@ -39,7 +39,7 @@ th{
} }
table.small th{padding: 4px;font-size: 16px;} table.small th{padding: 4px;font-size: 16px;}
textarea { textarea {
width:762px; width:932px;
font-family: 'Helvetica Neue',Tahoma,Helvetica,Arial,sans-serif; font-family: 'Helvetica Neue',Tahoma,Helvetica,Arial,sans-serif;
} }
...@@ -54,8 +54,8 @@ overflow-y: scroll; ...@@ -54,8 +54,8 @@ overflow-y: scroll;
#page #page
{ {
margin: 20px auto; margin: 10px auto;
width: 841px; width: 1014px;
} }
#logo{ #logo{
...@@ -64,8 +64,8 @@ overflow-y: scroll; ...@@ -64,8 +64,8 @@ overflow-y: scroll;
#header{ #header{
height: 78px; height: 78px;
padding-top: 15px; padding-top: 12px;
width: 847px; width: 1014px;
background: url(../images/head.png) no-repeat; background: url(../images/head.png) no-repeat;
} }
...@@ -86,7 +86,7 @@ overflow-y: scroll; ...@@ -86,7 +86,7 @@ overflow-y: scroll;
font-weight: normal; font-weight: normal;
padding-top: 3px; padding-top: 3px;
float: left; float: left;
width: 656px; width: 820px;
height: 22px; height: 22px;
text-align: center; text-align: center;
color: #4c6172; color: #4c6172;
...@@ -114,16 +114,12 @@ overflow-y: scroll; ...@@ -114,16 +114,12 @@ overflow-y: scroll;
} }
.wmenu{ .wmenu{
margin: 1px 0 1px 20px;
} }
.wmenu ul{ .wmenu ul{
list-style:none; height: 34px;
margin:0; overflow:hidden;
margin-top:1px;
padding:0;
margin-left:20px;
height: 36px;
} }
.space{ .space{
...@@ -132,7 +128,6 @@ overflow-y: scroll; ...@@ -132,7 +128,6 @@ overflow-y: scroll;
.wmenu li{ .wmenu li{
float:left; float:left;
background: url(../images/sep.png) left center no-repeat;
} }
.wmenu li .title_software{ .wmenu li .title_software{
...@@ -146,7 +141,7 @@ overflow-y: scroll; ...@@ -146,7 +141,7 @@ overflow-y: scroll;
padding-left: 20px; padding-left: 20px;
padding-right: 5px; padding-right: 5px;
margin-left:4px; margin-left:4px;
height: 20px; height: 18px;
text-shadow:1px 1px 0 #E6EDF2; text-shadow:1px 1px 0 #E6EDF2;
} }
...@@ -165,20 +160,23 @@ overflow-y: scroll; ...@@ -165,20 +160,23 @@ overflow-y: scroll;
text-shadow:1px 1px 0 #E6EDF2; text-shadow:1px 1px 0 #E6EDF2;
} }
.wmenu ul li.sep{border-right: 1px solid #c2c2c2; min-width:20px; height:34px}
.wmenu ul li a{ .wmenu ul li a{
display:block; display:block;
height: 20px; height: 20px;
Color:#000; Color:#275777;
font-size:14px; /*background: url(../images/sep.png) right center no-repeat;*/
border-right: 1px solid #c2c2c2;
/*font-weight:bold;*/
font-size:15px;
text-decoration:none; text-decoration:none;
padding:8px; padding:7px 10px 7px 10px;
padding-left: 6px;
} }
.wmenu ul li:last-child a {border: none}
.wmenu ul li a:hover, .wmenu ul li a.active{ .wmenu ul li a:hover, .wmenu ul li a.active{
color:#0271BF; color: #000;/*#0271BF;*/
background:url(../images/menu_hover.png) bottom repeat-x; background:#c2c2c2;
} }
#main #main
...@@ -191,7 +189,7 @@ overflow-y: scroll; ...@@ -191,7 +189,7 @@ overflow-y: scroll;
.main_content{ .main_content{
position:relative; position:relative;
width: 100%; width: 99.6%;
height: 430px; height: 430px;
margin-top:10px; margin-top:10px;
border:1px solid #4c6172; border:1px solid #4c6172;
...@@ -201,12 +199,12 @@ overflow-y: scroll; ...@@ -201,12 +199,12 @@ overflow-y: scroll;
.main_head{ .main_head{
height: 15px; height: 15px;
background: url(../images/main_top.png) no-repeat; background: url(../images/main_top.png) no-repeat;
width: 794px; width: 966px;
} }
.content{ .content{
background: url(../images/content.png) repeat-y; background: url(../images/content.png) repeat-y;
width: 764px; width: 936px;
padding: 15px; padding: 15px;
padding-top:0; padding-top:0;
padding-bottom:0; padding-bottom:0;
...@@ -229,16 +227,16 @@ overflow-y: scroll; ...@@ -229,16 +227,16 @@ overflow-y: scroll;
.main_foot{ .main_foot{
height: 15px; height: 15px;
background: url(../images/main_bottom.png) no-repeat; background: url(../images/main_bottom.png) no-repeat;
width: 794px; width: 966px;
} }
#footer{ #footer{
height: 35px; height: 35px;
width: 767px; width: 934px;
background: url(../images/footer_bg.png) no-repeat; background: url(../images/footer_bg.png) no-repeat;
padding-left: 40px; padding-left: 40px;
padding-right: 40px; padding-right: 40px;
padding-top: 5px; padding-top: 4px;
text-align: center; text-align: center;
color: #4c6172; color: #4c6172;
text-shadow: 0px 1px 1px #fff; text-shadow: 0px 1px 1px #fff;
...@@ -319,7 +317,8 @@ input[type="radio"], input[type="checkbox"]{ ...@@ -319,7 +317,8 @@ input[type="radio"], input[type="checkbox"]{
border: 2px solid #87B0D4; border: 2px solid #87B0D4;
padding: 0; padding: 0;
color: #4c6172; color: #4c6172;
margin: 15px 59px 15px 59px; margin: 20px auto;
width: 641px;
} }
#home_box a{ #home_box a{
...@@ -369,14 +368,14 @@ input[type="radio"], input[type="checkbox"]{ ...@@ -369,14 +368,14 @@ input[type="radio"], input[type="checkbox"]{
.lmenu{ .lmenu{
display: block; display: block;
height: 80px; height: 80px;
margin: 10px 45px 10px 45px; margin: 10px 0 10px 45px;
padding: 10px; padding: 10px;
padding-bottom:15px; padding-bottom:15px;
width: 530px; width: 530px;
border: 1px solid #678dad; border: 1px solid #678dad;
} }
.smaller{margin-left:10px; width: 350px; float:right} .smaller{margin-left:10px; width: 350px; float:left}
.smaller p{width: 280px;} .smaller p{width: 280px;}
.umenu{display: block;margin: 10px 0 10px 45px; width: 147px; float:left;border: 1px solid #678dad; .umenu{display: block;margin: 10px 0 10px 45px; width: 147px; float:left;border: 1px solid #678dad;
padding: 10px;height: 80px;padding-bottom:15px;} padding: 10px;height: 80px;padding-bottom:15px;}
...@@ -398,7 +397,6 @@ padding: 10px;height: 80px;padding-bottom:15px;} ...@@ -398,7 +397,6 @@ padding: 10px;height: 80px;padding-bottom:15px;}
.sright_menu{ .sright_menu{
display: block; display: block;
height: 80px; height: 80px;
margin: 0 45px 0 0;
padding: 10px; padding: 10px;
padding-bottom:15px; padding-bottom:15px;
border: #678dad; border: #678dad;
...@@ -415,7 +413,7 @@ padding: 10px;height: 80px;padding-bottom:15px;} ...@@ -415,7 +413,7 @@ padding: 10px;height: 80px;padding-bottom:15px;}
} }
.file_tree { .file_tree {
width: 752px; width: 923px;
height: 300px; height: 300px;
border: solid 1px #678dad; border: solid 1px #678dad;
background: #fff; background: #fff;
...@@ -433,28 +431,30 @@ padding: 10px;height: 80px;padding-bottom:15px;} ...@@ -433,28 +431,30 @@ padding: 10px;height: 80px;padding-bottom:15px;}
} }
.file_tree_short{ .file_tree_short{
width: 352px; width: 228px;
height: 170px; height: 379px;
border: solid 1px #678dad; border: solid 1px #678dad;
background: #fff; background: #fff;
overflow: auto; overflow: auto;
padding: 5px; padding: 5px;
float:left;
} }
.box_software{ .box_software{
width: 362px; width: 240px;
height: 100px;
background: #fff; background: #fff;
padding: 5px;
float:right;
} }
.software_details{float: left;}
#details_box{ #details_box{
display:none; display:block;
margin-top:10px;
} }
#code{
float: right;
width: 692px;
}
#details_head{margin-bottom: 10px;}
#contentInfo{ #contentInfo{
width: 756px; width: 926px;
border: solid 1px #678dad; border: solid 1px #678dad;
background: #fff; background: #fff;
overflow: auto; overflow: auto;
...@@ -490,10 +490,6 @@ h2.hight:hover{ ...@@ -490,10 +490,6 @@ h2.hight:hover{
cursor: pointer; cursor: pointer;
} }
.software_details{
padding: 10px;
}
.log_content{ .log_content{
border: solid 1px #4c6172; border: solid 1px #4c6172;
padding: 2px; padding: 2px;
...@@ -503,13 +499,17 @@ h2.hight:hover{ ...@@ -503,13 +499,17 @@ h2.hight:hover{
border: none; border: none;
background: #f6f7f8; background: #f6f7f8;
color: #000; color: #000;
width: 754px; width: 926px;
padding: 2px; padding: 2px;
height: 450px; height: 450px;
font-size: 13px; font-size: 13px;
overflow-y: auto;
white-space: pre-wrap;
} }
.log_btn{border: 1px solid #678dad; border-top:none; height: 22px; width: 654px; margin: 0 40px 10px 40px; .log_btn{border: 1px solid #678dad; border-top:none; height: 22px; width: 654px; margin: 0 40px 10px 40px;
padding:4px 10px 4px 10px; font-size: 16px; color: #4c6172;} padding:4px 10px 4px 10px; font-size: 16px; color: #4c6172;}
.log p{white-space: pre-wrap; width:100%}
.log p.info{white-space: pre-wrap; width:98%; font-size: 15px; margin: 5px; color:red;}
.waitting{ .waitting{
margin-left: 10px; margin-left: 10px;
...@@ -557,7 +557,11 @@ h2.hight:hover{ ...@@ -557,7 +557,11 @@ h2.hight:hover{
margin: 10px; margin: 10px;
margin-top: 20px; margin-top: 20px;
} }
label.header {
color: #4C6172;
font-size: 18px;
font-weight: normal;
}
select { select {
-webkit-appearance: button; -webkit-appearance: button;
-webkit-border-radius: 2px; -webkit-border-radius: 2px;
...@@ -655,7 +659,8 @@ a.lshare img{ ...@@ -655,7 +659,8 @@ a.lshare img{
.form input[type=text] ,.form input[type=password] {float:left; width:190px;margin:5px;} .form input[type=text] ,.form input[type=password] {float:left; width:190px;margin:5px;}
.hiddendiv {display: none;white-space: pre-wrap;min-height: 18px;font-size: 13px; .hiddendiv {display: none;white-space: pre-wrap;min-height: 18px;font-size: 13px;
padding:3px;word-wrap: break-word;width:430px; max-height:120px;font-family: 'Helvetica Neue',Tahoma,Helvetica,Arial,sans-serif;} padding:3px;word-wrap: break-word;width:430px; max-height:120px;font-family: 'Helvetica Neue',Tahoma,Helvetica,Arial,sans-serif;}
.list{background: url(../images/menu_dropdown.png) left center no-repeat; padding-left:10px;} .list{display: block;padding: 5px;background: #E7E7E7; margin-bottom:7px;}
div.sep{display:block; height:7px;}
.slidebox{padding:10px; } .slidebox{padding:10px; }
.alert_message{ background: url(../images/alert.png) center no-repeat; height: 26px;} .alert_message{ background: url(../images/alert.png) center no-repeat; height: 26px;}
.error_message{ background: url(../images/exit.png) center no-repeat; height: 26px;} .error_message{ background: url(../images/exit.png) center no-repeat; height: 26px;}
...@@ -665,10 +670,10 @@ a.lshare img{ ...@@ -665,10 +670,10 @@ a.lshare img{
#pClose, .close{background:url(../images/close.png) no-repeat 0px 0px; display:block; width:22px; height:22px; cursor:pointer} #pClose, .close{background:url(../images/close.png) no-repeat 0px 0px; display:block; width:22px; height:22px; cursor:pointer}
#pClose:hover, .close:hover{background:url(../images/close_hover.png) no-repeat 0px 0px;} #pClose:hover, .close:hover{background:url(../images/close_hover.png) no-repeat 0px 0px;}
.md5sum {margin:10px; font-size:15px;} .md5sum {margin:10px; font-size:15px;}
.title{background: #e4e4e4; width: 100%; height: 25px; padding-top:2px; text-indent: 5px; color: #737373; text-shadow: 0px 1px #FFF;} .title{background: #e4e4e4; width: 100%; height: 26px; padding-top:2px; text-indent: 5px; color: #737373; text-shadow: 0px 1px #FFF;}
.menu-box-left{float:left; width: 120px; font-size:14px; background: #e4e4e4; padding:5px 0 5px 5px; margin-top:10px; .menu-box-left{float:left; width: 135px; font-size:14px; background: #e4e4e4; padding:5px 0 5px 5px; margin-top:10px;
font-size:14px; border-radius: 4px 0 0 4px;} font-size:14px; border-radius: 4px 0 0 4px;}
.menu-box-right{background: #e4e4e4; padding: 5px; float:right; width: 634px; margin-left: -5px; .menu-box-right{background: #e4e4e4; padding: 5px; float:right; width: 745px; margin-left: -5px;
margin-top:10px; box-shadow: 1px 1px 1px #888888;} margin-top:10px; box-shadow: 1px 1px 1px #888888;}
.menu-box-left ul{margin:0px; list-style:none;} .menu-box-left ul{margin:0px; list-style:none;}
.menu-box-left li{padding: 2px; padding-left:10px; padding-right:10px; text-shadow: 0px 1px #fff;border-bottom:1px solid #fff;} .menu-box-left li{padding: 2px; padding-left:10px; padding-right:10px; text-shadow: 0px 1px #fff;border-bottom:1px solid #fff;}
...@@ -690,10 +695,14 @@ a.lshare img{ ...@@ -690,10 +695,14 @@ a.lshare img{
.popup td.top img { display: block; } .popup td.top img { display: block; }
.popup td#bottomright { background-image: url(../images/bubble-1.png); } .popup td#bottomright { background-image: url(../images/bubble-1.png); }
.popup-contents {background: #fff; color: #666666;} .popup-contents {background: #fff; color: #666666;}
.popup a{display: block; font-weight:bold; color: #4DA0C6;} .popup a{display: block; font-weight:bold; color: #4DA0C6; padding-left: 5px; padding-bottom: 5px;}
.popup a:hover{color: #666666;} .popup a:hover{color: #666666;}
.popup ul{margin:0; padding:0; list-style:none;} .popup ul{margin:0; margin-bottom:10px; padding:0; list-style:none;}
.popup li{border-bottom: 1px dashed #666666; padding:5px; padding-top:5px;} .popup li{border-bottom: 1px dashed #666666; padding:0;}
.popup ul li:last-child{border-bottom:none}
.popup ul li a{padding-bottom:0}
ul.menu li {padding-top:5px; padding-bottom:5px;}
ul.menu{margin-bottom:0;}
.popup-value{display:none;} .popup-value{display:none;}
textarea.parameter {border: solid 1px #678dad; color: #666666; height:110px;} textarea.parameter {border: solid 1px #678dad; color: #666666; height:110px;}
.link{color:#fff; font-weight:bold; text-decoration:none} .link{color:#fff; font-weight:bold; text-decoration:none}
......
slapos/runner/static/images/content.png

192 Bytes | W: | H:

slapos/runner/static/images/content.png

195 Bytes | W: | H:

slapos/runner/static/images/content.png
slapos/runner/static/images/content.png
slapos/runner/static/images/content.png
slapos/runner/static/images/content.png
  • 2-up
  • Swipe
  • Onion skin
slapos/runner/static/images/footer_bg.png

984 Bytes | W: | H:

slapos/runner/static/images/footer_bg.png

1.08 KB | W: | H:

slapos/runner/static/images/footer_bg.png
slapos/runner/static/images/footer_bg.png
slapos/runner/static/images/footer_bg.png
slapos/runner/static/images/footer_bg.png
  • 2-up
  • Swipe
  • Onion skin
slapos/runner/static/images/head.png

1.27 KB | W: | H:

slapos/runner/static/images/head.png

1.4 KB | W: | H:

slapos/runner/static/images/head.png
slapos/runner/static/images/head.png
slapos/runner/static/images/head.png
slapos/runner/static/images/head.png
  • 2-up
  • Swipe
  • Onion skin
slapos/runner/static/images/main_bg_all.png

236 Bytes | W: | H:

slapos/runner/static/images/main_bg_all.png

215 Bytes | W: | H:

slapos/runner/static/images/main_bg_all.png
slapos/runner/static/images/main_bg_all.png
slapos/runner/static/images/main_bg_all.png
slapos/runner/static/images/main_bg_all.png
  • 2-up
  • Swipe
  • Onion skin
slapos/runner/static/images/main_bottom.png

413 Bytes | W: | H:

slapos/runner/static/images/main_bottom.png

421 Bytes | W: | H:

slapos/runner/static/images/main_bottom.png
slapos/runner/static/images/main_bottom.png
slapos/runner/static/images/main_bottom.png
slapos/runner/static/images/main_bottom.png
  • 2-up
  • Swipe
  • Onion skin
slapos/runner/static/images/main_top.png

374 Bytes | W: | H:

slapos/runner/static/images/main_top.png

379 Bytes | W: | H:

slapos/runner/static/images/main_top.png
slapos/runner/static/images/main_top.png
slapos/runner/static/images/main_top.png
slapos/runner/static/images/main_top.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -465,7 +465,7 @@ if (jQuery) (function(jQuery){ ...@@ -465,7 +465,7 @@ if (jQuery) (function(jQuery){
var fileshtml = ''; var fileshtml = '';
var gs_lastparent = jQuery('#' + jQuery("#curDir").attr('rel')).parent().parent().parent().children('a'); var gs_lastparent = jQuery('#' + jQuery("#curDir").attr('rel')).parent().parent().parent().children('a');
if (gs_lastparent.length > 0) { if (gs_lastparent.length > 0) {
fileshtml += "<tr><td class='first'><div class='directory directory_info gsItem' rel=\'up\'><a href='javascript:void(0)' onclick=\"jQuery('#" + jQuery("#curDir").attr('rel')+ "').parent().parent().parent().children('a').trigger('click'); return false\"> parent...</a></div></td align='center'><td align='center'>Folder</td><td align='center'>-</td><td align='center'>-</td></tr>"; fileshtml += "<tr><td class='first'><div class='directory directory_info gsItem' rel=\'up\'><a href='javascript:void(0)' onclick=\"jQuery('#" + jQuery("#curDir").attr('rel')+ "').parent().parent().parent().children('a').trigger('click'); return false\"> ..</a></div></td align='center'><td align='center'>Folder</td><td align='center'>-</td><td align='center'>-</td></tr>";
} }
if (gsfiless.length > 0) { if (gsfiless.length > 0) {
for (var numf in gsfiless) { for (var numf in gsfiless) {
...@@ -525,6 +525,21 @@ if (jQuery) (function(jQuery){ ...@@ -525,6 +525,21 @@ if (jQuery) (function(jQuery){
} }
function splitPath(path) {
var list = path.split('/'),
html = "";
for (var i=0; i<list.length; i++){
var subList = new Array();
if (list[i] !== '') {
for (var j=0; j<=i; j++){
subList.push(list[j]);
}
html += "<a class='pathlink' rel='"+subList.join('/')+"/'>"+list[i]+"</a>/";
}
}
return html;
}
function showTree(c, t) { function showTree(c, t) {
var cObject = jQuery(c); var cObject = jQuery(c);
cObject.addClass('wait'); cObject.addClass('wait');
...@@ -541,7 +556,8 @@ if (jQuery) (function(jQuery){ ...@@ -541,7 +556,8 @@ if (jQuery) (function(jQuery){
success: function(data) { success: function(data) {
//remember current dir id //remember current dir id
jQuery("#curDir").html(unescape(t)); jQuery("#curDir").html(splitPath(unescape(t)));
jQuery("#curDir").attr('val', unescape(t));
jQuery("#curDir").attr('rel', jQuery('a', cObject).attr('id')); jQuery("#curDir").attr('rel', jQuery('a', cObject).attr('id'));
gs_cur_items = new Array(); gs_cur_items = new Array();
...@@ -587,6 +603,9 @@ if (jQuery) (function(jQuery){ ...@@ -587,6 +603,9 @@ if (jQuery) (function(jQuery){
jQuery(t).find('LI > A').bind('click', function () { jQuery(t).find('LI > A').bind('click', function () {
showTree (jQuery(this).parent(), encodeURIComponent(jQuery(this).attr('rel').match( /.*\// ))); showTree (jQuery(this).parent(), encodeURIComponent(jQuery(this).attr('rel').match( /.*\// )));
}); });
jQuery('a.pathlink').bind('click', function () {
showTree( jQuery('#gs_dir_list'), jQuery(this).attr('rel'));
});
} }
function showRoot(){ function showRoot(){
...@@ -630,7 +649,7 @@ if (jQuery) (function(jQuery){ ...@@ -630,7 +649,7 @@ if (jQuery) (function(jQuery){
}); });
return false; return false;
} }
var curDir = jQuery("#curDir").html(); var curDir = jQuery("#curDir").attr('val');
var dataForSend = null; var dataForSend = null;
var gsitem = gs_get_cur_item(jQuery(this).attr('rel')); var gsitem = gs_get_cur_item(jQuery(this).attr('rel'));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
$(document).ready(function(){ $(document).ready(function(){
$(".tabContents").hide(); // Hide all tab content divs by default $(".tabContents").hide(); // Hide all tab content divs by default
var hashes = window.location.href.split('#'); var hashes = window.location.href.split('#');
var fromheight = 0; var fromheight = 0;
var previoustab = null; var previoustab = null;
...@@ -18,17 +18,17 @@ $(document).ready(function(){ ...@@ -18,17 +18,17 @@ $(document).ready(function(){
}); });
} }
else{$(".tabContents:first").show(); previoustab = ".tabContents:first";} // Show the first div of tab content by default else{$(".tabContents:first").show(); previoustab = ".tabContents:first";} // Show the first div of tab content by default
$("#tabContaier ul li a").click(function(){ //Fire the click event $("#tabContaier ul li a").click(function(){ //Fire the click event
if($(this).hasClass('active')){ if($(this).hasClass('active')){
return false; return false;
} }
fromheight = $(previoustab).height(); fromheight = $(previoustab).height();
var activeTab = $(this).attr("href"); // Catch the click link var activeTab = $(this).attr("href"); // Catch the click link
$("#tabContaier .tabDetails").css("height", $("#tabContaier .tabDetails").height()); $("#tabContaier .tabDetails").css("height", $("#tabContaier .tabDetails").height());
$("#tabContaier ul li a").removeClass("active"); // Remove pre-highlighted link $("#tabContaier ul li a").removeClass("active"); // Remove pre-highlighted link
$(this).addClass("active"); // set clicked link to highlight state $(this).addClass("active"); // set clicked link to highlight state
$(".tabContents").hide(); // hide currently visible tab content div $(".tabContents").hide(); // hide currently visible tab content div
$(activeTab).fadeIn(); // show the target tab content div by matching clicked link. $(activeTab).fadeIn(); // show the target tab content div by matching clicked link.
var diff = fromheight - $(activeTab).height(); var diff = fromheight - $(activeTab).height();
if (diff > 0){$("#tabContaier .tabDetails").animate({height: '-=' + diff + 'px'}, 850, 'swing', function() { if (diff > 0){$("#tabContaier .tabDetails").animate({height: '-=' + diff + 'px'}, 850, 'swing', function() {
$("#tabContaier .tabDetails").css("height", ""); $("#tabContaier .tabDetails").css("height", "");
...@@ -39,5 +39,5 @@ $(document).ready(function(){ ...@@ -39,5 +39,5 @@ $(document).ready(function(){
previoustab = activeTab; previoustab = activeTab;
$("#tabContaier .tabDetails").css("height", $("#tabContaier .tabDetails").height()); $("#tabContaier .tabDetails").css("height", $("#tabContaier .tabDetails").height());
return false;//this reinitialize tab index when reload page return false;//this reinitialize tab index when reload page
}); });
}); });
\ No newline at end of file
...@@ -45,7 +45,7 @@ $(function () { ...@@ -45,7 +45,7 @@ $(function () {
$('.popup').css('display', 'none'); $('.popup').css('display', 'none');
shown = false; shown = false;
}); });
}, hideDelay) }, hideDelay);
return false; return false;
}); });
}); });
\ No newline at end of file
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
$.extend($.fn, { $.extend($.fn, {
Popup: function(msg, option) { Popup: function(msg, option) {
var h; var h;
if (option.type == undefined) option.type = "info"; if (option.type === undefined) option.type = "info";
if (option.closebtn == undefined) option.closebtn = false; if (option.closebtn === undefined) option.closebtn = false;
if (option.duration == undefined) option.duration = 0; if (option.duration === undefined) option.duration = 0;
if (option.load == undefined) option.load = false; if (option.load === undefined) option.load = false;
$box = $(this); var $box = $(this);
if(showDelayTimer){clearTimeout(showDelayTimer);} if(showDelayTimer){clearTimeout(showDelayTimer);}
if(isShow){ if(isShow){
$box.fadeOut('normal', function() { $box.fadeOut('normal', function() {
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
} }
else{setupBox();} else{setupBox();}
function setupBox(){ function setupBox(){
if (msg == undefined){ if (msg === undefined){
msg = "Cannot execute your request. Please make sure you are logged in!!" msg = "Cannot execute your request. Please make sure you are logged in!!";
option.type = "error"; option.type = "error";
} }
$box.empty(); $box.empty();
...@@ -30,43 +30,43 @@ ...@@ -30,43 +30,43 @@
$box.show(); $box.show();
$box.append('<div><table id="bcontent"><tr>' + $box.append('<div><table id="bcontent"><tr>' +
'<td valign="middle" class="logo ' + option.type + '_message"></td>' + '<td valign="middle" class="logo ' + option.type + '_message"></td>' +
'<td valign="middle"><p>' + msg + '</p></td>' + '<td valign="middle"><p>' + msg + '</p></td>' +
'<td valign="middle" class="b_close"><span id="pClose"></span></td></tr></table></div>'); '<td valign="middle" class="b_close"><span id="pClose"></span></td></tr></table></div>');
$(window).scroll(function(){ $(window).scroll(function(){
$box.animate({top:$(window).scrollTop()+"px" },{queue: false, duration: 350}); $box.animate({top:$(window).scrollTop()+"px" },{queue: false, duration: 350});
}); });
h = $("#bcontent").height()+5; h = $("#bcontent").height()+5;
$("#pClose").bind("click", function() { $("#pClose").bind("click", function() {
close(); close();
}); });
showBox(); showBox();
if(option.duration != 0){ if(option.duration !== 0){
showDelayTimer = setTimeout(function(){ showDelayTimer = setTimeout(function(){
showDelayTimer = null; showDelayTimer = null;
close(); close();
}, option.duration); }, option.duration);
} }
} }
function showBox(){ function showBox(){
if(option.load){ if(option.load){
$(window).load(function(){ $(window).load(function(){
$box.css('top', + ($(window).scrollTop() - h) +'px'); $box.css('top', + ($(window).scrollTop() - h) +'px');
$box.animate({ top:"+=" + h + "px" }, "slow"); $box.animate({ top:"+=" + h + "px" }, "slow");
isShow = true; isShow = true;
}); });
} }
else{ else{
$box.css('top', + ($(window).scrollTop() - h) +'px'); $box.css('top', + ($(window).scrollTop() - h) +'px');
$box.animate({ top:"+=" + h + "px" }, "slow"); $box.animate({ top:"+=" + h + "px" }, "slow");
isShow = true; isShow = true;
} }
} }
function close(){ function close(){
$box.animate({ top:"-=" + h + "px" }, "slow", function(){ $box.animate({ top:"-=" + h + "px" }, "slow", function(){
$box.fadeOut("normal", function() { $box.fadeOut("normal", function() {
isShow = false; isShow = false;
}); });
}); });
} }
} }
}); });
......
$(document).ready( function() { /*jslint undef: true */
var send = false; /*global $, document, window, $SCRIPT_ROOT */
$("#update").click(function(){ /* vim: set et sts=4: */
var haspwd = false;
var hasAccount = !($("input#hasAccount").val() === ""); $(document).ready(function () {
if($("input#username").val() === "" || !$("input#username").val().match(/^[\w\d\._-]+$/)){ "use strict";
$("#error").Popup("Invalid user name. Please check it!", {type:'alert', duration:3000}); var send = false;
return false; $("#update").click(function () {
} var haspwd = false,
else if ($("input#username").val().length <6){ hasAccount = ($("input#hasAccount").val() !== "");
$("#error").Popup("Username must have at least 6 characters", {type:'alert', duration:3000}); if ($("input#username").val() === "" || !$("input#username").val().match(/^[\w\d\._\-]+$/)) {
return false; $("#error").Popup("Invalid user name. Please check it!", {type: 'alert', duration: 3000});
} return false;
if($("input#name").val() === ""){
$("#error").Popup("Please enter your name and surname!", {type:'alert', duration:3000});
return false;
}
if(!$("input#email").val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)){
$("#error").Popup("Please enter a valid email adress!", {type:'alert', duration:3000});
return false;
}
if(!hasAccount && !$("input#password").val().match(/^[\w\d\._-]+$/)){
$("#error").Popup("Please enter your new password!", {type:'alert', duration:3000});
return false;
}
if ($("input#password").val() !== "" && $("input#password").val().length <6){
$("#error").Popup("The password must have at least 6 characters", {type:'alert', duration:3000});
return false;
}
if($("input#password").val() !== ""){
if($("input#password").val() === "" || !$("input#password").val().match(/^[\w\d\._-]+$/)){
$("#error").Popup("Please enter your new password!", {type:'alert', duration:3000});
return false;
}
if($("input#password").val() !== $("input#cpassword").val()){
$("#error").Popup("your password does not match!", {type:'alert', duration:3000});
return false;
}
haspwd = true;
}
if(!$("input#rcode").val().match(/^[\w\d]+$/)){
$("#error").Popup("Please enter your password recovery code.", {type:'alert', duration:3000});
return false;
}
if(send) return false;
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + ((hasAccount)? '/updateAccount':'/configAccount'),
data: {name: $("input#name").val(), username:$("input#username").val(), email:$("input#email").val(),
password:((haspwd) ? $("input#password").val():""), rcode:$("input#rcode").val()},
success: function(data){
if(data.code ==1){
location.href = $SCRIPT_ROOT+"/"
} }
else{ if ($("input#username").val().length < 6) {
$("#error").Popup(data.result, {type:'error', duration:5000}); $("#error").Popup("Username must have at least 6 characters", {type: 'alert', duration: 3000});
return false;
} }
send = false; if ($("input#name").val() === "") {
}, $("#error").Popup("Please enter your name and surname!", {type: 'alert', duration: 3000});
error:function(){send = false;} return false;
}
if (!$("input#email").val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)) {
$("#error").Popup("Please enter a valid email adress!", {type: 'alert', duration: 3000});
return false;
}
if (!hasAccount && !$("input#password").val()) {
$("#error").Popup("Please enter your new password!", {type: 'alert', duration: 3000});
return false;
}
if ($("input#password").val() !== "" && $("input#password").val().length < 6) {
$("#error").Popup("The password must have at least 6 characters", {type: 'alert', duration: 3000});
return false;
}
if ($("input#password").val() !== "") {
if ($("input#password").val() === "" || !$("input#password").val()) {
$("#error").Popup("Please enter your new password!", {type: 'alert', duration: 3000});
return false;
}
if ($("input#password").val() !== $("input#cpassword").val()) {
$("#error").Popup("your password does not match!", {type: 'alert', duration: 3000});
return false;
}
haspwd = true;
}
if (!$("input#rcode").val().match(/^[\w\d]+$/)) {
$("#error").Popup("Please enter your password recovery code.", {type: 'alert', duration: 3000});
return false;
}
if (send) {
return false;
}
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + ((hasAccount) ? '/updateAccount' : '/configAccount'),
data: {
name: $("input#name").val(),
username: $("input#username").val(),
email: $("input#email").val(),
password: ((haspwd) ? $("input#password").val() : ""),
rcode: $("input#rcode").val()
},
success: function (data) {
if (data.code === 1) {
window.location.href = $SCRIPT_ROOT + "/";
} else {
$("#error").Popup(data.result, {type: 'error', duration: 5000});
}
send = false;
},
error: function () { send = false; }
});
return false;
}); });
return false; });
});
});
\ No newline at end of file
/*jslint undef: true */
/*global $, window, $SCRIPT_ROOT */
/* vim: set et sts=4: */
/*Common javascript function*/ /*Common javascript function*/
String.prototype.toHtmlChar = function(){ String.prototype.toHtmlChar = function () {
var c = {'<':'&lt;', '>':'&gt;', '&':'&amp;', '"':'&quot;', "'":'&#039;', "use strict";
'#':'&#035;' }; var c = {
return this.replace( /[<&>'"#]/g, function(s) { return c[s]; } ); '<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;',
"'": '&#039;',
'#': '&#035;'
};
return this.replace(/[<&>'"#]/g, function (s) { return c[s]; });
}; };
String.prototype.trim = function () { String.prototype.trim = function () {
"use strict";
return this.replace(/^\s*/, "").replace(/\s*$/, ""); return this.replace(/^\s*/, "").replace(/\s*$/, "");
}; };
/****************************************/ /****************************************/
function setInput($elt) { function setInput($elt) {
if(!$elt){$elt = $('input[type="text"], input[type="password"]');} "use strict";
$elt.addClass("idleField"); if (!$elt) {
$elt.focus(function() { $elt = $('input[type="text"], input[type="password"]');
$(this).removeClass("idleField").addClass("focusField"); }
if (this.value == this.defaultValue){ $elt.addClass("idleField");
this.value = ''; $elt.focus(function () {
} $(this).removeClass("idleField").addClass("focusField");
if(this.value != this.defaultValue){ if (this.value === this.defaultValue) {
this.select(); this.value = '';
} }
}); if (this.value !== this.defaultValue) {
$elt.blur(function() { this.select();
$(this).removeClass("focusField").addClass("idleField"); }
if ($.trim(this.value) === ''){ });
this.value = (this.defaultValue ? this.defaultValue : ''); $elt.blur(function () {
} $(this).removeClass("focusField").addClass("idleField");
}); if ($.trim(this.value) === '') {
this.value = (this.defaultValue || '');
}
});
} }
/*******************Bind remove all button*******************/ /*******************Bind remove all button*******************/
function bindRemove(){ function bindRemove() {
$("a#removeSr").click(function(){ "use strict";
if(!window.confirm("Do you really want to remove all software release?")){ $("a#removeSr").click(function () {
return false; if (!window.confirm("Do you really want to remove all software release?")) {
} return false;
location.href = $SCRIPT_ROOT + '/removeSoftware'; }
}); window.location.href = $SCRIPT_ROOT + '/removeSoftware';
$("a#removeIst").click(function(){ });
if(!window.confirm("Do you really want to remove all computer partition?")){ $("a#removeIst").click(function () {
return false; if (!window.confirm("Do you really want to remove all computer partition?")) {
} return false;
location.href = $SCRIPT_ROOT + '/removeInstance'; }
}); window.location.href = $SCRIPT_ROOT + '/removeInstance';
});
} }
/**************************/ /**************************/
(function ($, document, window) { (function ($, document, window) {
"use strict";
$.extend($.fn, { $.extend($.fn, {
slideBox: function(state) { slideBox: function (state) {
if (!state) state = "hide"; if (!state) {
var header = $("#"+$(this).attr('id')+">h2"); state = "hide";
var box = $("#"+$(this).attr('id')+">div"); }
header.addClass(state); var header = $("#" + $(this).attr('id') + ">h2"),
if(state=="hide"){box.css('display', 'none');} box = $("#" + $(this).attr('id') + ">div");
header.click(function(){ header.addClass(state);
var state = box.css("display"); if (state === "hide") {
if (state == "none"){ box.css('display', 'none');
box.slideDown("normal"); }
header.removeClass("hide"); header.click(function () {
header.addClass("show"); var state = box.css("display");
} if (state === "none") {
else{ box.slideDown("normal");
box.slideUp("normal"); header.removeClass("hide");
header.removeClass("show"); header.addClass("show");
header.addClass("hide"); } else {
} box.slideUp("normal");
}); header.removeClass("show");
} header.addClass("hide");
}
});
}
}); });
}(jQuery, document, this)); }(jQuery, document, this));
\ No newline at end of file
/*jslint undef: true */
/*global document, escape, unescape */
/* vim: set et sts=4: */
/*Cookies Management*/ /*Cookies Management*/
function setCookie(name,value,expires,path,domain,secure){ function getCookie(name) {
if (!expires){ "use strict";
var today = new Date(); var i,
expires = new Date(today.getTime() + 365 * 24 * 60 * 60 * 1000); x,
} y,
document.cookie = name + "=" + escape(value) + result,
"; expires=" + expires.toGMTString() + ARRcookies = document.cookie.split(";");
((path) ? "; path=" + path : "/") + for (i = 0; i < ARRcookies.length; i += 1) {
((domain) ? "; domain=" + domain : "") + x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
((secure) ? "; secure" : ""); y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
x = x.replace(/^\s+|\s+$/g, "");
if (x === name) {
result = unescape(y);
if (result !== "" && result !== null) {
return result;
}
return null;
}
}
return null;
} }
function deleteCookie(name,path,domain) {
if (getCookie(name)) { function deleteCookie(name, path, domain) {
document.cookie = name + "=" + "use strict";
((path) ? "; path=" + path : "/") + if (getCookie(name)) {
((domain) ? "; domain=" + domain : "") + document.cookie = name + "=" +
"; expires=Thu, 01-Jan-70 00:00:01 GMT"; (path ? "; path=" + path : "/") +
} (domain ? "; domain=" + domain : "") +
"; expires=Thu, 01-Jan-70 00:00:01 GMT";
}
} }
function getCookie(name) {
var i,x,y,ARRcookies=document.cookie.split(";"); function setCookie(name, value, expires, path, domain, secure) {
for (i=0;i<ARRcookies.length;i++){ "use strict";
x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("=")); if (getCookie(name) !== null){
y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1); deleteCookie(name);
x=x.replace(/^\s+|\s+$/g,""); }
if (x==name){ if (!expires) {
var result = unescape(y); var today = new Date();
if (result != "" && result != null){ expires = new Date(today.getTime() + 365 * 24 * 60 * 60 * 1000);
return result;
}
return null;
} }
} document.cookie = name + "=" + escape(value) +
return null; "; expires=" + expires.toGMTString() +
((path) ? "; path=" + path : "/") +
((domain) ? "; domain=" + domain : "") +
((secure) ? "; secure" : "");
} }
/**************************/ /**************************/
$(document).ready( function() { /*jslint undef: true */
var editor = ace.edit("editor"); /*global $, document, ace, $SCRIPT_ROOT */
editor.setTheme("ace/theme/crimson_editor"); /* vim: set et sts=4: */
var CurentMode = require("ace/mode/buildout").Mode;
editor.getSession().setMode(new CurentMode());
editor.getSession().setTabSize(2);
editor.getSession().setUseSoftTabs(true);
editor.renderer.setHScrollBarAlwaysVisible(false);
var file = $("input#profile").val(); $(document).ready(function () {
var workdir = $("input#workdir").val(); "use strict";
var edit = false;
var send = false;
selectFile(file);
$("#save").click(function(){ var editor, CurrentMode, file, workdir, edit, send;
if(!edit){
$("#error").Popup("Can not load your file, please make sure that you have selected a Software Release", {type:'alert', duration:5000});
return false;
}
if (send) return;
send =true
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/saveFileContent',
data: {file: file, content: editor.getSession().getValue()},
success: function(data){
if(data.code == 1){
$("#error").Popup("File Saved!", {type:'confirm', duration:2000});
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
return false;
});
$("#getmd5").click(function(){
getmd5sum();
return false;
});
$("#adddevelop").click(function(){
var developList = new Array();
var i=0;
$("#plist li").each(function(index){
var elt = $(this).find("input:checkbox");
if (elt.is(":checked")){
developList[i] = workdir+"/"+elt.val();
i++;
elt.attr("checked", false);
}
});
if (developList.length > 0){setDevelop(developList);}
return false;
});
function selectFile(file){ function selectFile(file) {
edit = false; edit = false;
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: $SCRIPT_ROOT + '/getFileContent', url: $SCRIPT_ROOT + '/getFileContent',
data: "file=" + file, data: "file=" + file,
success: function(data){ success: function (data) {
if(data.code == 1){ if (data.code === 1) {
editor.getSession().setValue(data.result); editor.getSession().setValue(data.result);
edit = true; edit = true;
} } else {
else{ $("#error").Popup("Can not load your file, please make sure that you have selected a Software Release",
$("#error").Popup("Can not load your file, please make sure that you have selected a Software Release", {type:'alert', duration:5000}); {type: 'alert', duration: 5000});
} }
} }
}); });
return; return;
} }
function getmd5sum(){ function getmd5sum() {
if (send) return; if (send) {
send =true return;
$.ajax({ }
type: "POST", send = true;
url: $SCRIPT_ROOT + '/getmd5sum', $.ajax({
data: {file: file}, type: "POST",
success: function(data){ url: $SCRIPT_ROOT + '/getmd5sum',
if(data.code == 1){ data: {file: file},
$("#md5sum").empty(); success: function (data) {
$("#md5sum").append('md5sum : <span>' + data.result + '</span>'); if (data.code === 1) {
} $("#md5sum").empty();
else{ $("#md5sum").append('md5sum : <span>' + data.result + '</span>');
$("#error").Popup(data.result, {type:'error', duration:5000}); } else {
} $("#error").Popup(data.result, {type: 'error', duration: 5000});
send = false; }
} send = false;
}); }
} });
function setDevelop(developList){ }
if (developList==null || developList.length <= 0) return;
editor.navigateFileStart(); function setDevelop(developList) {
editor.find('buildout',{caseSensitive: true,wholeWord: true}); if (developList === null || developList.length <= 0) {
if(!editor.getSelectionRange().isEmpty()){ return;
//editor.find("",{caseSensitive: true,wholeWord: true,regExp: true}); }
//if(!editor.getSelectionRange().isEmpty()){ editor.navigateFileStart();
//alert("found"); editor.find('buildout', {caseSensitive: true, wholeWord: true});
//} if (editor.getSelectionRange().isEmpty()) {
//else{alert("no found"); $("#error").Popup("Can not found part [buildout]! Please make sure that you have a cfg file",
//} {type: 'alert', duration: 3000});
} return;
else{ }
$("#error").Popup("Can not found part [buildout]! Please make sure that you have a cfg file", {type:'alert', duration:3000}); //else {
return; // //editor.find("",{caseSensitive: true,wholeWord: true,regExp: true});
} // //if (!editor.getSelectionRange().isEmpty()) {
editor.navigateLineEnd(); // //alert("found");
$.post($SCRIPT_ROOT+"/getPath", {file:developList.join("#")}, function(data) { // //}
if(data.code==1){ // //else{alert("no found");
var result = data.result.split('#'); // //}
editor.insert("\ndevelop =\n\t" + result[0] + "\n"); //}
for(var i=1; i<result.length; i++) editor.navigateLineEnd();
editor.insert("\t" + result[i] + "\n"); $.post($SCRIPT_ROOT + "/getPath", {file: developList.join("#")}, function (data) {
} if (data.code === 1) {
}) var i,
.error(function() { }) result = data.result.split('#');
.complete(function(){}); editor.insert("\ndevelop =\n\t" + result[0] + "\n");
editor.insert("\n"); for (i = 1; i < result.length; i += 1) {
} editor.insert("\t" + result[i] + "\n");
}); }
\ No newline at end of file }
})
.error(function () { })
.complete(function () {});
editor.insert("\n");
}
editor = ace.edit("editor");
CurrentMode = require("ace/mode/buildout").Mode;
file = $("input#profile").val();
workdir = $("input#workdir").val();
edit = false;
send = false;
editor.setTheme("ace/theme/crimson_editor");
editor.getSession().setMode(new CurrentMode());
editor.getSession().setTabSize(2);
editor.getSession().setUseSoftTabs(true);
editor.renderer.setHScrollBarAlwaysVisible(false);
selectFile(file);
$("#save").click(function () {
if (!edit) {
$("#error").Popup("Can not load your file, please make sure that you have selected a Software Release",
{type: 'alert', duration: 5000});
return false;
}
if (send) {
return;
}
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/saveFileContent',
data: {file: file, content: editor.getSession().getValue()},
success: function (data) {
if (data.code === 1) {
$("#error").Popup("File Saved!", {type: 'confirm', duration: 2000});
} else {
$("#error").Popup(data.result, {type: 'error', duration: 5000});
}
send = false;
}
});
return false;
});
$("#getmd5").click(function () {
getmd5sum();
return false;
});
$("#adddevelop").click(function () {
var developList = [],
i = 0;
$("#plist li").each(function (index) {
var elt = $(this).find("input:checkbox");
if (elt.is(":checked")) {
developList[i] = workdir + "/" + elt.val();
i += 1;
elt.attr("checked", false);
}
});
if (developList.length > 0) {
setDevelop(developList);
}
return false;
});
});
$(document).ready( function() { /*jslint undef: true */
var send = false; /*global $, document, $SCRIPT_ROOT */
var cloneRequest; /* vim: set et sts=4: */
$('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT+"/fileBrowser", root: "workspace/"});
configRadio();
$("input#nothing").change(function(){ $(document).ready(function () {
configRadio(); "use strict";
});
$("input#ssh").change(function(){ function configRadio() {
configRadio(); $("#modelist li").each(function (index) {
}); var boxselector = "#box" + index;
$("input#https").change(function(){ if ($(this).hasClass('checked')) {
configRadio(); $(this).removeClass('checked');
}); $(boxselector).slideUp("normal");
$("#clone").click(function(){ }
if(send){ if ($(this).find("input:radio").is(':checked')) {
cloneRequest.abort(); $(this).addClass('checked');
$("#imgwaitting").fadeOut('normal'); //change content here
$("#clone").empty(); $(boxselector).slideDown("normal");
$("#clone").append("Clone"); }
send = false; if (index !== 2) {
return; $("input#password").val("");
} $("input#cpassword").val("");
var repo_url = $("input#repo").val(); }
var email = ""; });
var name = ""; }
/* /^(ht|f)tps?:\/\/[a-z0-9-\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?$/ */
if($("input#repo").val() === '' || !repo_url.match(/^[\w\d\.\/:~@_-]+$/)){ var send = false,
$("#error").Popup("Invalid url for the repository", {type:'alert', duration:3000}); cloneRequest;
return false;
} $('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT + "/fileBrowser", root: "workspace/"});
if($("input#name").val() === '' || !$("input#name").val().match(/^[\w\d\._-]+$/)){ configRadio();
$("#error").Popup("Invalid project name", {type:'alert', duration:3000}); $("input#nothing").change(function () {
return false; configRadio();
} });
if($("input#user").val() !== ""){ $("input#ssh").change(function () {
name = $("input#user").val(); configRadio();
} });
if($("input#email").val() !== '' && $("input#email").val() !== "Enter your email adress..."){ $("input#https").change(function () {
if(!$("input#email").val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)){ configRadio();
$("#error").Popup("Please enter a valid email adress!", {type:'alert', duration:3000}); });
return false; $("#clone").click(function () {
} if (send) {
email = $("input#email").val(); cloneRequest.abort();
} $("#imgwaitting").fadeOut('normal');
if($("input#https").is(':checked')){ $("#clone").empty();
if($("input#username").val() == "" || !$("input#username").val().match(/^[\w\d\._-]+$/)){ $("#clone").append("Clone");
$("#error").Popup("Please enter a correct username", {type:'alert', duration:3000}); send = false;
return false; return;
} }
if($("input#password").val() != ""){ var repo_url = $("input#repo").val(),
if(repo_url.indexOf("https://") != -1){ email = "",
repo_url = "https://" + $("input#username").val() + name = "";
":" + $("input#password").val() +
"@" + repo_url.substring(8); /* /^(ht|f)tps?:\/\/[a-z0-9-\.]+\.[a-z]{2,4}\/?([^\s<>\#%"\,\{\}\\|\\\^\[\]`]+)?$/ */
} if ($("input#repo").val() === '' || !repo_url.match(/^[\w\d\.\/:~@_\-]+$/)) {
else{ $("#error").Popup("Invalid url for the repository", {type: 'alert', duration: 3000});
$("#error").Popup("The URL of your repository should start with 'https://'", {type:'alert', duration:3000}); return false;
return false; }
} if ($("input#name").val() === '' || !$("input#name").val().match(/^[\w\d\._\-]+$/)) {
} $("#error").Popup("Invalid project name", {type: 'alert', duration: 3000});
else{ return false;
$("#error").Popup("Please enter your password", {type:'alert', duration:3000}); }
return false; if ($("input#user").val() !== "") {
} name = $("input#user").val();
} }
else if(repo_url.indexOf("https://") != -1){ if ($("input#email").val() !== '' && $("input#email").val() !== "Enter your email adress...") {
$("#error").Popup("Please select HTTPS Security Mode for this repository", {type:'alert', duration:3000}); if (!$("input#email").val().match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)) {
return false; $("#error").Popup("Please enter a valid email adress!", {type: 'alert', duration: 3000});
} return false;
$("#imgwaitting").fadeIn('normal'); }
$("#clone").empty(); email = $("input#email").val();
$("#clone").append("Stop"); }
send = true; if ($("input#https").is(':checked')) {
cloneRequest = $.ajax({ if ($("input#username").val() === "" || !$("input#username").val().match(/^[\w\d\._\-]+$/)) {
type: "POST", $("#error").Popup("Please enter a correct username", {type: 'alert', duration: 3000});
url: $SCRIPT_ROOT + '/cloneRepository', return false;
data: {repo: repo_url, name: ($("input#workdir").val() + "/" + }
$("input#name").val()), email:email, if ($("input#password").val() !== "") {
user:name}, if (repo_url.indexOf("https://") !== -1) {
success: function(data){ repo_url = "https://" + $("input#username").val() +
if(data.code == 1){ ":" + $("input#password").val() +
$("#file_navigation").fadeIn('normal'); "@" + repo_url.substring(8);
$("#error").Popup("Your repository is cloned!", {type:'confirm', duration:3000}); } else {
$("input#repo").val("Enter the url of your repository..."); $("#error").Popup("The URL of your repository should start with 'https://'", {type: 'alert', duration: 3000});
$("input#name").val("Enter the project name..."); return false;
$('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT+"/fileBrowser", root: "workspace"}); }
} } else {
else{ $("#error").Popup("Please enter your password", {type: 'alert', duration: 3000});
$("#error").Popup(data.result, {type:'error'}); return false;
} }
$("#imgwaitting").hide(); } else if (repo_url.indexOf("https://") !== -1) {
$("#clone").empty(); $("#error").Popup("Please select HTTPS Security Mode for this repository", {type: 'alert', duration: 3000});
$("#clone").append("Clone"); return false;
send = false; }
}, $("#imgwaitting").fadeIn('normal');
error: function(request,error) {
$("#error").Popup("unable to clone your project, please check your internet connection", {type:'error', duration:3000});
$("#imgwaitting").hide();
$("#clone").empty(); $("#clone").empty();
$("#clone").append("Clone"); $("#clone").append("Stop");
} send = true;
}); cloneRequest = $.ajax({
return false; type: "POST",
}); url: $SCRIPT_ROOT + '/cloneRepository',
function configRadio(){ data: {
$("#modelist li").each(function(index) { repo: repo_url,
var boxselector = "#box" + index; name: $("input#workdir").val() + "/" + $("input#name").val(),
if($(this).hasClass('checked')){ email: email,
$(this).removeClass('checked'); user: name
$(boxselector).slideUp("normal"); },
} success: function (data) {
if($(this).find("input:radio").is(':checked')){ if (data.code === 1) {
$(this).addClass('checked'); $("#file_navigation").fadeIn('normal');
//change content here $("#error").Popup("Your repository is cloned!", {type: 'confirm', duration: 3000});
$(boxselector).slideDown("normal"); $("input#repo").val("Enter the url of your repository...");
} $("input#name").val("Enter the project name...");
if(index != 2){ $('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT + "/fileBrowser", root: "workspace/"});
$("input#password").val(""); } else {
$("input#cpassword").val(""); $("#error").Popup(data.result, {type: 'error'});
} }
}); $("#imgwaitting").hide();
} $("#clone").empty();
$("#clone").append("Clone");
send = false;
},
error: function (request, error) {
$("#error").Popup("unable to clone your project, please check your internet connection", {type: 'error', duration: 3000});
$("#imgwaitting").hide();
$("#clone").empty();
$("#clone").append("Clone");
}
});
return false;
});
function selectFile(file){ function selectFile(file) {
//nothing //nothing
return; return;
} }
}); });
\ No newline at end of file
$(document).ready(function() { /*jslint undef: true */
var editor; /*global $, document, window, alert, $SCRIPT_ROOT, setInput, ace */
setupFileTree(); /* vim: set et sts=4: */
$($('#slappart li')[0]).find('input:radio').attr('checked', true);
$('.menu-box-right>div').css('min-height', $('#slappart li').length * 26 + 20 + 'px');
configRadio();
var send = false;
var lastli = null;
var partitionAmount = $('input#partitionAmount').val();
$('#slappart li').each(function() {
lastli = $(this);
$(this).find('input:radio').change(function() {
configRadio();
});
});
if (lastli) {lastli.css('border-bottom', 'none');}
$('#parameterkw').slideBox('show'); $(document).ready(function () {
setupSlappart(); "use strict";
$('#reloadfiles').click(function() {
setupFileTree(); var editor,
}); send = false,
$('#refresh').click(function() { lastli = null,
if (send) return; partitionAmount = $('input#partitionAmount').val();
$('#imgwaitting').fadeIn();
$.ajax({ function setupTextarea($txt) {
type: 'GET', var size = Number($txt.attr('id').split('_')[1]),
url: $SCRIPT_ROOT + '/supervisordStatus', hiddenDiv = $(document.createElement('div')),
data: '', content = null;
success: function(data) { hiddenDiv.attr('id', 'div_' + size);
if (data.code == 1) { hiddenDiv.addClass('hiddendiv');
$('#supervisordcontent').empty(); $('div#parameterkw').append(hiddenDiv);
$('#supervisordcontent').append(data.result); $txt.keyup(function () {
} content = $txt.val().replace(/\n/g, '<br>');
$('#imgwaitting').fadeOut(); hiddenDiv.html(content);
} if (hiddenDiv.height() > $txt.height() && hiddenDiv.height() > 120) {
}); return;
return false;
});
$('#add_attribute').click(function() {
var size = Number($('#partitionParameter > tbody > tr').last().attr('id').split('_')[1]) + 1;
var row = "<tr id='row_" + size + "'><td class='first'><input type='text' name='txt_" + size + "' id='txt_" + size + "'></td>" +
"<td style='padding:6px'><textarea class='slap' id='value_" + size + "'></textarea>" +
"</td><td valign='middle'><span style='margin-left: 10px;' id='btn_" + size + "' class='close'></span></td></tr>";
$('#partitionParameter').append(row);
setInput($('input#txt_' + size));
setupTextarea($('textarea#value_' + size));
$('#btn_' + size).click(function() {
var index = $(this).attr('id').split('_')[1];
$('tr#row_' + index).remove();
});
return false;
});
$('#updateParameters').click(function() {
updateParameter();
return false;
});
$('#xmlview').click(function() {
var content = '<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">' +
'INSTANCE PARAMETERS: Load XML file</h2><p id="xmllog" class="message"><br/></p>';
content += '<div class="main_content" style="height:230px"><pre id="editor"></pre></div>' +
'<input type=submit value="Load" id="loadxml" class="button">';
$.ajax({
type: 'GET',
url: $SCRIPT_ROOT + '/getParameterXml/xml',
success: function(data){
if(data.code == 1){
$("#inline_instance").html(content);
setupEditor(true);
$("a#inlineInstance").colorbox({inline:true, width: "600px", height: "410px", onComplete:function(){
editor.getSession().setValue(data.result);
}});
$("a#inlineInstance").click();
$("#loadxml").click(function(){
//Parse XML file
try {
var xmlDoc = $.parseXML(editor.getSession().getValue()), $xml = $(xmlDoc);
if ($xml.find('parsererror').length !== 0) {$('p#xmllog').html('Error: Invalid XML document!<br/>');return false;}
} catch (err) {
$('p#xmllog').html('Error: Invalid XML document!<br/>');return false;
}
$.ajax({
type: 'POST',
url: $SCRIPT_ROOT + '/saveParameterXml',
data: {software_type: '', parameter: editor.getSession().getValue()},
success: function(data) {
if (data.code == 1) {
location.href = $SCRIPT_ROOT + '/inspectInstance#tab3';
location.reload();
}
else {$('p#xmllog').html(data.result);}
} }
}); $txt.css('height', hiddenDiv.height() + 'px');
return false;
}); });
}
else {
$('#error').Popup(data.result, {type: 'error', duration: 5000});
}
}
});
});
//Load previous instance parameters
loadParameter();
$('a#parameterTab').click(function() {
var size = $('#partitionParameter > tbody > tr').length;
for (var i = 2; i <= size; i++) {
$('textarea#value_' + i).keyup();
} }
});
function setupFileTree(path){ function setupFileTree(path) {
var root = $("input#root").val(); var root = $("input#root").val();
if (root === '') return; if (root === '') {
if (path){ return;
root += '/' + path + '/'; }
if (path) {
root += '/' + path + '/';
} else {
root += '/';
}
$('#fileNavigator').gsFileManager({script: $SCRIPT_ROOT + "/fileBrowser", root: root});
} }
else{root += '/';}
$('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT+"/fileBrowser", root: root});
}
$("#parameter").load($SCRIPT_ROOT + '/getParameterXml'); function configRadio() {
$("#update").click(function(){ $('#slappart li').each(function () {
if($("#parameter").val() === ''){ var $radio = $(this).find('input:radio'),
$("#error").Popup("Can not save empty value!", {type:'alert', duration:3000}); boxselector = '#box' + $radio.attr('id');
if ($(this).hasClass('checked')) {
$(this).removeClass('checked');
$(boxselector).slideUp('normal');
}
if ($radio.is(':checked')) {
$(this).addClass('checked');
//change content here
$(boxselector).slideDown('normal');
}
});
} }
$.ajax({
type: 'POST', function setupSlappart() {
url: $SCRIPT_ROOT + '/saveParameterXml', var i, elt, fileId;
data: {parameter: $('#parameter').val().trim()}, for (i = 0; i < partitionAmount; i += 1) {
success: function(data) { elt = $('#slappart' + i + 'Parameter');
if (data.code == 1) { fileId = $('#slappart' + i + 'Files');
$('#error').Popup('Instance parameters updated!', {type: 'info', duration: 3000});
if (elt && elt !== undefined) {
elt.click(function () {
alert($(this).html());
});
} }
else { if (fileId && fileId !== undefined) {
$('#error').Popup(data.result, {type: 'error', duration: 5000}); fileId.click(function () {
$('#instancetabfiles').click();
setupFileTree($(this).attr('rel'));
});
} }
} }
}); }
});
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 = '',
software_type_input_value = $('input#software_type').val(); software_type_input_value = $('input#software_type').val(),
if (software_type_input_value !== '' && software_type_input_value !== 'Software Type here...') { size = $('#partitionParameter > tbody > tr').length,
software_type = software_type_input_value; i;
if (software_type_input_value !== '' && software_type_input_value !== 'Software Type here...') {
software_type = software_type_input_value;
}
xml += '<instance>\n';
if (size > 1) {
for (i = 2; i <= size; i += 1) {
if ($('input#txt_' + i).val() !== '') {
xml += '<parameter id="' + $('input#txt_' + i).val() + '">' + $('textarea#value_' + i).val() + '</parameter>\n';
}
}
}
xml += '</instance>\n';
$.ajax({
type: 'POST',
url: $SCRIPT_ROOT + '/saveParameterXml',
data: {software_type: software_type, parameter: xml},
success: function (data) {
if (data.code === 1) {
$('#error').Popup('Instance parameters has been updated, please run your instance now!', {type: 'confirm', duration: 5000});
} else {
$('#error').Popup(data.result, {type: 'error', duration: 5000});
}
}
});
} }
xml += '<instance>\n';
var size = $('#partitionParameter > tbody > tr').length; function setupEditor(editable) {
if (size > 1) { editor = ace.edit('editor');
for (var i = 2; i <= size; i++) { editor.setTheme('ace/theme/crimson_editor');
if ($('input#txt_' + i).val() != '') {
xml += '<parameter id="' + $('input#txt_' + i).val() + '">' + $('textarea#value_' + i).val() + '</parameter>\n'; var CurentMode = require('ace/mode/text').Mode;
editor.getSession().setMode(new CurentMode());
editor.getSession().setTabSize(2);
editor.getSession().setUseSoftTabs(true);
editor.renderer.setHScrollBarAlwaysVisible(false);
if (!editable) {
editor.setReadOnly(true);
} }
}
} }
xml += '</instance>\n';
$.ajax({ function loadParameter() {
type: 'POST', $.ajax({
url: $SCRIPT_ROOT + '/saveParameterXml', type: 'GET',
data: {software_type: software_type, parameter: xml}, url: $SCRIPT_ROOT + '/getParameterXml/dict',
success: function(data) { success: function (data) {
if (data.code == 1) { var dict, propertie, size;
$('#error').Popup('Instance parameters has been updated, please run your instance now!', {type: 'confirm', duration: 5000}); if (data.code === 1) {
} dict = data.result.instance;
else { for (propertie in dict) {
$('#error').Popup(data.result, {type: 'error', duration: 5000}); $("#add_attribute").click();
} size = Number($("#partitionParameter > tbody > tr").last().attr('id').split('_')[1]);
$("input#txt_" + size).val(propertie);
$("textarea#value_" + size).val(dict[propertie]);
$("textarea#value_" + size).keyup();
}
} else {
$('#error').Popup(data.result, {type: 'error', duration: 5000});
}
}
});
} }
setupFileTree();
$($('#slappart li')[0]).find('input:radio').attr('checked', true);
$('.menu-box-right>div').css('min-height', $('#slappart li').length * 26 + 20 + 'px');
configRadio();
$('#slappart li').each(function () {
lastli = $(this);
$(this).find('input:radio').change(function () {
configRadio();
});
}); });
} if (lastli) {
function setupTextarea($txt) { lastli.css('border-bottom', 'none');
var size = Number($txt.attr('id').split('_')[1]); }
var hiddenDiv = $(document.createElement('div')),
content = null; $('#parameterkw').slideBox('show');
hiddenDiv.attr('id', 'div_' + size); setupSlappart();
hiddenDiv.addClass('hiddendiv'); $('#reloadfiles').click(function () {
$('div#parameterkw').append(hiddenDiv); setupFileTree();
$txt.keyup(function() {
content = $txt.val().replace(/\n/g, '<br>');
hiddenDiv.html(content);
if (hiddenDiv.height() > $txt.height() && hiddenDiv.height() > 120) {
return;
}
$txt.css('height', hiddenDiv.height() + 'px');
}); });
} $('#refresh').click(function () {
function loadParameter() { if (send) {
$.ajax({ return;
type: 'GET',
url: $SCRIPT_ROOT + '/getParameterXml/dict',
success: function(data){
if(data.code == 1){
var dict = data.result['instance'];
for (var propertie in dict){
$("#add_attribute").click();
var size = Number($("#partitionParameter > tbody > tr").last().attr('id').split('_')[1]);
$("input#txt_"+size).val(propertie);
$("textarea#value_"+size).val(dict[propertie]);
$("textarea#value_"+size).keyup();
} }
} $('#imgwaitting').fadeIn();
else { $.ajax({
$('#error').Popup(data.result, {type: 'error', duration: 5000}); type: 'GET',
} url: $SCRIPT_ROOT + '/supervisordStatus',
} data: '',
success: function (data) {
if (data.code === 1) {
$('#supervisordcontent').empty();
$('#supervisordcontent').append(data.result);
}
$('#imgwaitting').fadeOut();
}
});
return false;
});
$('#add_attribute').click(function () {
var size = Number($('#partitionParameter > tbody > tr').last().attr('id').split('_')[1]) + 1,
row = "<tr id='row_" + size + "'><td class='first'><input type='text' name='txt_" + size + "' id='txt_" + size + "'></td>" +
"<td style='padding:6px'><textarea class='slap' id='value_" + size + "'></textarea>" +
"</td><td valign='middle'><span style='margin-left: 10px;' id='btn_" + size + "' class='close'></span></td></tr>";
$('#partitionParameter').append(row);
setInput($('input#txt_' + size));
setupTextarea($('textarea#value_' + size));
$('#btn_' + size).click(function () {
var index = $(this).attr('id').split('_')[1];
$('tr#row_' + index).remove();
});
return false;
});
$('#updateParameters').click(function () {
updateParameter();
return false;
}); });
} $('#xmlview').click(function () {
function configRadio() { var content = '<h2 style="color: #4c6172; font: 18px \'Helvetica Neue\', Helvetica, Arial, sans-serif;">' +
$('#slappart li').each(function() { 'INSTANCE PARAMETERS: Load XML file</h2><p id="xmllog" class="message"><br/></p>';
var $radio = $(this).find('input:radio'); content += '<div class="main_content" style="height:230px"><pre id="editor"></pre></div>' +
var boxselector = '#box' + $radio.attr('id'); '<input type=submit value="Load" id="loadxml" class="button">';
if ($(this).hasClass('checked')) { $.ajax({
$(this).removeClass('checked'); type: 'GET',
$(boxselector).slideUp('normal'); url: $SCRIPT_ROOT + '/getParameterXml/xml',
} success: function (data) {
if ($radio.is(':checked')) { if (data.code === 1) {
$(this).addClass('checked'); $("#loadxml").unbind('click');
//change content here $.colorbox.remove();
$(boxselector).slideDown('normal'); $("#inline_instance").empty();
$("#inline_instance").html(content);
setupEditor(true);
$("a#inlineInstance").colorbox(
{
inline: true,
width: "600px",
height: "410px",
onComplete: function () {
editor.getSession().setValue(data.result);
}
}
);
} $("a#inlineInstance").click();
$("#loadxml").click(function () {
//Parse XML file
try {
var xmlDoc = $.parseXML(editor.getSession().getValue()), $xml = $(xmlDoc);
if ($xml.find('parsererror').length !== 0) {
$('p#xmllog').html('Error: Invalid XML document!<br/>');
return false;
}
} catch (err) {
$('p#xmllog').html('Error: Invalid XML document!<br/>');
return false;
}
$.ajax({
type: 'POST',
url: $SCRIPT_ROOT + '/saveParameterXml',
data: {
software_type: '',
parameter: editor.getSession().getValue()
},
success: function (data) {
if (data.code === 1) {
window.location.href = $SCRIPT_ROOT + '/inspectInstance#tab3';
window.location.reload();
} else {
$('p#xmllog').html(data.result);
}
}
});
return false;
});
} else {
$('#error').Popup(data.result, {type: 'error', duration: 5000});
}
}
});
});
//Load previous instance parameters
loadParameter();
$('a#parameterTab').click(function () {
var i,
size = $('#partitionParameter > tbody > tr').length;
for (i = 2; i <= size; i += 1) {
$('textarea#value_' + i).keyup();
}
}); });
}
function setupBox() {
var state = $('#softwareType').css('display');
if (state == 'none') {
$('#softwareType').slideDown('normal');
$('#softwareTypeHead').removeClass('hide');
$('#softwareTypeHead').addClass('show');
}
else {
$('#softwareType').slideUp('normal');
$('#softwareTypeHead').removeClass('show');
$('#softwareTypeHead').addClass('hide');
}
}
function setupEditor(editable) {
editor = ace.edit('editor');
editor.setTheme('ace/theme/crimson_editor');
var CurentMode = require('ace/mode/text').Mode; $("#parameter").load($SCRIPT_ROOT + '/getParameterXml');
editor.getSession().setMode(new CurentMode()); $("#update").click(function () {
editor.getSession().setTabSize(2); if ($("#parameter").val() === '') {
editor.getSession().setUseSoftTabs(true); $("#error").Popup("Can not save empty value!", {type: 'alert', duration: 3000});
editor.renderer.setHScrollBarAlwaysVisible(false); }
if (!editable) {editor.setReadOnly(true);} $.ajax({
} type: 'POST',
function setupSlappart() { url: $SCRIPT_ROOT + '/saveParameterXml',
for (var i = 0; i < partitionAmount; i++) { data: {parameter: $('#parameter').val().trim()},
var elt = $('#slappart' + i + 'Parameter'); success: function (data) {
var fileId = $('#slappart' + i + 'Files'); if (data.code === 1) {
if (elt && elt !== undefined) elt.click(function() { $('#error').Popup('Instance parameters updated!', {type: 'info', duration: 3000});
alert($(this).html()); } else {
}); $('#error').Popup(data.result, {type: 'error', duration: 5000});
if (fileId && fileId !== undefined) fileId.click(function() { }
$('#instancetabfiles').click(); }
setupFileTree($(this).attr('rel')); });
}); });
function setupBox() {
var state = $('#softwareType').css('display');
if (state === 'none') {
$('#softwareType').slideDown('normal');
$('#softwareTypeHead').removeClass('hide');
$('#softwareTypeHead').addClass('show');
} else {
$('#softwareType').slideUp('normal');
$('#softwareTypeHead').removeClass('show');
$('#softwareTypeHead').addClass('hide');
}
} }
}
}); });
$(document).ready( function() { /*jslint undef: true */
var editor; /*global $, document, window, $SCRIPT_ROOT, ace */
var send = false; /* vim: set et sts=4: */
var runnerDir = $("input#runnerdir").val();
$("#reloadfiles").click(function(){
fillContent();
});
fillContent();
function fillContent(){
$('#fileNavigator').gsFileManager({ script: $SCRIPT_ROOT+"/fileBrowser", root: runnerDir});
}
$("#open").click(function(){ $(document).ready(function () {
var elt = $("option:selected", $("#softwarelist")); "use strict";
if(elt.val() === "No Software Release found"){
$("#error").Popup("Please select your Software Release", {type:'alert', duration:5000}); var editor,
return false; send = false,
runnerDir = $("input#runnerdir").val();
function fillContent() {
$('#fileNavigator').gsFileManager({script: $SCRIPT_ROOT + "/fileBrowser", root: runnerDir});
} }
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/setCurrentProject',
data: "path=" + elt.attr('rel'),
success: function(data){
if(data.code == 1){
location.href = $SCRIPT_ROOT + '/editSoftwareProfile'
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
}
});
return false;
});
$("#delete").click(function(){ $("#reloadfiles").click(function () {
if($("#softwarelist").val() === "No Software Release found"){ fillContent();
$("#error").Popup("Please select your Software Release", {type:'alert', duration:5000}); });
fillContent();
$("#open").click(function () {
var elt = $("option:selected", $("#softwarelist"));
if (elt.val() === "No Software Release found") {
$("#error").Popup("Please select your Software Release", {type: 'alert', duration: 5000});
return false;
}
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/setCurrentProject',
data: "path=" + elt.attr('rel'),
success: function (data) {
if (data.code === 1) {
window.location.href = $SCRIPT_ROOT + '/editSoftwareProfile';
} else {
$("#error").Popup(data.result, {type: 'error', duration: 5000});
}
}
});
return false; return false;
} });
if(send) return;
if(!window.confirm("Do you really want to delete this software release?")){
return;
}
send = false;
var elt = $("option:selected", $("#softwarelist"));
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/removeSoftwareDir',
data: {md5:$("#softwarelist").val(), title:elt.attr('title')},
success: function(data){
if(data.code == 1){
$("#softwarelist").empty();
for(var i=0; i<data.result.length; i++){
$("#softwarelist").append('<option value="' + data.result[i]['md5'] +
'" title="' + data.result[i]['title'] +'" rel="' +
data.result[i]['path'] +'">' + data.result[i]['title'] + '</option>');
}
if(data.result.length < 1){
$("#softwarelist").append('<option>No Software Release found</option>');
$('#fileTree').empty();
}
fillContent();
$("#error").Popup("Operation complete, Selected Software Release has been delete!", {type:'confirm', duration:5000});
}
else{
$("#error").Popup(data.result, {type:'error'});
}
send = false;
}
});
return false;
});
function setupEditor(){ $("#delete").click(function () {
editor = ace.edit("editor"); if ($("#softwarelist").val() === "No Software Release found") {
editor.setTheme("ace/theme/crimson_editor"); $("#error").Popup("Please select your Software Release", {type: 'alert', duration: 5000});
return false;
}
if (send) {
return;
}
if (!window.confirm("Do you really want to delete this software release?")) {
return;
}
send = false;
var elt = $("option:selected", $("#softwarelist"));
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/removeSoftwareDir',
data: {
md5: $("#softwarelist").val(),
title: elt.attr('title')
},
success: function (data) {
var i;
if (data.code === 1) {
$("#softwarelist").empty();
for (i = 0; i < data.result.length; i += 1) {
$("#softwarelist").append('<option value="' + data.result[i].md5 +
'" title="' + data.result[i].title + '" rel="' +
data.result[i].path + '">' + data.result[i].title + '</option>');
}
if (data.result.length < 1) {
$("#softwarelist").append('<option>No Software Release found</option>');
$('#fileTree').empty();
}
fillContent();
$("#error").Popup("Operation complete, Selected Software Release has been delete!",
{type: 'confirm', duration: 5000});
} else {
$("#error").Popup(data.result, {type: 'error'});
}
send = false;
}
});
return false;
});
var CurentMode = require("ace/mode/text").Mode; function setupEditor() {
editor.getSession().setMode(new CurentMode()); editor = ace.edit("editor");
editor.getSession().setTabSize(2); editor.setTheme("ace/theme/crimson_editor");
editor.getSession().setUseSoftTabs(true);
editor.renderer.setHScrollBarAlwaysVisible(false); var CurentMode = require("ace/mode/text").Mode;
editor.setReadOnly(true); editor.getSession().setMode(new CurentMode());
} editor.getSession().setTabSize(2);
}); editor.getSession().setUseSoftTabs(true);
\ No newline at end of file editor.renderer.setHScrollBarAlwaysVisible(false);
editor.setReadOnly(true);
}
});
$(document).ready( function() { /*jslint undef: true */
var send = false; /*global $, document, window, $SCRIPT_ROOT */
//change background /* vim: set et sts=4: */
$("body").css("background", "#9C9C9C");
$("#login").click(function(){ $(document).ready(function () {
if (send) return false; "use strict";
if($("input#clogin").val() === "" || !$("input#clogin").val().match(/^[\w\d\.-]+$/)){
$("#error").Popup("Please enter a valid user name", {type:'alert', duration:3000}); var send = false;
return false; //change background
} $("body").css("background", "#9C9C9C");
if($("input#cpwd").val() === "" || $("input#cpwd").val() ==="******"){ $("#login").click(function () {
$("#error").Popup("Please enter your password", {type:'alert', duration:3000}); if (send) {
return false; return false;
} }
send = true; if ($("input#clogin").val() === "" || !$("input#clogin").val().match(/^[\w\d\.\-]+$/)) {
var param = {clogin:$("input#clogin").val(), cpwd:$("input#cpwd").val()}; $("#error").Popup("Please enter a valid user name", {type: 'alert', duration: 3000});
var url = $SCRIPT_ROOT + "/doLogin"; return false;
$("#login").removeClass("button").addClass("dsblebutton"); }
$.post(url, param, function(data) { if ($("input#cpwd").val() === "" || $("input#cpwd").val() === "******") {
if (data.code==1){ $("#error").Popup("Please enter your password", {type: 'alert', duration: 3000});
location.href = $SCRIPT_ROOT + '/'; return false;
} }
else{ send = true;
$("#error").Popup(data.result, {type:'alert', duration:3000}); var param = { clogin: $("input#clogin").val(), cpwd: $("input#cpwd").val() },
} url = $SCRIPT_ROOT + "/doLogin";
})
.error(function() { $("#login").removeClass("button").addClass("dsblebutton");
$("#error").Popup("Cannot send your account identifier please try again!!", $.post(url, param, function (data) {
{type:'alert', duration:3000});}) if (data.code === 1) {
.complete(function() { window.location.href = $SCRIPT_ROOT + '/';
$("#login").removeClass('dsblebutton').addClass('button'); } else {
send = false; $("#error").Popup(data.result, {type: 'alert', duration: 3000});
}
})
.error(function () {
$("#error").Popup("Cannot send your account identifier please try again!!",
{type: 'alert', duration: 3000});
})
.complete(function () {
$("#login").removeClass('dsblebutton').addClass('button');
send = false;
});
return false;
}); });
return false; });
});
});
\ No newline at end of file
/*jslint undef: true */
/*global $, window, $SCRIPT_ROOT, setRunningState, setCookie, getCookie, deleteCookie */
/*global currentState: true, running: true, $current: true, processType: true, currentProcess: true */
/*global sendStop: true, processState: true, openedlogpage: true, logReadingPosition: true, speed: true */
/*global isRunning: true */
/* vim: set et sts=4: */
//Global Traitment!!! //Global Traitment!!!
var url = $SCRIPT_ROOT + "/slapgridResult"
var url = $SCRIPT_ROOT + "/slapgridResult";
var currentState = false; var currentState = false;
var running = true; var running = true;
var $current; var $current;
...@@ -10,151 +18,207 @@ var processState = "Checking"; //define slapgrid running state ...@@ -10,151 +18,207 @@ var processState = "Checking"; //define slapgrid running state
var openedlogpage = ""; //content software or instance if the current page is software or instance log, otherwise nothing var openedlogpage = ""; //content software or instance if the current page is software or instance log, otherwise nothing
var logReadingPosition = 0; var logReadingPosition = 0;
var speed = 5000; var speed = 5000;
var isRunning = function(){ var maxLogSize = 100000; //Define the max limit of log to display ~ 2500 lines
if (running){ var currentLogSize = 0; //Define the size of log actually displayed
$("#error").Popup("Slapgrid is currently under execution!", {type:'alert', duration:3000}); var isRunning = function () {
} "use strict";
return running; if (running) {
$("#error").Popup("Slapgrid is currently under execution!",
{type: 'alert', duration: 3000});
}
return running;
};
function setSpeed(value) {
"use strict";
if (openedlogpage === "") {
speed = 5000;
} else {
speed = value;
}
} }
function setSpeed(value){
if (openedlogpage == ""){ function clearAll(setStop) {
speed = 5000; "use strict";
} currentState = false;
else{ speed=value;} running = setStop;
} }
function getRunningState(){
var param = {position:logReadingPosition, log:(processState!="Checking" && openedlogpage==processType.toLowerCase())? openedlogpage:""} function removeFirstLog(){
var jqxhr = $.post(url, param, function(data) { "use strict";
setRunningState(data) currentLogSize -= parseInt($("#salpgridLog p:first-child").attr('rel'), 10);
logReadingPosition = data.content.position; $("#salpgridLog p:first-child").remove();
if(data.content.content != ""){
$("#salpgridLog").append(data.content.content.toHtmlChar());
$("#salpgridLog")
.scrollTop($("#salpgridLog")[0].scrollHeight - $("#salpgridLog")
.height());
}
if (running && processState=="Checking" && openedlogpage != ""){$("#salpgridLog").show();$("#manualLog").hide();}
processState = (running)?"Running":"Stopped";
})
.error(function() { clearAll(false); })
.complete(function() {
if (running){
setTimeout(function(){
getRunningState();
}, speed);
}
});
} }
function clearAll(setStop){
currentState = false; function getRunningState() {
running = setStop; "use strict";
var size = 0;
var log_info = "";
var param = {
position: logReadingPosition,
log: (processState !== "Checking" && openedlogpage === processType.toLowerCase()) ? openedlogpage : ""
},
jqxhr = $.post(url, param, function (data) {
setRunningState(data);
size = data.content.position - logReadingPosition;
if (logReadingPosition !== 0 && data.content.truncated){
log_info = "<p class='info' rel='0'>SLAPRUNNER INFO: SLAPGRID-LOG HAS BEEN TRUNCATED HERE. To see full log reload your log page</p>";
}
logReadingPosition = data.content.position;
if (data.content.content !== "") {
if (data.content.content !== "") {
$("#salpgridLog").append(log_info + "<p rel='" + size + "'>" + data.content.content.toHtmlChar() + "</p>");
$("#salpgridLog")
.scrollTop($("#salpgridLog")[0].scrollHeight - $("#salpgridLog").height());
}
}
if (running && processState === "Checking" && openedlogpage !== "") {
$("#salpgridLog").show();
$("#manualLog").hide();
}
processState = running ? "Running" : "Stopped";
currentLogSize += parseInt(size, 10);
if (currentLogSize > maxLogSize){
//Remove the first element into log div
removeFirstLog();
if (currentLogSize > maxLogSize){
removeFirstLog(); //in cas of previous <p/> size is 0
}
}
})
.error(function () {
clearAll(false);
})
.complete(function () {
if (running) {
setTimeout(function () {
getRunningState();
}, speed);
}
});
} }
function bindRun(){
$("#softrun").click(function(){ function stopProcess() {
if($("#softrun").text() == "Stop"){ "use strict";
stopProcess(); if (sendStop) {
} return;
else{
if(!isRunning()){
setCookie("slapgridCMD", "Software");
location.href = $SCRIPT_ROOT + "/viewSoftwareLog";
}
}
return false;
});
$("#instrun").click(function(){
if($("#instrun").text() == "Stop"){
stopProcess();
} }
else{ if (running) {
if(!isRunning()){ sendStop = true;
setCookie("slapgridCMD", "Instance");
location.href = $SCRIPT_ROOT + "/viewInstanceLog"; var urlfor = $SCRIPT_ROOT + "stopSlapgrid",
} type = "slapgrid-sr";
if ($("#instrun").text() === "Stop instance") {
type = "slapgrid-cp";
}
$.post(urlfor, {type: type}, function (data) {
//if (data.result) {
//$("#error").Popup("Failled to run Slapgrid", {type:'error', duration:3000}); });
//}
})
.error(function () {
$("#error").Popup("Failed to stop Slapgrid process", {type: 'error', duration: 3000});
})
.complete(function () {
sendStop = false;
processState = "Stopped";
});
} }
return false;
});
} }
function setRunningState(data){
if (data.result){ function bindRun() {
if(!currentState){ "use strict";
$("#running").show(); $("#softrun").click(function () {
running = true; if ($("#softrun").text() === "Stop software") {
//change run menu title and style stopProcess();
if(data.software){ } else {
$("#softrun").empty(); if (!isRunning()) {
$("#softrun").append("Stop"); setCookie("slapgridCMD", "Software");
$("#softrun").css("color", "#0271BF"); window.location.href = $SCRIPT_ROOT + "/viewSoftwareLog";
$current = $("#softrun"); }
processType = "Software"; }
} return false;
if(data.instance){ });
$("#instrun").empty(); $("#instrun").click(function () {
$("#instrun").append("Stop"); if ($("#instrun").text() === "Stop instance") {
$("#instrun").css("color", "#0271BF"); stopProcess();
$current = $("#instrun"); } else {
processType = "Instance"; if (!isRunning()) {
} setCookie("slapgridCMD", "Instance");
} window.location.href = $SCRIPT_ROOT + "/viewInstanceLog";
} }
else{ }
$("#running").hide(); return false;
running = false; //nothing is currently running });
if ($current != undefined){
$current.empty();
$current.append("Run");
$current.css("color", "#000");
$current = undefined;
currentState = false;
$("#error").Popup("Slapgrid completely finish running your " + processType + " Profile", {type:'info', duration:3000});
}
}
currentState = data.result;
} }
function runProcess(urlfor, data){
if(!isRunning()){ function setRunningState(data) {
running = true; "use strict";
processState = "Running"; if (data.result) {
currentProcess = $.post(urlfor) if (!currentState) {
.error(function() { $("#running").show();
$("#error").Popup("Failled to run Slapgrid", {type:'error', duration:3000}); }); running = true;
setRunningState(data); //change run menu title and style
setTimeout("getRunningState()", 5000); if (data.software) {
} $("#softrun").empty();
$("#softrun").append("Stop software");
$("#softrun").css("color", "#0271BF");
$current = $("#softrun");
processType = "Software";
}
if (data.instance) {
$("#instrun").empty();
$("#instrun").append("Stop instance");
$("#instrun").css("color", "#0271BF");
$current = $("#instrun");
processType = "Instance";
}
}
} else {
$("#running").hide();
running = false; //nothing is currently running
if ($current !== undefined) {
$current.empty();
$current.append("Run " + processType.toLowerCase());
$current.css("color", "#275777");
$current = undefined;
currentState = false;
$("#error").Popup("Slapgrid finished running your " + processType + " Profile", {type: 'info', duration: 3000});
}
}
currentState = data.result;
} }
function stopProcess(){
if (sendStop) return; function runProcess(urlfor, data) {
if (running){ "use strict";
sendStop = true; if (!isRunning()) {
var urlfor = $SCRIPT_ROOT + "stopSlapgrid" running = true;
var type = "slapgrid-sr.pid"; processState = "Running";
if($("#instrun").text() == "Stop"){ currentProcess = $.post(urlfor)
type = "slapgrid-cp.pid"; .error(function () {
$("#error").Popup("Failled to run Slapgrid", {type: 'error', duration: 3000});
});
setRunningState(data);
setTimeout(getRunningState, 6000);
} }
$.post(urlfor, {type:type}, function(data){
//if (data.result){
//$("#error").Popup("Failled to run Slapgrid", {type:'error', duration:3000}); });
//}
})
.error(function() {
$("#error").Popup("Failled to stop Slapgrid process", {type:'error', duration:3000}); })
.complete(function() {sendStop = false;processState="Stopped";});
}
} }
function checkSavedCmd(){ function checkSavedCmd() {
var result = getCookie("slapgridCMD"); "use strict";
if (!result) return false; var result = getCookie("slapgridCMD");
if (result == "Software"){ if (!result) {
running = false; return false;
runProcess(($SCRIPT_ROOT + "/runSoftwareProfile"), }
{result: true, instance:false, software:true}); if (result === "Software") {
} running = false;
else if(result == "Instance"){ runProcess(($SCRIPT_ROOT + "/runSoftwareProfile"),
running = false; {result: true, instance: false, software: true});
runProcess(($SCRIPT_ROOT + "/runInstanceProfile"), } else if (result === "Instance") {
{result: true, instance:true, software:false}); running = false;
} runProcess(($SCRIPT_ROOT + "/runInstanceProfile"),
deleteCookie("slapgridCMD"); {result: true, instance: true, software: false});
return (result != null); }
} deleteCookie("slapgridCMD");
\ No newline at end of file return (result !== null);
}
$(document).ready( function() { /*jslint undef: true */
var method = $("input#method").val(); /*global $, document, window, $SCRIPT_ROOT */
var workdir = $("input#workdir").val(); /* vim: set et sts=4: */
if (method != "file"){
script = "/openFolder"; $(document).ready(function () {
$('#fileTree').fileTree({ root: workdir, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) { "use strict";
selectFile(file);
}); var method = $("input#method").val(),
} workdir = $("input#workdir").val();
$("input#subfolder").val("");
$("#create").click(function(){ function checkFolder(path) {
repo_url = $("input#software").val(); $.ajax({
if($("input#software").val() == "" || !$("input#software").val().match(/^[\w\d._-]+$/)){ type: "POST",
$("#error").Popup("Invalid Software name", {type:'alert', duration:3000}) url: $SCRIPT_ROOT + '/checkFolder',
return false; data: "path=" + path,
} success: function (data) {
if($("input#subfolder").val() == ""){ var path = data.result;
$("#error").Popup("Select the parent folder of your software!", {type:'alert', duration:3000}) $("input#path").val(path);
return false; if (path !== "") {
} $("#check").fadeIn('normal');
$.ajax({ } else {
type: "POST", $("#check").hide();
url: $SCRIPT_ROOT + '/createSoftware', }
data: "folder=" + $("input#subfolder").val() + $("input#software").val(), }
success: function(data){ });
if(data.code == 1){ return "";
location.href = $SCRIPT_ROOT + '/editSoftwareProfile' }
}
else{ function selectFile(file) {
$("#error").Popup(data.result, {type:'error', duration:5000}) $("#info").empty();
$("input#subfolder").val(file);
} if (method === "open") {
} $("#info").append("Selection: " + file);
}); checkFolder(file);
return false; } else {
}); if ($("input#software").val() !== "" && $("input#software").val().match(/^[\w\d._\-]+$/)) {
$("#info").append("New Software in: " + file + $("input#software").val());
$("#open").click(function(){ } else {
$("#flash").fadeOut('normal'); $("#info").append("Selection: " + file);
$("#flash").empty(); }
$("#flash").fadeIn('normal'); }
if($("input#path").val() == ""){ return;
$("#error").Popup("Select a valid Software Release folder!", {type:'alert', duration:3000}) }
return false;
} if (method !== "file") {
$.ajax({ $('#fileTree').fileTree({root: workdir, script: $SCRIPT_ROOT + '/openFolder', folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function (file) {
type: "POST", selectFile(file);
url: $SCRIPT_ROOT + '/setCurrentProject', });
data: "path=" + $("input#path").val(), }
success: function(data){ $("input#subfolder").val("");
if(data.code == 1){ $("#create").click(function () {
location.href = $SCRIPT_ROOT + '/editSoftwareProfile' if ($("input#software").val() === "" || !$("input#software").val().match(/^[\w\d._\-]+$/)) {
} $("#error").Popup("Invalid Software name", {type: 'alert', duration: 3000});
else{ return false;
$("#error").Popup(data.result, {type:'error', duration:5000}) }
} if ($("input#subfolder").val() === "") {
} $("#error").Popup("Select the parent folder of your software!", {type: 'alert', duration: 3000});
}); return false;
return false; }
}); $.ajax({
type: "POST",
function selectFile(file){ url: $SCRIPT_ROOT + '/createSoftware',
$("#info").empty(); data: "folder=" + $("input#subfolder").val() + $("input#software").val(),
$("input#subfolder").val(file); success: function (data) {
path = ""; if (data.code === 1) {
if(method == "open"){ window.location.href = $SCRIPT_ROOT + '/editSoftwareProfile';
$("#info").append("Selection: " + file); } else {
checkFolder(file); $("#error").Popup(data.result, {type: 'error', duration: 5000});
} }
else{ }
if($("input#software").val() != "" && $("input#software").val().match(/^[\w\d._-]+$/)){ });
$("#info").append("New Software in: " + file + $("input#software").val()); return false;
} });
else{
$("#info").append("Selection: " + file); $("#open").click(function () {
} $("#flash").fadeOut('normal');
} $("#flash").empty();
return; $("#flash").fadeIn('normal');
} if ($("input#path").val() === "") {
$("#error").Popup("Select a valid Software Release folder!", {type: 'alert', duration: 3000});
function checkFolder(path){ return false;
$.ajax({ }
type: "POST", $.ajax({
url: $SCRIPT_ROOT + '/checkFolder', type: "POST",
data: "path=" + path, url: $SCRIPT_ROOT + '/setCurrentProject',
success: function(data){ data: "path=" + $("input#path").val(),
var path = data.result; success: function (data) {
$("input#path").val(path); if (data.code === 1) {
if (path != ""){ window.location.href = $SCRIPT_ROOT + '/editSoftwareProfile';
$("#check").fadeIn('normal'); } else {
} $("#error").Popup(data.result, {type: 'error', duration: 5000});
else{ }
$("#check").hide(); }
} });
} return false;
}); });
return ""; });
}
});
\ No newline at end of file
$(document).ready( function() { /*jslint undef: true */
var send = false; /*global $, document, $SCRIPT_ROOT */
var getStatus; /* vim: set et sts=4: */
gitStatus();
$("#project").change(function(){ $(document).ready(function () {
if (send){ "use strict";
getStatus.abort();
send=false; var send = false,
} getStatus;
gitStatus();
}); function loadBranch(branch) {
$("#activebranch").change(function(){ var i, selected;
var branch = $("#activebranch").val(); $("#activebranch").empty();
var project = $("#project").val(); for (i = 0; i < branch.length; i += 1) {
$.ajax({ selected = (branch[i].indexOf('*') === 0) ? "selected" : "";
type: "POST", $("#activebranch").append("<option value='" + branch[i] +
url: $SCRIPT_ROOT + '/changeBranch', "' " + selected + ">" + branch[i] + "</option>");
data: "project=" + $("input#workdir").val() + "/" + project + "&name=" + branch, }
success: function(data){ }
if(data.code == 1){
gitStatus(); function gitStatus() {
} var project = $("#project").val(),
else{ urldata = $("input#workdir").val() + "/" + project;
$("#error").Popup(data.result, {type:'error', duration:5000});
} $("#status").empty();
} $("#push").hide();
}); $("#flash").empty();
}); if (project === "") {
$("#addbranch").click(function(){ $("#status").append("<h2>Please select one project...</h2><br/><br/>");
checkout("1"); $("#branchlist").hide();
return false; return;
}); }
$("#docheckout").click(function(){ send = true;
checkout("0"); getStatus = $.ajax({
return false; type: "POST",
}); url: $SCRIPT_ROOT + '/getProjectStatus',
$("#commit").click(function(){ data: "project=" + urldata,
if($("input#commitmsg").val() == "" || success: function (data) {
$("input#commitmsg").val() == "Enter message..."){ var message;
$("#error").Popup("Please Enter the commit message", {type:'alert', duration:3000});
return false; if (data.code === 1) {
} $("#branchlist").show();
if (send){ $("#status").append("<h2>Your Repository status</h2>");
return false; message = data.result.split('\n').join('<br/>');
} //alert(message);
send = true; $("#status").append("<p>" + message + "</p>");
var project = $("#project").val(); if (data.dirty) {
$("#imgwaitting").fadeIn('normal'); $("#push").show();
$("#commit").empty(); $("#status").append("<br/><h2>Display Diff for current Project</h2>");
$("#commit").attr("value", "Wait..."); $("#status").append("<p style='font-size:15px;'>You have changes in your project." +
$.ajax({ " <a href='" + $SCRIPT_ROOT + "/getProjectDiff/"
type: "POST", + encodeURI(project) + "'>Watch the diff</a></p>");
url: $SCRIPT_ROOT + '/pushProjectFiles', }
data: {project: $("input#workdir").val() + "/" + project, msg: $("input#commitmsg").val()}, loadBranch(data.branch);
success: function(data){ } else {
if(data.code == 1){ $("#error").Popup(data.result, {type: 'error', duration: 5000});
if (data.result != ""){ }
$("#error").Popup(data.result, {type:'error', duration:5000}); send = false;
} }
else });
$("#error").Popup("Commit done!", {type:'confirm', duration:3000}); }
gitStatus();
} function checkout(mode) {
else{ if ($("input#branchname").val() === "" ||
$("#error").Popup(data.result, {type:'error'}); $("input#branchname").val() === "Enter the branch name...") {
} $("#error").Popup("Please Enter the branch name", {type: 'alert', duration: 3000});
$("#imgwaitting").hide() return false;
$("#commit").empty(); }
$("#commit").attr("value", "Commit"); var project = $("#project").val(),
send = false; branch = $("input#branchname").val();
} $.ajax({
}); type: "POST",
return false; url: $SCRIPT_ROOT + '/newBranch',
}); data: {project: $("input#workdir").val() + "/" + project, name: branch, create: mode},
/* success: function (data) {
$("#pullbranch").click(function(){ if (data.code === 1) {
if (send){ $("input#branchname").val("Enter the branch name...");
return false; gitStatus();
} } else {
send = true; $("#error").Popup(data.result, {type: 'error'});
var project = $("#project").val(); }
$("#pullimgwaitting").fadeIn('normal'); }
$("#pullbranch").empty(); });
$("#pullbranch").attr("value", "Wait..."); return false;
$.ajax({ }
type: "POST",
url: $SCRIPT_ROOT + '/pullProjectFiles',
data: "project=" + $("input#workdir").val() + "/" + project, gitStatus();
success: function(data){
if(data.code == 1){ $("#project").change(function () {
if (data.result != ""){ if (send) {
error(data.result); getStatus.abort();
} send = false;
else }
error("Pull done!"); gitStatus();
gitStatus(); });
} $("#activebranch").change(function () {
else{ var branch = $("#activebranch").val(),
error(data.result); project = $("#project").val();
}
$("#pullimgwaitting").hide() $.ajax({
$("#pullbranch").empty(); type: "POST",
$("#pullbranch").attr("value", "Git Pull"); url: $SCRIPT_ROOT + '/changeBranch',
send = false; data: "project=" + $("input#workdir").val() + "/" + project + "&name=" + branch,
} success: function (data) {
}); if (data.code === 1) {
return false; gitStatus();
});*/ } else {
function gitStatus(){ $("#error").Popup(data.result, {type: 'error', duration: 5000});
var project = $("#project").val(); }
$("#status").empty(); }
$("#push").hide(); });
$("#flash").empty(); });
if (project == ""){ $("#addbranch").click(function () {
$("#status").append("<h2>Please select one project...</h2><br/><br/>"); checkout("1");
$("#branchlist").hide(); return false;
return; });
} $("#docheckout").click(function () {
send = true; checkout("0");
var urldata = $("input#workdir").val() + "/" + project; return false;
getStatus = $.ajax({ });
type: "POST", $("#commit").click(function () {
url: $SCRIPT_ROOT + '/getProjectStatus', if ($("input#commitmsg").val() === "" ||
data: "project=" + urldata, $("input#commitmsg").val() === "Enter message...") {
success: function(data){ $("#error").Popup("Please Enter the commit message", {type: 'alert', duration: 3000});
if(data.code == 1){ return false;
$("#branchlist").show(); }
$("#status").append("<h2>Your Repository status</h2>"); if (send) {
message = data.result.split('\n').join('<br/>'); return false;
//alert(message); }
$("#status").append("<p>" + message + "</p>"); send = true;
if(data.dirty){ var project = $("#project").val();
$("#push").show(); $("#imgwaitting").fadeIn('normal');
$("#status").append("<br/><h2>Display Diff for current Project</h2>"); $("#commit").empty();
$("#status").append("<p style='font-size:15px;'>You have changes in your project." + $("#commit").attr("value", "Wait...");
" <a href='" + $SCRIPT_ROOT + "/getProjectDiff/" $.ajax({
+ encodeURI(project) + "'>Watch the diff</a></p>"); type: "POST",
} url: $SCRIPT_ROOT + '/pushProjectFiles',
loadBranch(data.branch); data: {project: $("input#workdir").val() + "/" + project, msg: $("input#commitmsg").val()},
} success: function (data) {
else{ if (data.code === 1) {
$("#error").Popup(data.result, {type:'error', duration:5000}); if (data.result !== "") {
} $("#error").Popup(data.result, {type: 'error', duration: 5000});
send = false; } else {
} $("#error").Popup("Commit done!", {type: 'confirm', duration: 3000});
}); }
} gitStatus();
function checkout(mode){ } else {
if($("input#branchname").val() == "" || $("#error").Popup(data.result, {type: 'error'});
$("input#branchname").val() == "Enter the branch name..."){ }
$("#error").Popup("Please Enter the branch name", {type:'alert', duration:3000}); $("#imgwaitting").hide();
return false; $("#commit").empty();
} $("#commit").attr("value", "Commit");
var project = $("#project").val(); send = false;
var branch = $("input#branchname").val(); }
$.ajax({ });
type: "POST", return false;
url: $SCRIPT_ROOT + '/newBranch', });
data: {project:$("input#workdir").val() + "/" + project, name:branch, create:mode},
success: function(data){ /*
if(data.code == 1){ $("#pullbranch").click(function (){
$("input#branchname").val("Enter the branch name..."); if (send){
gitStatus(); return false;
} }
else{ send = true;
$("#error").Popup(data.result, {type:'error'}); var project = $("#project").val();
} $("#pullimgwaitting").fadeIn('normal');
} $("#pullbranch").empty();
}); $("#pullbranch").attr("value", "Wait...");
return false; $.ajax({
} type: "POST",
function loadBranch(branch){ url: $SCRIPT_ROOT + '/pullProjectFiles',
$("#activebranch").empty(); data: "project=" + $("input#workdir").val() + "/" + project,
for(i=0; i< branch.length; i++){ success: function (data){
selected = (branch[i].indexOf('*') == 0)? "selected":""; if (data.code == 1){
$("#activebranch").append("<option value='" + branch[i] + if (data.result != ""){
"' " + selected + ">" + branch[i] + "</option>"); error(data.result);
} }
} else
}); error("Pull done!");
\ No newline at end of file gitStatus();
} else {
error(data.result);
}
$("#pullimgwaitting").hide()
$("#pullbranch").empty();
$("#pullbranch").attr("value", "Git Pull");
send = false;
}
});
return false;
});*/
});
$(document).ready( function() { /*jslint undef: true */
var editor = ace.edit("editor"); /*global $, document, $SCRIPT_ROOT, ace */
editor.setTheme("ace/theme/crimson_editor"); /*global path: true */
/* vim: set et sts=4: */
var CurentMode = require("ace/mode/text").Mode;
editor.getSession().setMode(new CurentMode());
editor.getSession().setTabSize(2);
editor.getSession().setUseSoftTabs(true);
editor.renderer.setHScrollBarAlwaysVisible(false);
var script = "/readFolder"; $(document).ready(function () {
var softwareDisplay = true; "use strict";
var Mode = function(name, desc, clazz, extensions) {
this.name = name;
this.desc = desc;
this.clazz = clazz;
this.mode = new clazz();
this.mode.name = name;
this.extRe = new RegExp("^.*\\.(" + extensions.join("|") + ")$"); var editor = ace.edit("editor"),
}; CurrentMode,
var modes = [ script = "/readFolder",
new Mode("php", "PHP",require("ace/mode/php").Mode, ["php", "in", "inc"]), softwareDisplay = true,
new Mode("python", "Python", require("ace/mode/python").Mode, ["py"]), Mode,
new Mode("buildout", "Python Buildout config", require("ace/mode/buildout").Mode, ["cfg"]) modes,
]; projectDir = $("input#project").val(),
var projectDir = $("input#project").val(); workdir = $("input#workdir").val(),
var workdir = $("input#workdir").val(); currentProject = workdir + "/" + projectDir.replace(workdir, "").split('/')[1],
var currentProject = workdir + "/" + projectDir.replace(workdir, "").split('/')[1]; send = false,
var send = false; edit = false,
var edit = false; selection = "",
$('#fileTree').fileTree({ root: projectDir, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) { edit_status = "";
selectFile(file);
});
setDetailBox();
$("#add").click(function(){
var path = (softwareDisplay)? projectDir:currentProject;
if (send) return false;
if($("input#file").val() == "" ||
$("input#file").val() == "Enter name here..."){
$("#error").Popup("Please enter your file or folder name", {type:'alert', duration:3000});
return false;
}
if($("input#subfolder").val() != ""){
path = $("input#subfolder").val();
}
path = path + "/" + $("input#file").val();
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/createFile',
data: "file=" + path + "&type=" + $("#type").val(),
success: function(data){
if(data.code == 1){
switchContent();
$("input#file").val("");
$("#flash").fadeOut('normal');
$("#flash").empty();
$("#info").empty();
$("#info").append("Select parent directory or nothing for root...");
$("input#subfolder").val("");
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
return false;
});
$("#save").click(function(){ var base_path = function() {
if(!edit){ return softwareDisplay ? projectDir : currentProject;
$("#error").Popup("Please select the file to edit", {type:'alert', duration:3000}); }
return false;
}
if (send) return false;
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/saveFileContent',
data: {file: $("input#subfolder").val(), content: editor.getSession().getValue()},
success: function(data){
if(data.code == 1){
$("#error").Popup("File saved succefuly!", {type:'confirm', duration:3000});
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
return false;
});
$("#details_head").click(function(){ function setEditMode(file) {
setDetailBox(); var i,
}); CurrentMode = require("ace/mode/text").Mode;
editor.getSession().setMode(new CurrentMode());
for (i = 0; i < modes.length; i += 1) {
if (modes[i].extRe.test(file)) {
editor.getSession().setMode(modes[i].mode);
break;
}
}
}
$("#switch").click(function(){ function openFile(file) {
softwareDisplay = !softwareDisplay; if (send) {
switchContent(); return;
return false; }
}); send = true;
$("#getmd5").click(function(){ edit = false;
getmd5sum(); if (file.substr(-1) !== "/") {
return false; $.ajax({
}); type: "POST",
url: $SCRIPT_ROOT + '/getFileContent',
data: {file: file},
success: function (data) {
var name, start, path = file;
if (data.code === 1) {
$("#edit_info").empty();
name = file.split('/');
if (file.length > 60) {
//substring title.
start = file.length - 60;
path = "..." + file.substring(file.indexOf("/", (start + 1)));
}
$("#edit_info").append(" " + path);
$("a#option").show();
editor.getSession().setValue(data.result);
setEditMode(name[name.length - 1]);
edit = true;
$("input#subfolder").val(file);
$("span#edit_status").html("");
edit_status = "";
} else {
$("#error").Popup(data.result, {type: 'error', duration: 5000});
}
send = false;
}
});
} else {
$("#edit_info").empty();
$("#edit_info").append("No file in editor");
$("a#option").hide();
editor.getSession().setValue("");
}
return;
}
$("#clearselect").click(function(){ function selectFile(file) {
$("#info").empty(); $("#info").empty();
$("#info").append("Select directory or nothing for root directory..."); $("#info").append("Selection: " + file);
$("input#subfolder").val(""); selection = file;
$("#edit_info").empty(); return;
$("#edit_info").append("No file selected"); }
editor.getSession().setValue(""); /*
$("#md5sum").empty(); function setDetailBox() {
$("a#option").hide(); var state = $("#details_box").css("display");
return false; if (state === "none") {
}); $("#details_box").fadeIn("normal");
$("#adddevelop").click(function(){ $("#details_head").removeClass("hide");
var developList = new Array(); $("#details_head").addClass("show");
var i=0; } else {
$("#plist li").each(function(index){ $("#details_box").fadeOut("normal");
var elt = $(this).find("input:checkbox"); $("#details_head").removeClass("show");
if (elt.is(":checked")){ $("#details_head").addClass("hide");
developList[i] = workdir+"/"+elt.val(); }
i++; } */
elt.attr("checked", false);
}
});
if (developList.length > 0){setDevelop(developList);}
return false;
});
function getmd5sum(){ function switchContent() {
var file = $("input#subfolder").val(); if (!softwareDisplay) {
if (send) return; $("#switch").empty();
send =true $("#switch").append("Switch to Profile&nbsp;");
$.ajax({ $('#fileTreeFull').show();
type: "POST", $('#fileTree').hide();
url: $SCRIPT_ROOT + '/getmd5sum', } else {
data: {file: $("input#subfolder").val()}, $("#switch").empty();
success: function(data){ $("#switch").append("Switch to Project");
if(data.code == 1){ $('#fileTree').show();
$("#md5sum").empty(); $('#fileTreeFull').hide();
$("#md5sum").append('md5sum : <span>' + data.result + '</span>'); }
} $("#info").empty();
else{ $("#info").append("Selection: " + base_path());
$("#error").Popup(data.result, {type:'error', duration:5000}); selection = "";
} }
send = false;
}
});
}
function switchContent(){ function getmd5sum() {
var root = projectDir; if (send) {
if(!softwareDisplay){ return;
$("#switch").empty(); }
$("#switch").append("Switch to Software files"); send = true;
root = currentProject; $.ajax({
} type: "POST",
else{ url: $SCRIPT_ROOT + '/getmd5sum',
$("#switch").empty(); data: {file: $("input#subfolder").val()},
$("#switch").append("Switch to Project files"); success: function (data) {
} if (data.code === 1) {
$('#fileTree').fileTree({ root: root, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function(file) { $("#info").empty();
selectFile(file); $("#info").html("Md5sum Current file: " + data.result);
}); } else {
$("#info").empty(); $("#error").Popup(data.result, {type: 'error', duration: 5000});
$("#info").append("Select directory or nothing for root directory..."); }
$("input#subfolder").val(""); send = false;
} }
});
}
function setDetailBox(){ function setDevelop(developList) {
var state = $("#details_box").css("display"); if (developList === null || developList.length <= 0) {
if (state == "none"){ return;
$("#details_box").slideDown("normal"); }
$("#details_head").removeClass("hide"); editor.navigateFileStart();
$("#details_head").addClass("show"); editor.find('buildout', {caseSensitive: true, wholeWord: true});
} if (!editor.getSelectionRange().isEmpty()) {
else{ //editor.find("",{caseSensitive: true,wholeWord: true,regExp: true});
$("#details_box").slideUp("normal"); //if (!editor.getSelectionRange().isEmpty()) {
$("#details_head").removeClass("show"); //alert("found");
$("#details_head").addClass("hide"); //}
} //else{alert("no found");
} //}
} else {
$("#error").Popup("Can not found part [buildout]! Please make sure that you have a cfg file", {type: 'alert', duration: 3000});
return;
}
editor.navigateLineEnd();
$.post($SCRIPT_ROOT + "/getPath", {file: developList.join("#")}, function (data) {
var result, i;
if (data.code === 1) {
result = data.result.split('#');
editor.insert("\ndevelop =\n\t" + result[0] + "\n");
for (i = 1; i < result.length; i += 1) {
editor.insert("\t" + result[i] + "\n");
}
}
})
.error(function () {})
.complete(function () {});
editor.insert("\n");
}
function selectFile(file){
$("#info").empty();
$("#info").append(file);
$("input#subfolder").val(file);
$("#md5sum").empty();
path = "";
send = false;
edit = false;
if(file.substr(-1) != "/"){
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/getFileContent',
data: {file: file},
success: function(data){
if(data.code == 1){
$("#edit_info").empty();
var name = file.split('/');
if(file.length > 65){
//substring title.
var start = file.length - 65;
file = "..." + file.substring(file.indexOf("/", (start + 1)));
}
$("#edit_info").append("Current file: " +
file);
$("a#option").show();
editor.getSession().setValue(data.result);
setEditMode(name[name.length - 1]);
edit = true;
}
else{
$("#error").Popup(data.result, {type:'error', duration:5000});
}
send = false;
}
});
}
else{
$("#edit_info").empty();
$("#edit_info").append("No file selected");
$("a#option").hide();
editor.getSession().setValue("");
}
return;
}
function setEditMode(file){ editor.setTheme("ace/theme/crimson_editor");
var CurentMode = require("ace/mode/text").Mode;
editor.getSession().setMode(new CurentMode()); CurrentMode = require("ace/mode/text").Mode;
for (var i=0; i< modes.length; i++){ editor.getSession().setMode(new CurrentMode());
if(modes[i].extRe.test(file)){ editor.getSession().setTabSize(2);
editor.getSession().setMode(modes[i].mode); editor.getSession().setUseSoftTabs(true);
set = true; editor.renderer.setHScrollBarAlwaysVisible(false);
break;
} Mode = function (name, desc, Clazz, extensions) {
} this.name = name;
} this.desc = desc;
function setDevelop(developList){ this.clazz = Clazz;
if (developList==null || developList.length <= 0) return; this.mode = new Clazz();
editor.navigateFileStart(); this.mode.name = name;
editor.find('buildout',{caseSensitive: true,wholeWord: true});
if(!editor.getSelectionRange().isEmpty()){ this.extRe = new RegExp("^.*\\.(" + extensions.join("|") + ")$");
//editor.find("",{caseSensitive: true,wholeWord: true,regExp: true}); };
//if(!editor.getSelectionRange().isEmpty()){ modes = [
//alert("found"); new Mode("php", "PHP", require("ace/mode/php").Mode, ["php", "in", "inc"]),
//} new Mode("python", "Python", require("ace/mode/python").Mode, ["py"]),
//else{alert("no found"); new Mode("buildout", "Python Buildout config", require("ace/mode/buildout").Mode, ["cfg"])
//} ];
} $('#fileTree').fileTree({ root: projectDir, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function (file) {
else{ selectFile(file);
$("#error").Popup("Can not found part [buildout]! Please make sure that you have a cfg file", {type:'alert', duration:3000}); }, function (file) { openFile(file); });
return; $('#fileTreeFull').fileTree({ root: currentProject, script: $SCRIPT_ROOT + script, folderEvent: 'click', expandSpeed: 750, collapseSpeed: 750, multiFolder: false, selectFolder: true }, function (file) {
} selectFile(file);
editor.navigateLineEnd(); }, function (file) { openFile(file); });
$.post($SCRIPT_ROOT+"/getPath", {file:developList.join("#")}, function(data) { $("#info").append("Selection: " + base_path());
if(data.code==1){ /*setDetailBox();*/
var result = data.result.split('#');
editor.insert("\ndevelop =\n\t" + result[0] + "\n"); editor.on("change", function (e) {
for(var i=1; i<result.length; i++) if (edit_status === "" && edit) {
editor.insert("\t" + result[i] + "\n"); $("span#edit_status").html("*");
} }
}) });
.error(function() { })
.complete(function(){}); $("#add").click(function () {
editor.insert("\n"); var path = base_path();
} if (send) {
}); return false;
\ No newline at end of file }
if ($("input#file").val() === "" || $("input#file").val() === "Name here...") {
$("#error").Popup("Please select a directory or nothing for root directory and enter your file name", {type: 'alert', duration: 5000});
return false;
}
if (selection !== "") {
path = selection;
}
path = path + "/" + $("input#file").val();
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/createFile',
data: "file=" + path + "&type=" + $("#type").val(),
success: function (data) {
if (data.code === 1) {
switchContent();
$("input#file").val("");
$("#flash").fadeOut('normal');
$("#flash").empty();
$("#info").empty();
$("#info").append("Selection: " + base_path());
selection = "";
} else {
$("#error").Popup(data.result, {type: 'error', duration: 5000});
}
send = false;
}
});
return false;
});
$("#save").click(function () {
if (!edit) {
$("#error").Popup("Please select the file to edit", {type: 'alert', duration: 3000});
return false;
}
if (send) {
return false;
}
send = true;
$.ajax({
type: "POST",
url: $SCRIPT_ROOT + '/saveFileContent',
data: {
file: $("input#subfolder").val(),
content: editor.getSession().getValue()
},
success: function (data) {
if (data.code === 1) {
$("#error").Popup("File saved succefuly!", {type: 'confirm', duration: 3000});
$("span#edit_status").html("");
} else {
$("#error").Popup(data.result, {type: 'error', duration: 5000});
}
send = false;
}
});
return false;
});
/*$("#details_head").click(function () {
setDetailBox();
});*/
$("#switch").click(function () {
softwareDisplay = !softwareDisplay;
switchContent();
return false;
});
$("#getmd5").click(function () {
getmd5sum();
return false;
});
$("#clearselect").click(function () {
edit = false;
$("#info").empty();
$("#info").append("Selection: " + base_path());
$("input#subfolder").val("");
$("#edit_info").empty();
$("#edit_info").append("No file in editor");
editor.getSession().setValue("");
$("a#option").hide();
selection = "";
return false;
});
$("#adddevelop").click(function () {
var developList = [],
i = 0;
$("#plist li").each(function (index) {
var elt = $(this).find("input:checkbox");
if (elt.is(":checked")) {
developList[i] = workdir + "/" + elt.val();
i += 1;
elt.attr("checked", false);
}
});
if (developList.length > 0) {
setDevelop(developList);
}
return false;
});
});
$(document).ready( function() { /*jslint undef: true */
openedlogpage = $("input#type").val(); /*global $, document, window, processState, getCookie, setCookie, setSpeed, $SCRIPT_ROOT */
updatelogBox(); /*global openedlogpage: true */
var state = getCookie("autoUpdate"); /* vim: set et sts=4: */
$("#logheader").click(function(){ $(document).ready(function () {
setupBox(); "use strict";
});
$("#manual").change(function(){ function setupBox() {
setCookie("autoUpdate", "manual"); var state = $("#logconfigbox").css("display");
if ($("input#type").val() == "instance"){location.href = $SCRIPT_ROOT + "/viewInstanceLog";} if (state === "none") {
else{location.href = $SCRIPT_ROOT + "/viewSoftwareLog";} $("#logconfigbox").slideDown("normal");
}); $("#logheader").removeClass("hide");
$("#live").change(function(){ $("#logheader").addClass("show");
updatelogBox();$("#logconfigbox").find("input:radio").attr('checked', false);$("#live").attr('checked', true); } else {
setSpeed(100);setCookie("autoUpdate", "live");openedlogpage = $("input#type").val();}); $("#logconfigbox").slideUp("normal");
$("#slow").change(function(){ $("#logheader").removeClass("show");
updatelogBox();$("#logconfigbox").find("input:radio").attr('checked', false);$("#slow").attr('checked', true); $("#logheader").addClass("hide");
setSpeed(2500);setCookie("autoUpdate", "slow");openedlogpage = $("input#type").val();}); }
if(state){
$("#"+state).attr('checked', true);
updatelogBox();
if (state == "manual"){
openedlogpage = ""; setSpeed(0);
}
else{setSpeed((state=="live")?100:2500);}
}
else{$("#slow").attr('checked', true);}
function setupBox(){
var state = $("#logconfigbox").css("display");
if (state == "none"){
$("#logconfigbox").slideDown("normal");
$("#logheader").removeClass("hide");
$("#logheader").addClass("show");
}
else{
$("#logconfigbox").slideUp("normal");
$("#logheader").removeClass("show");
$("#logheader").addClass("hide");
} }
}
function updatelogBox() {
function updatelogBox(){ if (processState === "Stopped" || processState === "Checking" || $("#manual").is(":checked")) {
if(processState=="Stopped" || processState=="Checking" || $("#manual").is(":checked")){ $("#salpgridLog").hide();
$("#salpgridLog").hide(); $("#manualLog").show();
$("#manualLog").show(); $("#manualLog")
$("#manualLog") .scrollTop($("#manualLog")[0].scrollHeight - $("#manualLog").height());
.scrollTop($("#manualLog")[0].scrollHeight - $("#manualLog") } else {
.height()); $("#salpgridLog").show();
$("#manualLog").hide();
}
} }
else{
$("#salpgridLog").show(); openedlogpage = $("input#type").val();
$("#manualLog").hide(); updatelogBox();
var state = getCookie("autoUpdate");
$("#logheader").click(function () {
setupBox();
});
$("#manual").change(function () {
setCookie("autoUpdate", "manual");
if ($("input#type").val() === "instance") {
window.location.href = $SCRIPT_ROOT + "/viewInstanceLog";
} else {
window.location.href = $SCRIPT_ROOT + "/viewSoftwareLog";
}
});
$("#live").change(function () {
updatelogBox();
$("#logconfigbox").find("input:radio").attr('checked', false);
$("#live").attr('checked', true);
setSpeed(100);
setCookie("autoUpdate", "live");
openedlogpage = $("input#type").val();
});
$("#slow").change(function () {
updatelogBox();
$("#logconfigbox").find("input:radio").attr('checked', false);
$("#slow").attr('checked', true);
setSpeed(2500);
setCookie("autoUpdate", "slow");
openedlogpage = $("input#type").val();
});
if (state) {
$("#" + state).attr('checked', true);
updatelogBox();
if (state === "manual") {
openedlogpage = "";
setSpeed(0);
} else {
setSpeed((state === "live") ? 100 : 2500);
}
} else {
$("#slow").attr('checked', true);
} }
} });
});
\ No newline at end of file
/*jslint undef: true */
/*global $, document, window, $SCRIPT_ROOT, ace */
/* vim: set et sts=4: */
$(document).ready(function () {
"use strict";
$('#fileNavigator').gsFileManager({script: $SCRIPT_ROOT + "/fileBrowser", root:'workspace/'});
});
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
</div> </div>
<br/> <br/>
<h2>Set your Security Mode</h2> <h2>Set your Security Mode</h2>
<div class="menu-box-right" style="width: 592px;"> <div class="menu-box-right">
<div style="background:#fff; padding:10px; min-height:100px; font-size:14px;"> <div style="background:#fff; padding:10px; min-height:100px; font-size:14px;">
<div id="box0"> <div id="box0">
<h2>Clone Repository without using HTTPS and SSH</h2><br/> <h2>Clone Repository without using HTTPS and SSH</h2><br/>
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
</div> </div>
<div id="box2" style="display:none;"> <div id="box2" style="display:none;">
<h2>Enter your username and password for https authentication access</h2><br/> <h2>Enter your username and password for https authentication access</h2><br/>
<div style="margin-left:80px; margin-bottom:20px;"> <div style="margin-left:140px; margin-bottom:20px;">
<label for='username'>Your username:&nbsp;&nbsp;</label> <label for='username'>Your username:&nbsp;&nbsp;</label>
<input type="text" name="username" id="username" size='20' value="Enter your username..." /><br/><br/> <input type="text" name="username" id="username" size='20' value="Enter your username..." /><br/><br/>
<label for='password'>Your password: &nbsp;&nbsp;</label> <label for='password'>Your password: &nbsp;&nbsp;</label>
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="menu-box-left" style="width: 115px;"> <div class="menu-box-left">
<ul id="modelist"> <ul id="modelist">
<li class="checked"><input type="radio" name="security" id="nothing" value="nothing" /><label for="nothing">ReadOnly</label></li> <li class="checked"><input type="radio" name="security" id="nothing" value="nothing" /><label for="nothing">ReadOnly</label></li>
<li><input type="radio" name="security" id="ssh" value="SSH" checked /><label for="ssh">SSH Mode</label></li> <li><input type="radio" name="security" id="ssh" value="SSH" checked /><label for="ssh">SSH Mode</label></li>
......
...@@ -24,17 +24,15 @@ ...@@ -24,17 +24,15 @@
</form> </form>
<div id="tooltip-editOption" style="display:none"> <div id="tooltip-editOption" style="display:none">
<span class="list">MD5 SUM for the current file</span> <span class="list">MD5 SUM for the current file</span>
<div style="margin-top:3px; margin-bottom:5px;border-bottom: 1px dashed #666666; heigth:1px"></div>
<a id='getmd5' href="#">Get or Update md5sum</a> <a id='getmd5' href="#">Get or Update md5sum</a>
<br/><span class="list">Add Project to Develop</span><br/> <div class="sep"></div>
<div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div> <span class="list">Add Project to Develop</span>
<ul id="plist"> <ul id="plist">
{% for name in projectList%} {% for name in projectList%}
<li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}"> <li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}">
<label>{{name}}</label></li> <label>{{name}}</label></li>
{% endfor %} {% endfor %}
</ul> </ul>
<br/>
<a href="#" id="adddevelop" class="lshare">Add to profile</a> <a href="#" id="adddevelop" class="lshare">Add to profile</a>
</div> </div>
{% endblock %} {% endblock %}
......
...@@ -23,6 +23,11 @@ ...@@ -23,6 +23,11 @@
<img src="{{ url_for('static', filename='images/manage_repo.png') }}" /> <img src="{{ url_for('static', filename='images/manage_repo.png') }}" />
</div> </div>
<div class="clear"></div> <div class="clear"></div>
<div class="umenu">
<h2><a href="{{ url_for('myAccount')}}">Your Account</a></h2>
<p>Update your account informations</p>
<img src="{{ url_for('static', filename='images/user_card.png') }}" />
</div>
<div class="lmenu smaller"> <div class="lmenu smaller">
<h2><a href="{{ url_for('openProject', method='new')}}">Create your Software Release</a></h2> <h2><a href="{{ url_for('openProject', method='new')}}">Create your Software Release</a></h2>
<p>To create a new Software Release, choose the project directory in which you want to create your software.<!-- You will then be able to edit and <p>To create a new Software Release, choose the project directory in which you want to create your software.<!-- You will then be able to edit and
...@@ -31,11 +36,6 @@ ...@@ -31,11 +36,6 @@
<img src="{{ url_for('static', filename='images/folder_blue.png') }}" /> <img src="{{ url_for('static', filename='images/folder_blue.png') }}" />
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div class="umenu">
<h2><a href="{{ url_for('myAccount')}}">Your Account</a></h2>
<p>Update your account informations</p>
<img src="{{ url_for('static', filename='images/user_card.png') }}" />
</div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
</div> </div>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<ul> <ul>
<li><a href="#tab1" class="active">Slapgrid Supervisor</a></li> <li><a href="#tab1" class="active">Slapgrid Supervisor</a></li>
<li><a href="#tab2">SLAP Response</a></li> <li><a href="#tab2">SLAP Response</a></li>
<li><a href="#tab3" id="parameterTab">Parameters</a></li> <li><a href="#tab3" id="parameterTab">SLAP Parameters</a></li>
<li><a href="#tab4" id="instancetabfiles">Partitions Content</a></li> <li><a href="#tab4" id="instancetabfiles">Partitions Content</a></li>
</ul><!-- //Tab buttons --> </ul><!-- //Tab buttons -->
<div class="tabDetails"> <div class="tabDetails">
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
<div id="tab2" class="tabContents"> <div id="tab2" class="tabContents">
{% if slap_status %} {% if slap_status %}
<p>Uses parameters below to run your application</p> <p>Uses parameters below to run your application</p>
<div class="menu-box-right" style="width: 597px;"> <div class="menu-box-right">
<div style="background:#fff; padding:10px;"> <div style="background:#fff; padding:10px;">
{% for item in slap_status %} {% for item in slap_status %}
<div id="box{{item[0]}}" style="display:none;"> <div id="box{{item[0]}}" style="display:none;">
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
</h2> </h2>
<div class="clear"></div><br/> <div class="clear"></div><br/>
<div id="bcontent{{item[0]}}"> <div id="bcontent{{item[0]}}">
<table cellpadding="0" cellspacing="0" width="577"> <table cellpadding="0" cellspacing="0" width="100%">
<tr> <tr>
<th>Parameter Name</th><th>Parameter Value</th> <th>Parameter Name</th><th>Parameter Value</th>
</tr> </tr>
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<div class="menu-box-left" style="width: 110px;"> <div class="menu-box-left">
<ul id="slappart"> <ul id="slappart">
{% for item in slap_status %} {% for item in slap_status %}
<li><input type="radio" name="slapresponse" id="{{item[0]}}" value="{{item[0]}}" /> <li><input type="radio" name="slapresponse" id="{{item[0]}}" value="{{item[0]}}" />
...@@ -143,6 +143,5 @@ ...@@ -143,6 +143,5 @@
</div> </div>
</div> </div>
{{instance}}
{% endblock %} {% endblock %}
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<meta name="description" content="" /> <meta name="description" content="" />
<link href="{{ url_for('static', filename='css/styles.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" /> <link href="{{ url_for('static', filename='css/styles.css', _external=False) }}" rel="stylesheet" type="text/css" media="screen" />
<script src="{{ url_for('static', filename='js/jquery/jquery-1.8.0.min.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/jquery/jquery-1.8.0.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/jquery/jquery.form.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/jquery/jquery.form.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/jquery/popup.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/jquery/popup.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ url_for('static', filename='js/jquery/jqueryToolTip.js') }}" type="text/javascript" charset="utf-8"></script> <script src="{{ url_for('static', filename='js/jquery/jqueryToolTip.js') }}" type="text/javascript" charset="utf-8"></script>
...@@ -64,19 +64,17 @@ ...@@ -64,19 +64,17 @@
</div> </div>
<div class="wmenu"> <div class="wmenu">
<ul> <ul>
<li><span class="title_software">Software</span></li> <li><a href="{{ url_for('editSoftwareProfile') }}">Profiles</a></li>
<li><a href="{{ url_for('editSoftwareProfile') }}">Edit</a></li> <li><a href="{{ url_for('browseWorkspace') }}">Workspace</a></li>
<li><a href="{{ url_for('runSoftwareProfile') }}" id="softrun">Run</a></li> <li class='sep'></li>
<li><a href="{{ url_for('viewSoftwareLog') }}">Build log</a></li> <li><a href="{{ url_for('runSoftwareProfile') }}" id="softrun">Run software</a></li>
<li><a href="{{ url_for('inspectSoftware') }}">Inspect</a></li> <li><a href="{{ url_for('viewSoftwareLog') }}">Software log</a></li>
<li><a id="removeSr" href="#">Remove all</a></li> <li><a href="{{ url_for('inspectSoftware') }}">SR result</a></li>
<li class='sep'></li>
<li class="space"><span class="title_instance">Instance</span></li> <li><a href="{{ url_for('runInstanceProfile') }}" id="instrun">Run instance</a></li>
<li><a href="{{ url_for('editInstanceProfile') }}">Edit</a></li> <li><a href="{{ url_for('viewInstanceLog') }}">Instance log</a></li>
<li><a href="{{ url_for('runInstanceProfile') }}" id="instrun">Run</a></li> <li><a href="{{ url_for('inspectInstance') }}">Inspect instance</a></li>
<li><a href="{{ url_for('viewInstanceLog') }}">Build log</a></li> <li><a id="removeIst" href="#">Destroy instance</a></li>
<li><a href="{{ url_for('inspectInstance') }}">Inspect</a></li>
<li><a id="removeIst" href="#">Remove all</a></li>
</ul> </ul>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
...@@ -123,11 +121,12 @@ ...@@ -123,11 +121,12 @@
<div id="tooltip-home" style="display:none"> <div id="tooltip-home" style="display:none">
<span style="font-weight:bold">QUICK ACCESS TO MENU</span><br/><br/> <span style="font-weight:bold">QUICK ACCESS TO MENU</span><br/><br/>
<div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div> <div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div>
<ul> <ul class="menu">
<li><a href="{{ url_for('manageProject')}}">Manage Repositories</a></li> <li><a href="{{ url_for('manageProject')}}">Manage Repositories</a></li>
<li><a href="{{ url_for('configRepo')}}" >Clone your repository</a></li> <li><a href="{{ url_for('configRepo')}}" >Clone your repository</a></li>
<li><a href="{{ url_for('openProject', method='open')}}">Open Software Release</a></li> <li><a href="{{ url_for('openProject', method='open')}}">Open Software Release</a></li>
<li><a href="{{ url_for('openProject', method='new')}}">Create Software Release</a></li> <li><a href="{{ url_for('openProject', method='new')}}">Create Software Release</a></li>
<li style="heigth:1px"></li>
</ul> </ul>
</div> </div>
</body> </body>
......
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<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'>Software Release: </label> <label for='softwarelist' class='header'>Inspect 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 %}
......
...@@ -18,51 +18,53 @@ ...@@ -18,51 +18,53 @@
<input type="hidden" name="workdir" id="workdir" value="{{workDir}}" /> <input type="hidden" name="workdir" id="workdir" value="{{workDir}}" />
<input type="hidden" name="subfolder" id="subfolder" value="" /> <input type="hidden" name="subfolder" id="subfolder" value="" />
<div id="software_folder"> <div id="software_folder">
<h2 class="hight show" id="details_head">Current software release file content</h2> <div class="software_details">
<div class="software_details" id="details_box"> <a href="#" id="switch" class="lshare no-right-border" style="float:left">Switch to Project</a>
<div id="fileTree" class="file_tree_short"></div> <a href="#" id="clearselect" class="lshare no-right-border" style="float:left">Reset</a>
<div class="box_software"> <a href="#" id="save" class="lshare" style="float:left">Save</a>
<h2>Add new file or folder</h2>
<input type="text" name="file" id="file" size='22' value="Enter name here..." />
&nbsp;&nbsp;&nbsp;<select name="type" id="type">
<option value="file">file</option>
<option value="folder">folder</option>
</select>
&nbsp;&nbsp;&nbsp;<input type="submit" name="add" id ="add" value="Add" class="button"/>
<br/><br/>
<a href="#" id="switch" class="lshare">Switch to Project files</a>
<a href="" id="clearselect" class="lshare">Clear selection</a><br/><br/>
<div id="file_info" class="file_info"><span id="info">Select directory or nothing for root directory...</span></div>
</div>
<div class="clear"></div>
</div>
<div class="clear"></div> <div class="clear"></div>
<div id="code" style="margin-top:10px"> <div id="details_box">
<h2 class='title'><span id="edit_info">No file selected</span> <a style="display:none" id='option' href='#' rel='tooltip' title='Show more option'>[More]</a></h2> <div id="fileTree" class="file_tree_short" title="Double click to edit selected file..."></div>
<div class='md5sum' id='md5sum'></div> <div id="fileTreeFull" style='display:none' class="file_tree_short" title="Double click to edit selected file..."></div>
<div class="main_content"> <div class="box_software">
<input type="text" name="file" id="file" size='12' value="Name here..." />
&nbsp;<select name="type" id="type">
<option value="file">file</option>
<option value="folder">folder</option>
</select>
&nbsp;<input type="submit" name="add" id ="add" value="Add" class="button"/>
</div>
</div>
</div>
<div id="code">
<h2 class='title'>
<a style="display:none" id='option' href='#' rel='tooltip' title='Show more option'>[Current file]</a><span id="edit_info">No file in editor</span>
<span id="edit_status"></span>
</h2>
<div class="main_content">
<pre id="editor"> <pre id="editor">
</pre> </pre>
</div> </div>
<input type=submit value="Save" id="save" class="button"> <!--<input type=submit value="Save" id="save" class="button">-->
</div> </div>
</div> </div>
<div class="clear"></div>
<div id="file_info" class="file_info"><span id="info"></span></div>
<br/>
</form> </form>
<div id="tooltip-option" style="display:none"> <div id="tooltip-option" style="display:none">
<span class="list">MD5 SUM for the current file</span> <span class="list first-list">MD5 SUM for the current file</span>
<div style="margin-top:3px; margin-bottom:5px;border-bottom: 1px dashed #666666; heigth:1px"></div>
<a id='getmd5' href="#">Get or Update md5sum</a> <a id='getmd5' href="#">Get or Update md5sum</a>
<br/><span class="list">Add Project to Develop</span><br/> <div class="sep"></div>
<div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div> <span class="list">Add Project to Develop</span>
<ul id="plist"> <ul id="plist">
{% for name in projectList%} {% for name in projectList%}
<li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}"> <li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}">
<label>{{name}}</label></li> <label>{{name}}</label></li>
{% endfor %} {% endfor %}
</ul> </ul>
<br/>
<a href="#" id="adddevelop" class="lshare">Add to profile</a> <a href="#" id="adddevelop" class="lshare">Add to profile</a>
</div> </div>
{% endblock %} {% endblock %}
...@@ -24,17 +24,15 @@ ...@@ -24,17 +24,15 @@
</form> </form>
<div id="tooltip-editOption" style="display:none"> <div id="tooltip-editOption" style="display:none">
<span class="list">MD5 SUM for the current file</span> <span class="list">MD5 SUM for the current file</span>
<div style="margin-top:3px; margin-bottom:5px;border-bottom: 1px dashed #666666; heigth:1px"></div>
<a id='getmd5' href="#">Get or Update md5sum</a> <a id='getmd5' href="#">Get or Update md5sum</a>
<br/><span class="list">Add Project to Develop</span><br/> <div class="sep"></div>
<div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div> <span class="list">Add Project to Develop</span><br/>
<ul id="plist"> <ul id="plist">
{% for name in projectList%} {% for name in projectList%}
<li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}"> <li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}">
<label>{{name}}</label></li> <label>{{name}}</label></li>
{% endfor %} {% endfor %}
</ul> </ul>
<br/>
<a href="#" id="adddevelop" class="lshare">Add to profile</a> <a href="#" id="adddevelop" class="lshare">Add to profile</a>
</div> </div>
{% endblock %} {% endblock %}
......
...@@ -23,18 +23,17 @@ ...@@ -23,18 +23,17 @@
</dl> </dl>
</form> </form>
<div id="tooltip-editOption" style="display:none"> <div id="tooltip-editOption" style="display:none">
<span class="list">MD5 SUM for the current file</span> <span class="list">Current profile options</span>
<div style="margin-top:3px; margin-bottom:5px;border-bottom: 1px dashed #666666; heigth:1px"></div>
<a id='getmd5' href="#">Get or Update md5sum</a> <a id='getmd5' href="#">Get or Update md5sum</a>
<br/><span class="list">Add Project to Develop</span><br/> <a href="{{ url_for('editCurrentProject')}}">Edit software release files</a>
<div style="margin-top:3px;border-bottom: 1px dashed #666666; heigth:1px"></div> <div class="sep"></div>
<span class="list">Add Project to Develop</span>
<ul id="plist"> <ul id="plist">
{% for name in projectList%} {% for name in projectList%}
<li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}"> <li><input type="checkbox" name="develop" value="{{name}}" id="{{name}}">
<label>{{name}}</label></li> <label>{{name}}</label></li>
{% endfor %} {% endfor %}
</ul> </ul>
<br/>
<a href="#" id="adddevelop" class="lshare">Add to profile</a> <a href="#" id="adddevelop" class="lshare">Add to profile</a>
</div> </div>
{% endblock %} {% endblock %}
......
...@@ -18,6 +18,6 @@ ...@@ -18,6 +18,6 @@
<label for="slow">From time to time</label> <label for="slow">From time to time</label>
</div> </div>
<br/> <br/>
<div class="log_content"><textarea class="log" readonly id="salpgridLog"></textarea> <div class="log_content"><div class="log" id="salpgridLog"></div>
<textarea class="log" readonly id="manualLog" style="display:none">{{result}}</textarea></div> <textarea class="log" readonly id="manualLog" style="display:none">{{result}}</textarea></div>
{% endblock %} {% endblock %}
{% extends "layout.html" %}
{% block title %}Browse webrunner workspace{% endblock %}
{% block head %}
{{ super() }}
<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/scripts/workspace.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" />
<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 %}
{% block body %}
<div id="fileNavigator" class="browser"></div>
{% endblock %}
\ No newline at end of file
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: set et sts=2:
# pylint: disable-msg=W0311,C0301,C0103,C0111,W0141,W0142
import slapos.slap
import time import md5
import subprocess import logging
import os import multiprocessing
from xml_marshaller import xml_marshaller
from xml.dom import minidom
import re import re
from slapos.runner.process import Popen, isRunning, killRunningProcess
import shutil
import os
import time
import urllib import urllib
from xml.dom import minidom
import xml_marshaller
from flask import jsonify from flask import jsonify
import shutil
import string import slapos.slap
import hashlib
import signal
import multiprocessing
# Setup default flask (werkzeug) parser # Setup default flask (werkzeug) parser
import logging
logger = logging.getLogger('werkzeug')
logger = logging.getLogger('werkzeug')
class Popen(subprocess.Popen):
def __init__(self, *args, **kwargs):
kwargs['stdin'] = subprocess.PIPE
kwargs['stderr'] = subprocess.STDOUT
kwargs.setdefault('stdout', subprocess.PIPE)
kwargs.setdefault('close_fds', True)
subprocess.Popen.__init__(self, *args, **kwargs)
self.stdin.flush()
self.stdin.close()
self.stdin = None
html_escape_table = { html_escape_table = {
"&": "&amp;", "&": "&amp;",
...@@ -41,7 +35,7 @@ html_escape_table = { ...@@ -41,7 +35,7 @@ html_escape_table = {
def html_escape(text): def html_escape(text):
"""Produce entities within text.""" """Produce entities within text."""
return "".join(html_escape_table.get(c,c) for c in text) return "".join(html_escape_table.get(c, c) for c in text)
def getSession(config): def getSession(config):
""" """
...@@ -86,7 +80,7 @@ def saveSession(config, account): ...@@ -86,7 +80,7 @@ def saveSession(config, account):
#save new account data #save new account data
open(user, 'w').write((';'.join(account)).encode("utf-8")) open(user, 'w').write((';'.join(account)).encode("utf-8"))
return True return True
except Exception, e: except Exception as e:
try: try:
if backup: if backup:
os.remove(user) os.remove(user)
...@@ -169,24 +163,9 @@ def updateProxy(config): ...@@ -169,24 +163,9 @@ def updateProxy(config):
'reference': partition_reference, 'reference': partition_reference,
'tap': {'name': partition_reference}, 'tap': {'name': partition_reference},
}) })
computer.updateConfiguration(xml_marshaller.dumps(slap_config)) computer.updateConfiguration(xml_marshaller.xml_marshaller.dumps(slap_config))
return True return True
def readPid(file):
"""Read process pid from file `file`"""
if os.path.exists(file):
data = open(file).read().strip()
try:
return int(data)
except Exception:
return 0
return 0
def writePid(file, pid):
"""Save process pid into a file `file`"""
open(file, 'w').write(str(pid))
def updateInstanceParameter(config, software_type=None): def updateInstanceParameter(config, software_type=None):
""" """
Reconfigure Slapproxy to re-deploy current Software Instance with parameters. Reconfigure Slapproxy to re-deploy current Software Instance with parameters.
...@@ -200,31 +179,17 @@ def updateInstanceParameter(config, software_type=None): ...@@ -200,31 +179,17 @@ def updateInstanceParameter(config, software_type=None):
def startProxy(config): def startProxy(config):
"""Start Slapproxy server""" """Start Slapproxy server"""
proxy_pid = os.path.join(config['etc_dir'], 'proxy.pid') if not isRunning('slapproxy'):
pid = readPid(proxy_pid) log = os.path.join(config['log_dir'], 'slapproxy.log')
running = False Popen([config['slapproxy'], '--log_file', log,
if pid: config['configuration_file_path']],
try: name='slapproxy')
os.kill(pid, 0) time.sleep(4)
except Exception:
pass
else:
running = True
if not running:
proxy = Popen([config['slapproxy'], config['configuration_file_path']])
proxy_pid = os.path.join(config['etc_dir'], 'proxy.pid')
writePid(proxy_pid, proxy.pid)
time.sleep(5)
def stopProxy(config): def stopProxy(config):
"""Stop Slapproxy server""" """Stop Slapproxy server"""
pid = readPid(os.path.join(config['etc_dir'], 'proxy.pid')) pass
if pid:
try:
os.kill(pid)
except:
pass
def removeProxyDb(config): def removeProxyDb(config):
...@@ -233,22 +198,11 @@ def removeProxyDb(config): ...@@ -233,22 +198,11 @@ def removeProxyDb(config):
if os.path.exists(config['database_uri']): if os.path.exists(config['database_uri']):
os.unlink(config['database_uri']) os.unlink(config['database_uri'])
def isSoftwareRunning(config): def isSoftwareRunning(config=None):
""" """
Return True if slapgrid-sr is still running and false if slapgrid if not Return True if slapgrid-sr is still running and false if slapgrid if not
""" """
slapgrid_pid = os.path.join(config['etc_dir'], 'slapgrid-sr.pid') return isRunning('slapgrid-sr')
pid = readPid(slapgrid_pid)
if pid:
try:
os.kill(pid, 0)
except Exception:
running = False
else:
running = True
else:
running = False
return running
def runSoftwareWithLock(config): def runSoftwareWithLock(config):
...@@ -256,8 +210,8 @@ def runSoftwareWithLock(config): ...@@ -256,8 +210,8 @@ def runSoftwareWithLock(config):
Use Slapgrid to compile current Software Release and wait until Use Slapgrid to compile current Software Release and wait until
compilation is done compilation is done
""" """
slapgrid_pid = os.path.join(config['etc_dir'], 'slapgrid-sr.pid') slapgrid_pid = os.path.join(config['run_dir'], 'slapgrid-sr.pid')
if not isSoftwareRunning(config): if not isSoftwareRunning():
if not os.path.exists(config['software_root']): if not os.path.exists(config['software_root']):
os.mkdir(config['software_root']) os.mkdir(config['software_root'])
stopProxy(config) stopProxy(config)
...@@ -270,9 +224,10 @@ def runSoftwareWithLock(config): ...@@ -270,9 +224,10 @@ def runSoftwareWithLock(config):
environment = os.environ.copy() environment = os.environ.copy()
environment['MAKEFLAGS'] = '-j%r' % multiprocessing.cpu_count() environment['MAKEFLAGS'] = '-j%r' % multiprocessing.cpu_count()
slapgrid = Popen([config['slapgrid_sr'], '-vc', slapgrid = Popen([config['slapgrid_sr'], '-vc',
config['configuration_file_path'], '--now', '--develop'], '--pidfile', slapgrid_pid,
stdout=logfile, env=environment) config['configuration_file_path'], '--now', '--develop'],
writePid(slapgrid_pid, slapgrid.pid) stdout=logfile, env=environment,
name='slapgrid-sr')
slapgrid.wait() slapgrid.wait()
#Saves the current compile software for re-use #Saves the current compile software for re-use
config_SR_folder(config) config_SR_folder(config)
...@@ -328,68 +283,28 @@ def loadSoftwareRList(config): ...@@ -328,68 +283,28 @@ def loadSoftwareRList(config):
list.append(dict(md5=cfg[1], path=cfg[0], title=path)) list.append(dict(md5=cfg[1], path=cfg[0], title=path))
return list return list
def isInstanceRunning(config): def isInstanceRunning(config=None):
""" """
Return True if slapgrid-cp is still running and false if slapgrid if not Return True if slapgrid-cp is still running and false if slapgrid if not
""" """
slapgrid_pid = os.path.join(config['etc_dir'], 'slapgrid-cp.pid') return isRunning('slapgrid-cp')
pid = readPid(slapgrid_pid)
if pid:
try:
os.kill(pid, 0)
except Exception:
running = False
else:
running = True
else:
running = False
return running
def killRunningSlapgrid(config, ptype):
"""Kill slapgrid process and all running children process"""
slapgrid_pid = os.path.join(config['etc_dir'], ptype)
pid = readPid(slapgrid_pid)
if pid:
recursifKill([pid])
else:
return False
def recursifKill(pids):
"""Try to kill a list of proccess by the given pid list"""
if pids == []:
return
else:
for pid in pids:
ppids = pidppid(pid)
try:
os.kill(pid, signal.SIGKILL) #kill current process
except Exception:
pass
recursifKill(ppids) #kill all children of this process
def pidppid(pid):
"""get the list of the children pids of a process `pid`"""
proc = Popen('ps -o pid,ppid ax | grep "%d"' % pid, shell=True,
stdout=subprocess.PIPE)
ppid = [x.split() for x in proc.communicate()[0].split("\n") if x]
return list(int(p) for p, pp in ppid if int(pp) == pid)
def runInstanceWithLock(config): def runInstanceWithLock(config):
""" """
Use Slapgrid to deploy current Software Release and wait until Use Slapgrid to deploy current Software Release and wait until
deployment is done. deployment is done.
""" """
slapgrid_pid = os.path.join(config['etc_dir'], 'slapgrid-cp.pid') slapgrid_pid = os.path.join(config['run_dir'], 'slapgrid-cp.pid')
if not isInstanceRunning(config): if not isInstanceRunning():
startProxy(config) startProxy(config)
logfile = open(config['instance_log'], 'w') logfile = open(config['instance_log'], 'w')
if not (updateProxy(config) and requestInstance(config)): if not (updateProxy(config) and requestInstance(config)):
return False return False
svcStopAll(config) #prevent lost control of process
slapgrid = Popen([config['slapgrid_cp'], '-vc', slapgrid = Popen([config['slapgrid_cp'], '-vc',
config['configuration_file_path'], '--now'], '--pidfile', slapgrid_pid,
stdout=logfile) config['configuration_file_path'], '--now'],
writePid(slapgrid_pid, slapgrid.pid) stdout=logfile, name='slapgrid-cp')
slapgrid.wait() slapgrid.wait()
return True return True
return False return False
...@@ -425,7 +340,7 @@ def getSlapStatus(config): ...@@ -425,7 +340,7 @@ def getSlapStatus(config):
if partition_list: if partition_list:
for i in xrange(0, int(config['partition_amount'])): for i in xrange(0, int(config['partition_amount'])):
slappart_id = '%s%s' % ("slappart", i) slappart_id = '%s%s' % ("slappart", i)
if not [x[0] for x in partition_list if slappart_id==x[0]]: if not [x[0] for x in partition_list if slappart_id == x[0]]:
partition_list.append((slappart_id, [])) partition_list.append((slappart_id, []))
return partition_list return partition_list
...@@ -438,7 +353,7 @@ def removeInstanceRoot(config): ...@@ -438,7 +353,7 @@ def removeInstanceRoot(config):
"""Clean instance directory and stop all its running process""" """Clean instance directory and stop all its running process"""
if os.path.exists(config['instance_root']): if os.path.exists(config['instance_root']):
svcStopAll(config) svcStopAll(config)
for root, dirs, files in os.walk(config['instance_root']): for root, dirs, _ in os.walk(config['instance_root']):
for fname in dirs: for fname in dirs:
fullPath = os.path.join(root, fname) fullPath = os.path.join(root, fname)
if not os.access(fullPath, os.W_OK) : if not os.access(fullPath, os.W_OK) :
...@@ -450,14 +365,12 @@ def getSvcStatus(config): ...@@ -450,14 +365,12 @@ def getSvcStatus(config):
"""Return all Softwares Instances process Informations""" """Return all Softwares Instances process Informations"""
result = Popen([config['supervisor'], config['configuration_file_path'], result = Popen([config['supervisor'], config['configuration_file_path'],
'status']).communicate()[0] 'status']).communicate()[0]
regex = "(^unix:.+\.socket)|(^error:).*$" regex = "(^unix:.+\.socket)|(^error:)|(^watchdog).*$"
supervisord = [] supervisord = []
for item in result.split('\n'): for item in result.split('\n'):
if item.strip() != "": if item.strip() != "":
if re.search(regex, item, re.IGNORECASE) == None: if re.search(regex, item, re.IGNORECASE) == None:
supervisord.append(re.split('[\s,]+', item)) supervisord.append(re.split('[\s,]+', item))
else:
return [] #ignore because it is an error message
return supervisord return supervisord
def getSvcTailProcess(config, process): def getSvcTailProcess(config, process):
...@@ -495,11 +408,11 @@ def getFolderContent(config, folder): ...@@ -495,11 +408,11 @@ def getFolderContent(config, folder):
Returns: Returns:
Html formated string or error message when fail. Html formated string or error message when fail.
""" """
r=['<ul class="jqueryFileTree" style="display: none;">'] r = ['<ul class="jqueryFileTree" style="display: none;">']
try: try:
folder = str(folder) folder = str(folder)
r=['<ul class="jqueryFileTree" style="display: none;">'] r = ['<ul class="jqueryFileTree" style="display: none;">']
d=urllib.unquote(folder) d = urllib.unquote(folder)
realdir = realpath(config, d) realdir = realpath(config, d)
if not realdir: if not realdir:
r.append('Could not load directory: Permission denied') r.append('Could not load directory: Permission denied')
...@@ -509,14 +422,14 @@ def getFolderContent(config, folder): ...@@ -509,14 +422,14 @@ def getFolderContent(config, folder):
for f in ldir: for f in ldir:
if f.startswith('.'): #do not displays this file/folder if f.startswith('.'): #do not displays this file/folder
continue continue
ff=os.path.join(d,f) ff = os.path.join(d, f)
if os.path.isdir(os.path.join(realdir,f)): if os.path.isdir(os.path.join(realdir, f)):
r.append('<li class="directory collapsed"><a href="#%s" rel="%s/">%s</a></li>' % (ff, ff,f)) r.append('<li class="directory collapsed"><a href="#%s" rel="%s/">%s</a></li>' % (ff, ff, f))
else: else:
e=os.path.splitext(f)[1][1:] # get .ext and remove dot e = os.path.splitext(f)[1][1:] # get .ext and remove dot
r.append('<li class="file ext_%s"><a href="#%s" rel="%s">%s</a></li>' % (e, ff,ff,f)) r.append('<li class="file ext_%s"><a href="#%s" rel="%s">%s</a></li>' % (e, ff, ff, f))
r.append('</ul>') r.append('</ul>')
except Exception,e: except Exception as e:
r.append('Could not load directory: %s' % str(e)) r.append('Could not load directory: %s' % str(e))
r.append('</ul>') r.append('</ul>')
return jsonify(result=''.join(r)) return jsonify(result=''.join(r))
...@@ -532,11 +445,11 @@ def getFolder(config, folder): ...@@ -532,11 +445,11 @@ def getFolder(config, folder):
Returns: Returns:
Html formated string or error message when fail. Html formated string or error message when fail.
""" """
r=['<ul class="jqueryFileTree" style="display: none;">'] r = ['<ul class="jqueryFileTree" style="display: none;">']
try: try:
folder = str(folder) folder = str(folder)
r=['<ul class="jqueryFileTree" style="display: none;">'] r = ['<ul class="jqueryFileTree" style="display: none;">']
d=urllib.unquote(folder) d = urllib.unquote(folder)
realdir = realpath(config, d) realdir = realpath(config, d)
if not realdir: if not realdir:
r.append('Could not load directory: Permission denied') r.append('Could not load directory: Permission denied')
...@@ -546,11 +459,11 @@ def getFolder(config, folder): ...@@ -546,11 +459,11 @@ def getFolder(config, folder):
for f in ldir: for f in ldir:
if f.startswith('.'): #do not display this file/folder if f.startswith('.'): #do not display this file/folder
continue continue
ff=os.path.join(d,f) ff = os.path.join(d, f)
if os.path.isdir(os.path.join(realdir,f)): if os.path.isdir(os.path.join(realdir, f)):
r.append('<li class="directory collapsed"><a href="#%s" rel="%s/">%s</a></li>' % (ff, ff, f)) r.append('<li class="directory collapsed"><a href="#%s" rel="%s/">%s</a></li>' % (ff, ff, f))
r.append('</ul>') r.append('</ul>')
except Exception,e: except Exception as e:
r.append('Could not load directory: %s' % str(e)) r.append('Could not load directory: %s' % str(e))
r.append('</ul>') r.append('</ul>')
return jsonify(result=''.join(r)) return jsonify(result=''.join(r))
...@@ -581,10 +494,10 @@ def configNewSR(config, projectpath): ...@@ -581,10 +494,10 @@ def configNewSR(config, projectpath):
""" """
folder = realpath(config, projectpath) folder = realpath(config, projectpath)
if folder: if folder:
if isInstanceRunning(config): if isInstanceRunning():
killRunningSlapgrid(config, "slapgrid-cp.pid") killRunningProcess('slapgrid-cp')
if isSoftwareRunning(config): if isSoftwareRunning():
killRunningSlapgrid(config, "slapgrid-sr.pid") killRunningProcess('slapgrid-sr')
stopProxy(config) stopProxy(config)
removeProxyDb(config) removeProxyDb(config)
startProxy(config) startProxy(config)
...@@ -623,12 +536,18 @@ def newSoftware(folder, config, session): ...@@ -623,12 +536,18 @@ def newSoftware(folder, config, session):
open(os.path.join(folderPath, config['software_profile']), 'w').write(softwareContent) open(os.path.join(folderPath, config['software_profile']), 'w').write(softwareContent)
open(os.path.join(folderPath, config['instance_profile']), 'w').write("") open(os.path.join(folderPath, config['instance_profile']), 'w').write("")
open(os.path.join(basedir, ".project"), 'w').write(folder + "/") open(os.path.join(basedir, ".project"), 'w').write(folder + "/")
#Clean sapproxy Database
stopProxy(config)
removeProxyDb(config)
startProxy(config)
#Stop runngin process and remove existing instance
removeInstanceRoot(config)
session['title'] = getProjectTitle(config) session['title'] = getProjectTitle(config)
code = 1 code = 1
else: else:
json = "Bad folder or Directory '" + folder + \ json = "Bad folder or Directory '" + folder + \
"' already exist, please enter a new name for your software" "' already exist, please enter a new name for your software"
except Exception, e: except Exception as e:
json = "Can not create your software, please try again! : " + str(e) json = "Can not create your software, please try again! : " + str(e)
if os.path.exists(folderPath): if os.path.exists(folderPath):
shutil.rmtree(folderPath) shutil.rmtree(folderPath)
...@@ -646,8 +565,8 @@ def getProjectTitle(config): ...@@ -646,8 +565,8 @@ def getProjectTitle(config):
conf = os.path.join(config['etc_dir'], ".project") conf = os.path.join(config['etc_dir'], ".project")
if os.path.exists(conf): if os.path.exists(conf):
project = open(conf, "r").read().split("/") project = open(conf, "r").read().split("/")
software = project[len(project) - 2] software = project[-2]
return software + " (" + string.join(project[:(len(project) - 2)], '/') + ")" return '%s (%s)' % (software, '/'.join(project[:-2]))
return "No Profile" return "No Profile"
def getSoftwareReleaseName(config): def getSoftwareReleaseName(config):
...@@ -655,7 +574,7 @@ def getSoftwareReleaseName(config): ...@@ -655,7 +574,7 @@ def getSoftwareReleaseName(config):
sr_profile = os.path.join(config['etc_dir'], ".project") sr_profile = os.path.join(config['etc_dir'], ".project")
if os.path.exists(sr_profile): if os.path.exists(sr_profile):
project = open(sr_profile, "r").read().split("/") project = open(sr_profile, "r").read().split("/")
software = project[len(project) - 2] software = project[-2]
return software.replace(' ', '_') return software.replace(' ', '_')
return "No_name" return "No_name"
...@@ -666,7 +585,7 @@ def removeSoftwareByName(config, md5, folderName): ...@@ -666,7 +585,7 @@ def removeSoftwareByName(config, md5, folderName):
config: slaprunner configuration config: slaprunner configuration
foldername: the link 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""" md5: the md5 filename given by slapgrid to SR folder"""
if isSoftwareRunning(config) or isInstanceRunning(config): if isSoftwareRunning() or isInstanceRunning():
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'], md5) path = os.path.join(config['software_root'], md5)
linkpath = os.path.join(config['software_link'], folderName) linkpath = os.path.join(config['software_link'], folderName)
...@@ -698,19 +617,20 @@ def tail(f, lines=20): ...@@ -698,19 +617,20 @@ def tail(f, lines=20):
data.insert(0, f.read(BUFSIZ)) data.insert(0, f.read(BUFSIZ))
else: else:
# file too small, start from begining # file too small, start from begining
f.seek(0,0) f.seek(0, 0)
# only read what was not read # only read what was not read
data.insert(0, f.read(bytes)) data.insert(0, f.read(bytes))
linesFound = data[0].count('\n') linesFound = data[0].count('\n')
size -= linesFound size -= linesFound
bytes -= BUFSIZ bytes -= BUFSIZ
block -= 1 block -= 1
return string.join(''.join(data).splitlines()[-lines:], '\n') return '\n'.join(''.join(data).splitlines()[-lines:])
def readFileFrom(f, lastPosition): def readFileFrom(f, lastPosition, limit=20000):
""" """
Returns the last lines of file `f`, from position lastPosition. Returns the last lines of file `f`, from position lastPosition.
and the last position and the last position
limit = max number of caracter to read
""" """
BUFSIZ = 1024 BUFSIZ = 1024
f.seek(0, 2) f.seek(0, 2)
...@@ -718,8 +638,10 @@ def readFileFrom(f, lastPosition): ...@@ -718,8 +638,10 @@ def readFileFrom(f, lastPosition):
block = -1 block = -1
data = "" data = ""
length = bytes length = bytes
if lastPosition <= 0 and length > 30000: truncated = False #True if a part of log data has been truncated
lastPosition = length-30000 if (lastPosition <= 0 and length > limit) or (length-lastPosition > limit):
lastPosition = length - limit
truncated = True
size = bytes - lastPosition size = bytes - lastPosition
while bytes > lastPosition: while bytes > lastPosition:
if abs(block*BUFSIZ) <= size: if abs(block*BUFSIZ) <= size:
...@@ -729,7 +651,7 @@ def readFileFrom(f, lastPosition): ...@@ -729,7 +651,7 @@ def readFileFrom(f, lastPosition):
else: else:
margin = abs(block*BUFSIZ) - size margin = abs(block*BUFSIZ) - size
if length < BUFSIZ: if length < BUFSIZ:
f.seek(0,0) f.seek(0, 0)
else: else:
seek = block * BUFSIZ + margin seek = block * BUFSIZ + margin
f.seek(seek, 2) f.seek(seek, 2)
...@@ -737,13 +659,13 @@ def readFileFrom(f, lastPosition): ...@@ -737,13 +659,13 @@ def readFileFrom(f, lastPosition):
bytes -= BUFSIZ bytes -= BUFSIZ
block -= 1 block -= 1
f.close() f.close()
return {"content":data, "position":length} return {"content":data, "position":length, "truncated":truncated}
def isText(file): def isText(file):
"""Return True if the mimetype of file is Text""" """Return True if the mimetype of file is Text"""
if not os.path.exists(file): if not os.path.exists(file):
return False return False
text_range = ''.join(map(chr, [7,8,9,10,12,13,27] + range(0x20, 0x100))) text_range = ''.join(map(chr, [7, 8, 9, 10, 12, 13, 27] + range(0x20, 0x100)))
is_binary_string = lambda bytes: bool(bytes.translate(None, text_range)) is_binary_string = lambda bytes: bool(bytes.translate(None, text_range))
try: try:
return not is_binary_string(open(file).read(1024)) return not is_binary_string(open(file).read(1024))
...@@ -756,7 +678,7 @@ def md5sum(file): ...@@ -756,7 +678,7 @@ def md5sum(file):
return False return False
try: try:
fh = open(file, 'rb') fh = open(file, 'rb')
m = hashlib.md5() m = md5.md5()
while True: while True:
data = fh.read(8192) data = fh.read(8192)
if not data: if not data:
...@@ -799,14 +721,14 @@ def readParameters(path): ...@@ -799,14 +721,14 @@ def readParameters(path):
if os.path.exists(path): if os.path.exists(path):
try: try:
xmldoc = minidom.parse(path) xmldoc = minidom.parse(path)
object = {} obj = {}
for elt in xmldoc.childNodes: for elt in xmldoc.childNodes:
sub_object = {} sub_obj = {}
for subnode in elt.childNodes: for subnode in elt.childNodes:
if subnode.nodeType != subnode.TEXT_NODE: if subnode.nodeType != subnode.TEXT_NODE:
sub_object[str(subnode.getAttribute('id'))] = subnode.childNodes[0].data #.decode('utf-8').decode('utf-8') sub_obj[str(subnode.getAttribute('id'))] = subnode.childNodes[0].data #.decode('utf-8').decode('utf-8')
object[str(elt.tagName)] = sub_object obj[str(elt.tagName)] = sub_obj
return object return obj
except Exception, e: except Exception, e:
return str(e) return str(e)
else: else:
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: set et sts=2:
# pylint: disable-msg=W0311,C0301,C0103,C0111
from flask import Flask, request, redirect, url_for, \
render_template, g, flash, jsonify, session, abort, send_file
from utils import *
import os import os
import shutil import shutil
import md5
from gittools import cloneRepo, gitStatus, switchBranch, addBranch, getDiff, \
gitPush, gitPull
from flaskext.auth import Auth, AuthUser, login_required, logout
from fileBrowser import fileBrowser
import urllib import urllib
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)
from slapos.runner.process import killRunningProcess
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,
updateInstanceParameter)
from slapos.runner.fileBrowser import FileBrowser
from slapos.runner.gittools import (cloneRepo, gitStatus, switchBranch,
addBranch, getDiff, gitPush, gitPull)
app = Flask(__name__) app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 20 * 1024 * 1024 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) file_request = FileBrowser(app.config)
# Setup default flask (werkzeug) parser # Setup default flask (werkzeug) parser
import logging import logging
...@@ -45,6 +64,11 @@ def before_request(): ...@@ -45,6 +64,11 @@ def before_request():
def home(): def home():
return render_template('index.html') return render_template('index.html')
# general views
@login_required()
def browseWorkspace():
return render_template('workspace.html')
@app.route("/login") @app.route("/login")
def login(): def login():
return render_template('login.html') return render_template('login.html')
...@@ -64,7 +88,7 @@ def myAccount(): ...@@ -64,7 +88,7 @@ def myAccount():
@app.route("/dologout") @app.route("/dologout")
def dologout(): def dologout():
user_data = logout() _ = logout()
return redirect(url_for('login')) return redirect(url_for('login'))
@login_required() @login_required()
...@@ -95,10 +119,6 @@ def editSoftwareProfile(): ...@@ -95,10 +119,6 @@ def editSoftwareProfile():
@login_required() @login_required()
def inspectSoftware(): def inspectSoftware():
if not os.path.exists(app.config['software_root']):
result = ""
else:
result = app.config['software_root']
return render_template('runResult.html', softwareRoot='software_link/', return render_template('runResult.html', softwareRoot='software_link/',
softwares=loadSoftwareRList(app.config)) softwares=loadSoftwareRList(app.config))
...@@ -164,11 +184,17 @@ def supervisordStatus(): ...@@ -164,11 +184,17 @@ def supervisordStatus():
html = "<tr><th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th></tr>" 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: for item in result:
html += "<tr>" html += "<tr>"
html +="<td class='first'><b><a href='" + url_for('tailProcess', process=item[0])+"'>"+item[0]+"</a></b></td>" html += "<td class='first'><b><a href='" \
html +="<td align='center'><a href='"+url_for('startStopProccess', process=item[0], action=item[1])+"'>"+item[1]+"</a></td>" + url_for('tailProcess', process=item[0]) + "'>" \
html +="<td align='center'>"+item[3]+"</td><td>"+item[5]+"</td>" + item[0] + "</a></b></td>"
html +="<td align='center'><a href='"+url_for('startStopProccess', process=item[0], action='RESTART')+"'>Restart</a></td>" html += "<td align='center'><a href='" \
html +="</tr>" + url_for('startStopProccess', process=item[0], action=item[1]) \
+ "'>" + item[1] + "</a></td>"
html += "<td align='center'>" + item[3] + "</td><td>" + item[5] + "</td>"
html += "<td align='center'><a href='" \
+ url_for('startStopProccess', process=item[0], action='RESTART') \
+ "'>Restart</a></td>"
html += "</tr>"
return jsonify(code=1, result=html) return jsonify(code=1, result=html)
@login_required() @login_required()
...@@ -176,9 +202,8 @@ def removeInstance(): ...@@ -176,9 +202,8 @@ def removeInstance():
if isInstanceRunning(app.config): if isInstanceRunning(app.config):
flash('Instantiation in progress, cannot remove') flash('Instantiation in progress, cannot remove')
else: else:
stopProxy(app.config)
removeProxyDb(app.config) removeProxyDb(app.config)
startProxy(app.config) svcStopAll(app.config) #Stop All instance process
removeInstanceRoot(app.config) removeInstanceRoot(app.config)
param_path = os.path.join(app.config['etc_dir'], ".parameter.xml") param_path = os.path.join(app.config['etc_dir'], ".parameter.xml")
if os.path.exists(param_path): if os.path.exists(param_path):
...@@ -287,11 +312,11 @@ def createFile(): ...@@ -287,11 +312,11 @@ def createFile():
request.form['type'] + ": Permission Denied") request.form['type'] + ": Permission Denied")
try: try:
if request.form['type'] == "file": if request.form['type'] == "file":
f = open(path, 'w').write(" ") open(path, 'w')
else: else:
os.mkdir(path) os.mkdir(path)
return jsonify(code=1, result="") return jsonify(code=1, result="")
except Exception, e: except Exception as e:
return jsonify(code=0, result=str(e)) return jsonify(code=0, result=str(e))
#remove file or directory #remove file or directory
...@@ -303,7 +328,7 @@ def removeFile(): ...@@ -303,7 +328,7 @@ def removeFile():
else: else:
os.remove(request.form['path']) os.remove(request.form['path'])
return jsonify(code=1, result="") return jsonify(code=1, result="")
except Exception, e: except Exception as e:
return jsonify(code=0, result=str(e)) return jsonify(code=0, result=str(e))
@login_required() @login_required()
...@@ -312,7 +337,7 @@ def removeSoftwareDir(): ...@@ -312,7 +337,7 @@ def removeSoftwareDir():
data = removeSoftwareByName(app.config, request.form['md5'], data = removeSoftwareByName(app.config, request.form['md5'],
request.form['title']) request.form['title'])
return jsonify(code=1, result=data) return jsonify(code=1, result=data)
except Exception, e: except Exception as e:
return jsonify(code=0, result=str(e)) return jsonify(code=0, result=str(e))
#read file and return content to ajax #read file and return content to ajax
...@@ -320,6 +345,9 @@ def removeSoftwareDir(): ...@@ -320,6 +345,9 @@ def removeSoftwareDir():
def getFileContent(): def getFileContent():
file_path = realpath(app.config, request.form['file']) file_path = realpath(app.config, request.form['file'])
if file_path: if file_path:
if not isText(file_path):
return jsonify(code=0,
result="Can not open a binary file, please select a text file!")
if not request.form.has_key('truncate'): if not request.form.has_key('truncate'):
return jsonify(code=1, result=open(file_path, 'r').read()) return jsonify(code=1, result=open(file_path, 'r').read())
else: else:
...@@ -386,7 +414,8 @@ def checkFileType(): ...@@ -386,7 +414,8 @@ def checkFileType():
if isText(path): if isText(path):
return jsonify(code=1, result="text") return jsonify(code=1, result="text")
else: else:
return jsonify(code=0, result="Can not open a binary file, please select a text file!") return jsonify(code=0,
result="Can not open a binary file, please select a text file!")
@login_required() @login_required()
def getmd5sum(): def getmd5sum():
...@@ -404,7 +433,7 @@ def getmd5sum(): ...@@ -404,7 +433,7 @@ def getmd5sum():
def slapgridResult(): def slapgridResult():
software_state = isSoftwareRunning(app.config) software_state = isSoftwareRunning(app.config)
instance_state = isInstanceRunning(app.config) instance_state = isInstanceRunning(app.config)
log_result = {"content":"", "position":0} log_result = {"content":"", "position":0, "truncated":False}
if request.form['log'] == "software" or\ if request.form['log'] == "software" or\
request.form['log'] == "instance": request.form['log'] == "instance":
log_file = request.form['log'] + "_log" log_file = request.form['log'] + "_log"
...@@ -416,7 +445,7 @@ def slapgridResult(): ...@@ -416,7 +445,7 @@ def slapgridResult():
@login_required() @login_required()
def stopSlapgrid(): def stopSlapgrid():
result = killRunningSlapgrid(app.config, request.form['type']) result = killRunningProcess(request.form['type'])
return jsonify(result=result) return jsonify(result=result)
@login_required() @login_required()
...@@ -430,9 +459,10 @@ def getPath(): ...@@ -430,9 +459,10 @@ def getPath():
break break
else: else:
list.append(path) list.append(path)
realfile = string.join(list, "#") realfile = '#'.join(list)
if not realfile: if not realfile:
return jsonify(code=0, result="Can not access to this file: Permission Denied!") return jsonify(code=0,
result="Can not access to this file: Permission Denied!")
else: else:
return jsonify(code=1, result=realfile) return jsonify(code=1, result=realfile)
...@@ -451,7 +481,7 @@ def saveParameterXml(): ...@@ -451,7 +481,7 @@ def saveParameterXml():
f.write(content) f.write(content)
f.close() f.close()
result = readParameters(param_path) result = readParameters(param_path)
except Exception, e: except Exception as e:
result = str(e) result = str(e)
software_type = None software_type = None
if request.form['software_type']: if request.form['software_type']:
...@@ -461,8 +491,10 @@ def saveParameterXml(): ...@@ -461,8 +491,10 @@ def saveParameterXml():
else: else:
try: try:
updateInstanceParameter(app.config, software_type) updateInstanceParameter(app.config, software_type)
except Exception, e: except Exception as e:
return jsonify(code=0, result="An error occurred while applying your settings!<br/>" + str(e)) return jsonify(
code=0,
result="An error occurred while applying your settings!<br/>" + str(e))
return jsonify(code=1, result="") return jsonify(code=1, result="")
#read instance parameters into the local xml file and return a dict #read instance parameters into the local xml file and return a dict
...@@ -520,7 +552,8 @@ def configAccount(): ...@@ -520,7 +552,8 @@ def configAccount():
return jsonify(code=0, result=result) return jsonify(code=0, result=result)
else: else:
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 #Global File Manager
@login_required() @login_required()
...@@ -567,8 +600,7 @@ def fileBrowser(): ...@@ -567,8 +600,7 @@ def fileBrowser():
except: except:
abort(404) abort(404)
elif opt == 9: elif opt == 9:
truncateTo = int(request.form.get('truncate', '0')) result = file_request.readFile(dir, filename, False)
result = file_request.readFile(dir, filename)
elif opt == 11: elif opt == 11:
#Upload file #Upload file
result = file_request.uploadFile(dir, request.files) result = file_request.uploadFile(dir, request.files)
...@@ -583,7 +615,7 @@ def fileBrowser(): ...@@ -583,7 +615,7 @@ def fileBrowser():
result = file_request.unzipFile(dir, filename, newfilename) result = file_request.unzipFile(dir, filename, newfilename)
else: else:
result = "ARGS PARSE ERROR: Bad option..." result = "ARGS PARSE ERROR: Bad option..."
except Exception, e: except Exception as e:
return str(e) return str(e)
return result return result
...@@ -596,49 +628,78 @@ def editFile(): ...@@ -596,49 +628,78 @@ def editFile():
#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('/browseWorkspace', 'browseWorkspace', browseWorkspace)
app.add_url_rule('/editSoftwareProfile', 'editSoftwareProfile',
editSoftwareProfile)
app.add_url_rule('/inspectSoftware', 'inspectSoftware', inspectSoftware) app.add_url_rule('/inspectSoftware', 'inspectSoftware', inspectSoftware)
app.add_url_rule('/removeSoftware', 'removeSoftware', removeSoftware) app.add_url_rule('/removeSoftware', 'removeSoftware', removeSoftware)
app.add_url_rule('/runSoftwareProfile', 'runSoftwareProfile', runSoftwareProfile, methods=['POST']) app.add_url_rule('/runSoftwareProfile', 'runSoftwareProfile',
app.add_url_rule('/viewSoftwareLog', 'viewSoftwareLog', viewSoftwareLog, methods=['GET']) runSoftwareProfile, methods=['POST'])
app.add_url_rule('/editInstanceProfile', 'editInstanceProfile', editInstanceProfile) app.add_url_rule('/viewSoftwareLog', 'viewSoftwareLog',
app.add_url_rule('/inspectInstance', 'inspectInstance', inspectInstance, methods=['GET']) viewSoftwareLog, methods=['GET'])
app.add_url_rule('/supervisordStatus', 'supervisordStatus', supervisordStatus, methods=['GET']) app.add_url_rule('/editInstanceProfile', 'editInstanceProfile',
app.add_url_rule('/runInstanceProfile', 'runInstanceProfile', runInstanceProfile, methods=['POST']) 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',
runInstanceProfile, methods=['POST'])
app.add_url_rule('/removeInstance', 'removeInstance', removeInstance) app.add_url_rule('/removeInstance', 'removeInstance', removeInstance)
app.add_url_rule('/viewInstanceLog', 'viewInstanceLog', viewInstanceLog, methods=['GET']) app.add_url_rule('/viewInstanceLog', 'viewInstanceLog',
app.add_url_rule('/stopAllPartition', 'stopAllPartition', stopAllPartition, methods=['GET']) viewInstanceLog, methods=['GET'])
app.add_url_rule('/tailProcess/name/<process>', 'tailProcess', tailProcess, methods=['GET']) app.add_url_rule('/stopAllPartition', 'stopAllPartition',
app.add_url_rule('/startStopProccess/name/<process>/cmd/<action>', 'startStopProccess', startStopProccess, methods=['GET']) stopAllPartition, methods=['GET'])
app.add_url_rule("/getParameterXml/<request>", 'getParameterXml', getParameterXml, 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'])
app.add_url_rule("/stopSlapgrid", 'stopSlapgrid', stopSlapgrid, methods=['POST']) app.add_url_rule("/stopSlapgrid", 'stopSlapgrid', stopSlapgrid, methods=['POST'])
app.add_url_rule("/slapgridResult", 'slapgridResult', slapgridResult, methods=['POST']) app.add_url_rule("/slapgridResult", 'slapgridResult',
slapgridResult, methods=['POST'])
app.add_url_rule("/getmd5sum", 'getmd5sum', getmd5sum, methods=['POST']) app.add_url_rule("/getmd5sum", 'getmd5sum', getmd5sum, methods=['POST'])
app.add_url_rule("/checkFileType", 'checkFileType', checkFileType, methods=['POST']) app.add_url_rule("/checkFileType", 'checkFileType', checkFileType,
app.add_url_rule("/pullProjectFiles", 'pullProjectFiles', pullProjectFiles, methods=['POST']) methods=['POST'])
app.add_url_rule("/pushProjectFiles", 'pushProjectFiles', pushProjectFiles, methods=['POST']) app.add_url_rule("/pullProjectFiles", 'pullProjectFiles', pullProjectFiles,
app.add_url_rule("/getProjectDiff/<project>", 'getProjectDiff', getProjectDiff, methods=['GET']) methods=['POST'])
app.add_url_rule("/pushProjectFiles", 'pushProjectFiles', pushProjectFiles,
methods=['POST'])
app.add_url_rule("/getProjectDiff/<project>", 'getProjectDiff', getProjectDiff,
methods=['GET'])
app.add_url_rule("/newBranch", 'newBranch', newBranch, methods=['POST']) app.add_url_rule("/newBranch", 'newBranch', newBranch, methods=['POST'])
app.add_url_rule("/changeBranch", 'changeBranch', changeBranch, methods=['POST']) app.add_url_rule("/changeBranch", 'changeBranch', changeBranch, methods=['POST'])
app.add_url_rule("/saveFileContent", 'saveFileContent', saveFileContent, methods=['POST']) app.add_url_rule("/saveFileContent", 'saveFileContent', saveFileContent,
app.add_url_rule("/removeSoftwareDir", 'removeSoftwareDir', removeSoftwareDir, methods=['POST']) methods=['POST'])
app.add_url_rule("/getFileContent", 'getFileContent', getFileContent, methods=['POST']) app.add_url_rule("/removeSoftwareDir", 'removeSoftwareDir', removeSoftwareDir,
methods=['POST'])
app.add_url_rule("/getFileContent", 'getFileContent', getFileContent,
methods=['POST'])
app.add_url_rule("/removeFile", 'removeFile', removeFile, methods=['POST']) app.add_url_rule("/removeFile", 'removeFile', removeFile, methods=['POST'])
app.add_url_rule("/createFile", 'createFile', createFile, methods=['POST']) app.add_url_rule("/createFile", 'createFile', createFile, methods=['POST'])
app.add_url_rule("/editCurrentProject", 'editCurrentProject', editCurrentProject) app.add_url_rule("/editCurrentProject", 'editCurrentProject', editCurrentProject)
app.add_url_rule("/getProjectStatus", 'getProjectStatus', getProjectStatus, methods=['POST']) app.add_url_rule("/getProjectStatus", 'getProjectStatus', getProjectStatus,
app.add_url_rule('/openProject/<method>', 'openProject', openProject, methods=['GET']) methods=['POST'])
app.add_url_rule('/openProject/<method>', 'openProject', openProject,
methods=['GET'])
app.add_url_rule("/manageProject", 'manageProject', manageProject, methods=['GET']) app.add_url_rule("/manageProject", 'manageProject', manageProject, methods=['GET'])
app.add_url_rule("/setCurrentProject", 'setCurrentProject', setCurrentProject, methods=['POST']) app.add_url_rule("/setCurrentProject", 'setCurrentProject', setCurrentProject,
methods=['POST'])
app.add_url_rule("/checkFolder", 'checkFolder', checkFolder, methods=['POST']) app.add_url_rule("/checkFolder", 'checkFolder', checkFolder, methods=['POST'])
app.add_url_rule('/createSoftware', 'createSoftware', createSoftware, methods=['POST']) app.add_url_rule('/createSoftware', 'createSoftware', createSoftware,
app.add_url_rule('/cloneRepository', 'cloneRepository', cloneRepository, methods=['POST']) methods=['POST'])
app.add_url_rule('/cloneRepository', 'cloneRepository', cloneRepository,
methods=['POST'])
app.add_url_rule('/openFolder', 'openFolder', openFolder, methods=['POST']) app.add_url_rule('/openFolder', 'openFolder', openFolder, methods=['POST'])
app.add_url_rule('/readFolder', 'readFolder', readFolder, methods=['POST']) app.add_url_rule('/readFolder', 'readFolder', readFolder, methods=['POST'])
app.add_url_rule('/configRepo', 'configRepo', configRepo) app.add_url_rule('/configRepo', 'configRepo', configRepo)
app.add_url_rule("/saveParameterXml", 'saveParameterXml', saveParameterXml, methods=['POST']) app.add_url_rule("/saveParameterXml", 'saveParameterXml', saveParameterXml,
methods=['POST'])
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,
app.add_url_rule("/fileBrowser", 'fileBrowser', fileBrowser, methods=['GET', 'POST']) methods=['POST'])
app.add_url_rule("/fileBrowser", 'fileBrowser', fileBrowser,
methods=['GET', 'POST'])
app.add_url_rule("/editFile", 'editFile', editFile, methods=['GET']) app.add_url_rule("/editFile", 'editFile', editFile, methods=['GET'])
...@@ -26,7 +26,7 @@ class NetworkcacheParser(OptionParser): ...@@ -26,7 +26,7 @@ class NetworkcacheParser(OptionParser):
""" """
def __init__(self, usage=None, version=None): def __init__(self, usage=None, version=None):
""" """
Initialize all options possibles. Initialize all possible options.
""" """
OptionParser.__init__(self, usage=usage, version=version, OptionParser.__init__(self, usage=usage, version=version,
option_list=[ option_list=[
......
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