-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcompileLanguage.py
More file actions
101 lines (86 loc) · 3.46 KB
/
compileLanguage.py
File metadata and controls
101 lines (86 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#-*- coding: utf8 -*-
import dockerContainer
def getVolumnPath(S):
L = S.split(':')
containerVolumn = L[1]
if containerVolumn[len(containerVolumn)-1] != '/':
containerVolumn = containerVolumn + '/'
hostVolumn = L[0]
if hostVolumn[len(hostVolumn)-1] != '/':
hostVolumn = hostVolumn + '/'
return (hostVolumn, containerVolumn)
def compile(sourceFile, volumn, compilerName = 'g++', option='-std=c++0x', binaryName='a.out', imageName='baekjoon/onlinejudge-gcc:4.8', timeLimit=5, logger=None):
(hostVolumn, containerVolumn) = getVolumnPath(volumn)
if len(sourceFile) < 1:
return None
fileNames = containerVolumn + sourceFile[0]
for source in sourceFile[1:]:
fileNames = fileNames + ' ' + containerVolumn + source
if binaryName is not None:
binaryName = '-o ' + containerVolumn + binaryName
else:
binaryName = ''
command = "-v %s %s sh -c '%s %s %s %s'" % (volumn, imageName, compilerName, option, binaryName, fileNames)
logger.debug(command)
D = dockerContainer.execute(command, timeLimit, logger)
exitCode = D['exitcode']
if logger is not None:
logger.info('Compile done. (exit code: %s)' % str(exitCode))
res = {}
if exitCode == 0:
res['state'] = 'success'
res['stdout'] = D['stdout']
res['stderr'] = D['stderr']
elif exitCode == 1:
res['state'] = 'compile error'
res['stdout'] = D['stdout']
res['stderr'] = D['stderr']
elif D['state'] == 'tle':
res['state'] = 'tle'
res['stdout'] = ''
res['stderr'] = 'Compile time limit exceeded.'
else:
res['state'] = 'error'
res['stdout'] = ''
res['stderr'] = 'Server error.'
if logger is not None:
logger.critical('Error while compile: ' + D['stderr'])
else:
print 'Error while compile: ' + D['stderr']
return res
def run(volumn, compilerName = 'g++', option='-std=c++0x', runName='a.out', imageName='cpp', memoryLimit=128, memorySwapLimit=256, stdinName='stdin.txt', timeLimit=5, logger=None):
(hostVolumn, containerVolumn) = getVolumnPath(volumn)
#Run
command = "-v %s --net none --memory %sm --memory-swap %sm %s sh -c '%s < %s'" % (volumn, str(memoryLimit), str(memorySwapLimit), imageName, containerVolumn+runName, containerVolumn+stdinName)
D = dockerContainer.execute(command, timeLimit, logger)
exitCode = D['exitcode']
if logger is not None:
logger.info('Run done. (exit code: %s)' % str(exitCode))
res = {}
if exitCode == 0:
res['state'] = 'success'
res['stdout'] = D['stdout']
res['stderr'] = D['stderr']
elif D['state'] == 'tle':
res['state'] = 'tle'
res['stdout'] = ''
res['stderr'] = 'Running time limit exceeded.'
elif exitCode == 137:
res['state'] = 'error'
res['stdout'] = ''
res['stderr'] = 'Memory limit exceeded.'
elif 'docker' not in D['stderr']:
res['state'] = 'error'
res['stdout'] = D['stdout']
res['stderr'] = D['stderr']
if logger is not None:
logger.info('Exception while running(may due to user): ' + res['stderr'])
else:
res['state'] = 'error'
res['stdout'] = ''
res['stderr'] = 'Server error.'
if logger is not None:
logger.critical('Error while running: ' + res['stderr'])
else:
print 'Error while running: ' + res['stderr']
return res