diff --git a/api/.eslintrc.json b/api/.eslintrc.json new file mode 100644 index 0000000..579bcfc --- /dev/null +++ b/api/.eslintrc.json @@ -0,0 +1,40 @@ +{ + "env": { + "commonjs": true, + "es2021": true, + "node": true + }, + "plugins": [ + "snakecasejs" + ], + "extends": "eslint:recommended", + "parser": "babel-eslint", + "parserOptions": { + "ecmaVersion": 12 + }, + "settings": + { + "snakecasejs/filter": ["ClassDeclaration", "NewExpression"], + "snakecasejs/whitelist": [] + }, + "rules": { + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "no-unused-vars": ["error", { "argsIgnorePattern": "^_"}], + "snakecasejs/snakecasejs": "warn" + } +} diff --git a/api/Dockerfile b/api/Dockerfile index fd261bd..b3eb8a8 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,12 +1,12 @@ FROM node:15.8.0-buster-slim RUN dpkg-reconfigure -p critical dash +RUN apt-get update && apt-get install -y libxml2 gnupg tar coreutils util-linux \ + && rm -rf /var/lib/apt/lists/* + RUN for i in $(seq 1001 1500); do \ groupadd -g $i runner$i && \ useradd -M runner$i -g $i -u $i ; \ done -RUN apt-get update && \ - apt-get install -y libxml2 gnupg tar coreutils util-linux libc6-dev binutils && \ - rm -rf /var/lib/apt/lists/* ENV NODE_ENV=production WORKDIR /piston_api @@ -15,4 +15,4 @@ RUN yarn COPY ./src ./src CMD [ "node", "src", "-m", "-c", "/piston/config.yaml"] -EXPOSE 6969/tcp +EXPOSE 6969/tcp \ No newline at end of file diff --git a/api/package.json b/api/package.json index 75cb08c..ba86daa 100644 --- a/api/package.json +++ b/api/package.json @@ -1,20 +1,25 @@ { - "name": "piston-api", - "version": "3.0.0", - "description": "API for piston - a high performance code execution engine", - "main": "src/index.js", - "dependencies": { - "body-parser": "^1.19.0", - "express": "^4.17.1", - "express-validator": "^6.10.0", - "is-docker": "^2.1.1", - "js-yaml": "^4.0.0", - "logplease": "^1.2.15", - "nocamel": "HexF/nocamel#patch-1", - "node-fetch": "^2.6.1", - "semver": "^7.3.4", - "uuid": "^8.3.2", - "yargs": "^16.2.0" - }, - "license": "MIT" + "name": "piston-api", + "version": "3.0.0", + "description": "API for piston - a high performance code execution engine", + "main": "src/index.js", + "dependencies": { + "body-parser": "^1.19.0", + "express": "^4.17.1", + "express-validator": "^6.10.0", + "is-docker": "^2.1.1", + "js-yaml": "^4.0.0", + "logplease": "^1.2.15", + "nocamel": "HexF/nocamel#patch-1", + "node-fetch": "^2.6.1", + "semver": "^7.3.4", + "uuid": "^8.3.2", + "yargs": "^16.2.0" + }, + "devDependencies": { + "babel-eslint": "^10.1.0", + "eslint": "^7.20.0", + "eslint-plugin-snakecasejs": "^2.2.0" + }, + "license": "MIT" } diff --git a/api/src/config.js b/api/src/config.js index 2ad3ffc..2d841b0 100644 --- a/api/src/config.js +++ b/api/src/config.js @@ -1,25 +1,25 @@ const fss = require('fs'); const yargs = require('yargs'); -const hide_bin = require('yargs/helpers').hideBin; +const hide_bin = require('yargs/helpers').hideBin; //eslint-disable-line snakecasejs/snakecasejs const Logger = require('logplease'); const logger = Logger.create('config'); const yaml = require('js-yaml'); const header = `# -# ____ _ _ -# | _ \\(_)___| |_ ___ _ __ -# | |_) | / __| __/ _ \\| '_ \\ +# ____ _ _ +# | _ \\(_)___| |_ ___ _ __ +# | |_) | / __| __/ _ \\| '_ \\ # | __/| \\__ \\ || (_) | | | | # |_| |_|___/\\__\\___/|_| |_| # -# A High performance code execution engine +# A High performance code execution engine # github.com/engineer-man/piston # `; const argv = yargs(hide_bin(process.argv)) .usage('Usage: $0 -c [config]') - .demandOption('c') + .demandOption('c') //eslint-disable-line snakecasejs/snakecasejs .option('config', { alias: 'c', describe: 'config file to load from', @@ -29,18 +29,18 @@ const argv = yargs(hide_bin(process.argv)) alias: 'm', type: 'boolean', describe: 'create config file and populate defaults if it does not already exist' - }) - .argv; + }).argv; + const options = [ { key: 'log_level', desc: 'Level of data to log', default: 'INFO', + /* eslint-disable snakecasejs/snakecasejs */ options: Object.values(Logger.LogLevels), - validators: [ - x => Object.values(Logger.LogLevels).includes(x) || `Log level ${x} does not exist` - ] + validators: [x=>Object.values(Logger.LogLevels).includes(x) || `Log level ${x} does not exist`] + /* eslint-enable snakecasejs/snakecasejs */ }, { key: 'bind_address', @@ -110,71 +110,68 @@ const options = [ } ]; -const make_default_config = () => { +function make_default_config(){ let content = header.split('\n'); options.forEach(option => { content = content.concat(option.desc.split('\n').map(x=>`# ${x}`)); - if (option.options) { + if(option.options) content.push('# Options: ' + option.options.join(', ')); - } content.push(`${option.key}: ${option.default}`); - + content.push(''); // New line between }); return content.join('\n'); -}; +} logger.info(`Loading Configuration from ${argv.config}`); -if (argv['make-config']) { +if(argv['make-config']) logger.debug('Make configuration flag is set'); -} -if (!!argv['make-config'] && !fss.exists_sync(argv.config)) { +if(!!argv['make-config'] && !fss.exists_sync(argv.config)){ logger.info('Writing default configuration...'); try { - fss.write_file_sync(argv.config, make_default_config()); - } catch (e) { - logger.error('Error writing default configuration:', e.message); + fss.write_file_sync(argv.config, make_default_config()); + } catch (err) { + logger.error('Error writing default configuration:', err.message); process.exit(1); } } -let config = {}; +var config = {}; logger.debug('Reading config file'); -try { +try{ const cfg_content = fss.read_file_sync(argv.config); config = yaml.load(cfg_content); -} catch(err) { +}catch(err){ logger.error('Error reading configuration file:', err.message); process.exit(1); } logger.debug('Validating config entries'); -let errored = false; +var errored=false; -options.for_each(option => { +options.forEach(option => { logger.debug('Checking option', option.key); - let cfg_val = config[option.key]; + var cfg_val = config[option.key]; - if (cfg_val === undefined) { + if(cfg_val == undefined){ errored = true; logger.error(`Config key ${option.key} does not exist on currently loaded configuration`); return; } - option.validators.for_each(validator => { - let response = validator(cfg_val); - - if (!response) { + option.validators.forEach(validator => { + var response = validator(cfg_val); + if(response !== true){ errored = true; logger.error(`Config option ${option.key} failed validation:`, response); return; @@ -182,10 +179,9 @@ options.for_each(option => { }); }); -if (errored) { - process.exit(1); -} +if(errored) process.exit(1); logger.info('Configuration successfully loaded'); module.exports = config; + diff --git a/api/src/executor/job.js b/api/src/executor/job.js index ba739c4..046cd53 100644 --- a/api/src/executor/job.js +++ b/api/src/executor/job.js @@ -1,5 +1,5 @@ const logger = require('logplease').create('executor/job'); -const {v4: uuidv4} = require('uuid'); +const { v4: uuidv4 } = require('uuid'); const cp = require('child_process'); const path = require('path'); const config = require('../config'); @@ -12,12 +12,11 @@ const job_states = { EXECUTED: Symbol('Executed and ready for cleanup') }; -let uid = 0; -let gid = 0; +var uid=0; +var gid=0; class Job { - - constructor({ runtime, files, args, stdin, timeouts, main, alias }) { + constructor({runtime, files, args, stdin, timeouts, main}){ this.uuid = uuidv4(); this.runtime = runtime; this.files = files; @@ -25,13 +24,9 @@ class Job { this.stdin = stdin; this.timeouts = timeouts; this.main = main; - this.alias = alias; - let file_list = this.files.map(f => f.name); - - if (!file_list.includes(this.main)) { + if(!this.files.map(f=>f.name).includes(this.main)) throw new Error(`Main file "${this.main}" will not be written to disk`); - } this.uid = config.runner_uid_min + uid; this.gid = config.runner_gid_min + gid; @@ -46,30 +41,34 @@ class Job { this.dir = path.join(config.data_directory, globals.data_directories.jobs, this.uuid); } - async prime() { + async prime(){ logger.info(`Priming job uuid=${this.uuid}`); logger.debug('Writing files to job cache'); + await fs.mkdir(this.dir, {mode:0o700}); + + const files = this.files.map(({name: file_name, content}) => { + return fs.write_file(path.join(this.dir, file_name), content); + }); + + await Promise.all(files); + logger.debug(`Transfering ownership uid=${this.uid} gid=${this.gid}`); - - await fs.mkdir(this.dir, { mode:0o700 }); await fs.chown(this.dir, this.uid, this.gid); + + const chowns = this.files.map(({name:file_name}) => { + return fs.chown(path.join(this.dir, file_name), this.uid, this.gid); + }); - for (const file of this.files) { - let file_path = path.join(this.dir, file.name); - - await fs.write_file(file_path, file.content); - await fs.chown(file_path, this.uid, this.gid); - } + await Promise.all(chowns); this.state = job_states.PRIMED; - logger.debug('Primed job'); } - async safe_call(file, args, timeout) { - return new Promise((resolve, reject) => { + async safe_call(file, args, timeout){ + return await new Promise((resolve, reject) => { const unshare = config.enable_unshare ? ['unshare','-n','-r'] : []; const prlimit = [ @@ -88,91 +87,70 @@ class Job { var stderr = ''; const proc = cp.spawn(proc_call[0], proc_call.splice(1) ,{ - env: { - ...this.runtime.env_vars, - PISTON_ALIAS: this.alias - }, + env: this.runtime.env_vars, stdio: 'pipe', cwd: this.dir, uid: this.uid, gid: this.gid, detached: true //give this process its own process group }); - + proc.stdin.write(this.stdin); proc.stdin.end(); + - const kill_timeout = set_timeout(_ => proc.kill('SIGKILL'), timeout); + const kill_timeout = setTimeout(_ => proc.kill('SIGKILL'), timeout); - proc.stderr.on('data', data => { - if (stderr.length > config.output_max_size) { - proc.kill('SIGKILL'); - } else { - stderr += data; - } - }); - - proc.stdout.on('data', data => { - if (stdout.length > config.output_max_size) { - proc.kill('SIGKILL'); - } else { - stdout += data; - } - }); - - const exit_cleanup = () => { - clear_timeout(kill_timeout); + proc.stderr.on('data', d=>{if(stderr.length>config.output_max_size) proc.kill('SIGKILL'); else stderr += d;}); + proc.stdout.on('data', d=>{if(stdout.length>config.output_max_size) proc.kill('SIGKILL'); else stdout += d;}); + function exit_cleanup(){ + clearTimeout(kill_timeout); proc.stderr.destroy(); proc.stdout.destroy(); - - try { + try{ process.kill(-proc.pid, 'SIGKILL'); - } catch { + }catch{ // Process will be dead already, so nothing to kill. } - }; + } proc.on('exit', (code, signal)=>{ exit_cleanup(); - - resolve({ stdout, stderr, code, signal }); + + resolve({stdout, stderr, code, signal}); }); proc.on('error', (err) => { exit_cleanup(); - reject({ error: err, stdout, stderr }); + reject({error: err, stdout, stderr}); }); }); } - async execute() { - if (this.state !== job_states.PRIMED) { + async execute(){ + if(this.state != job_states.PRIMED) throw new Error('Job must be in primed state, current state: ' + this.state.toString()); - } logger.info(`Executing job uuid=${this.uuid} uid=${this.uid} gid=${this.gid} runtime=${this.runtime.toString()}`); logger.debug('Compiling'); - let compile; - - if (this.runtime.compiled) { + var compile = undefined; + if(this.runtime.compiled) compile = await this.safe_call( path.join(this.runtime.pkgdir, 'compile'), - this.files.map(x => x.name), - this.timeouts.compile - ); - } + this.files.map(x=>x.name), + this.timeouts.compile); + logger.debug('Running'); const run = await this.safe_call( path.join(this.runtime.pkgdir, 'run'), [this.main, ...this.args], - this.timeouts.run - ); + this.timeouts.run); this.state = job_states.EXECUTED; @@ -180,15 +158,13 @@ class Job { compile, run }; + } - async cleanup() { + async cleanup(){ logger.info(`Cleaning up job uuid=${this.uuid}`); - await fs.rm(this.dir, { recursive: true, force: true }); + await fs.rm(this.dir, {recursive: true, force: true}); } - } -module.exports = { - Job -}; +module.exports = {Job}; \ No newline at end of file diff --git a/api/src/executor/routes.js b/api/src/executor/routes.js index 3cb4fe2..fe09d63 100644 --- a/api/src/executor/routes.js +++ b/api/src/executor/routes.js @@ -6,49 +6,41 @@ const { Job } = require('./job'); const { body } = require('express-validator'); module.exports = { - run_job_validators: [ body('language') - .isString(), + .isString(), // eslint-disable-line snakecasejs/snakecasejs body('version') - .isString(), + .isString(), // eslint-disable-line snakecasejs/snakecasejs // isSemVer requires it to be a version, not a selector body('files') - .isArray(), + .isArray(), // eslint-disable-line snakecasejs/snakecasejs body('files.*.name') - .isString() + .isString() // eslint-disable-line snakecasejs/snakecasejs .bail() .not() .contains('/'), body('files.*.content') - .isString(), + .isString(), // eslint-disable-line snakecasejs/snakecasejs body('compile_timeout') - .isNumeric(), + .isNumeric(), // eslint-disable-line snakecasejs/snakecasejs body('run_timeout') - .isNumeric(), + .isNumeric(), // eslint-disable-line snakecasejs/snakecasejs body('stdin') - .isString(), + .isString(), // eslint-disable-line snakecasejs/snakecasejs body('args') .isArray(), body('args.*') - .isString() + .isString() // eslint-disable-line snakecasejs/snakecasejs ], + async run_job(req, res){ + // POST /jobs + - // POST /jobs - async run_job(req, res) { const runtime = get_latest_runtime_matching_language_version(req.body.language, req.body.version); - - if (runtime === undefined) { - return res - .status(400) - .send({ - message: `${req.body.language}-${req.body.version} runtime is unknown` - }); - } + if(runtime == undefined) return res.json_error(`${req.body.language}-${req.body.version} runtime is unknown`, 400); const job = new Job({ runtime, - alias: req.body.language, files: req.body.files, args: req.body.args, stdin: req.body.stdin, @@ -62,12 +54,8 @@ module.exports = { await job.prime(); const result = await job.execute(); + res.json_success(result); await job.cleanup(); - - return res - .status(200) - .send(result); } - -}; +}; \ No newline at end of file diff --git a/api/src/globals.js b/api/src/globals.js index 300558e..c9bd427 100644 --- a/api/src/globals.js +++ b/api/src/globals.js @@ -5,7 +5,7 @@ const platform = `${is_docker() ? 'docker' : 'baremetal'}-${ fss.read_file_sync('/etc/os-release') .toString() .split('\n') - .find(x => x.startsWith('ID')) + .find(x=>x.startsWith('ID')) .replace('ID=','') }`; @@ -17,4 +17,4 @@ module.exports = { version: require('../package.json').version, platform, pkg_installed_file: '.ppman-installed' //Used as indication for if a package was installed -}; +}; \ No newline at end of file diff --git a/api/src/index.js b/api/src/index.js index 63d1393..1325243 100644 --- a/api/src/index.js +++ b/api/src/index.js @@ -9,103 +9,117 @@ const fs = require('fs/promises'); const fss = require('fs'); const body_parser = require('body-parser'); const runtime = require('./runtime'); -const { validationResult } = require('express-validator'); +const {validationResult} = require('express-validator'); //eslint-disable-line snakecasejs/snakecasejs const logger = Logger.create('index'); const app = express(); (async () => { logger.info('Setting loglevel to',config.log_level); - Logger.setLogLevel(config.log_level); + Logger.setLogLevel(config.log_level); //eslint-disable-line snakecasejs/snakecasejs + logger.debug('Ensuring data directories exist'); - - Object.values(globals.data_directories).for_each(dir => { - let data_path = path.join(config.data_directory, dir); - + Object.values(globals.data_directories).forEach(dir => { + var data_path = path.join(config.data_directory, dir); logger.debug(`Ensuring ${data_path} exists`); - - if (!fss.exists_sync(data_path)) { + if(!fss.exists_sync(data_path)){ logger.info(`${data_path} does not exist.. Creating..`); - - try { + try{ fss.mkdir_sync(data_path); - } catch(e) { - logger.error(`Failed to create ${data_path}: `, e.message); + }catch(err){ + logger.error(`Failed to create ${data_path}: `, err.message); } } + }); logger.info('Loading packages'); const pkgdir = path.join(config.data_directory,globals.data_directories.packages); const pkglist = await fs.readdir(pkgdir); - const languages = await Promise.all( pkglist.map(lang=> fs.readdir(path.join(pkgdir,lang)) .then(x=>x.map(y=>path.join(pkgdir, lang, y))) )); - - const installed_languages = languages - .flat() - .filter(pkg => fss.exists_sync(path.join(pkg, globals.pkg_installed_file))); + const installed_languages = languages.flat() + .filter(pkg=>fss.exists_sync(path.join(pkg, globals.pkg_installed_file))); installed_languages.forEach(pkg => new runtime.Runtime(pkg)); logger.info('Starting API Server'); + logger.debug('Constructing Express App'); + + logger.debug('Registering custom message wrappers'); + + express.response.json_error = function(message, code) { + this.status(code); + return this.json({success: false, message, code}); + }; + + express.response.json_success = function(obj) { + return this.json({success: true, data: obj}); + }; + logger.debug('Registering middleware'); - app.use(body_parser.urlencoded({ extended: true })); + app.use(body_parser.urlencoded({extended: true})); app.use(body_parser.json()); - const validate = (req, res, next) => { - const errors = validationResult(req); - - if (!errors.isEmpty()) { - return res - .status(422) - .send({ - message: errors.array() - }); - } + function validate(req, res, next) { + const errors = validationResult(req); //eslint-disable-line snakecasejs/snakecasejs + if (!errors.isEmpty()) //eslint-disable-line snakecasejs/snakecasejs + return res.json_error(errors.array(), 422); next(); - }; + } logger.debug('Registering Routes'); const ppman_routes = require('./ppman/routes'); const executor_routes = require('./executor/routes'); - app.get('/packages', ppman_routes.package_list); - app.post('/packages/:language/:version', ppman_routes.package_install); - app.delete('/packages/:language/:version', ppman_routes.package_uninstall); + + app.get('/packages', + ppman_routes.package_list + ); + + app.post('/packages/:language/:version', + ppman_routes.package_install + ); + + app.delete('/packages/:language/:version', + ppman_routes.package_uninstall + ); + app.post('/jobs', executor_routes.run_job_validators, validate, - executor_routes.run_job - ); - app.get('/runtimes', (req, res) => { - const runtimes = runtime - .map(rt => { - return { - language: rt.language, - version: rt.version.raw, - author: rt.author, - aliases: rt.aliases - }; - }); + executor_routes.run_job); - return res - .status(200) - .send(runtimes); - }); + function list_runtimes(_, res){ + const runtimes = runtime.map(rt => ( + { + language: rt.language, + version: rt.version.raw, + author: rt.author, + aliases: rt.aliases + } + )); + + return res.json_success({ + runtimes + }); + } + + app.get('/runtimes', list_runtimes); logger.debug('Calling app.listen'); - const [ address, port ] = config.bind_address.split(':'); + const [address,port] = config.bind_address.split(':'); - app.listen(port, address, () => { + app.listen(port, address, ()=>{ logger.info('API server started on', config.bind_address); }); -})(); + +})(); \ No newline at end of file diff --git a/api/src/ppman/package.js b/api/src/ppman/package.js index 0f4c78d..66a29b7 100644 --- a/api/src/ppman/package.js +++ b/api/src/ppman/package.js @@ -11,73 +11,66 @@ const crypto = require('crypto'); const runtime = require('../runtime'); class Package { - - constructor({ language, version, download, checksum }){ + constructor({language, version, download, checksum}){ this.language = language; this.version = semver.parse(version); this.checksum = checksum; this.download = download; } - get installed() { + get installed(){ return fss.exists_sync(path.join(this.install_path, globals.pkg_installed_file)); } - get install_path() { - return path.join( - config.data_directory, - globals.data_directories.packages, - this.language, - this.version.raw - ); + get download_url(){ + return this.download; } - async install() { - if (this.installed) { - throw new Error('Already installed'); - } + get install_path(){ + return path.join(config.data_directory, + globals.data_directories.packages, + this.language, + this.version.raw); + } + async install(){ + if(this.installed) throw new Error('Already installed'); logger.info(`Installing ${this.language}-${this.version.raw}`); - if (fss.exists_sync(this.install_path)) { + if(fss.exists_sync(this.install_path)){ logger.warn(`${this.language}-${this.version.raw} has residual files. Removing them.`); - await fs.rm(this.install_path, { recursive: true, force: true }); + await fs.rm(this.install_path, {recursive: true, force: true}); } logger.debug(`Making directory ${this.install_path}`); await fs.mkdir(this.install_path, {recursive: true}); - logger.debug(`Downloading package from ${this.download} in to ${this.install_path}`); - const pkgpath = path.join(this.install_path, 'pkg.tar.gz'); - const download = await fetch(this.download); + logger.debug(`Downloading package from ${this.download_url} in to ${this.install_path}`); + const pkgpath = path.join(this.install_path, "pkg.tar.gz"); + const download = await fetch(this.download_url); const file_stream = fss.create_write_stream(pkgpath); await new Promise((resolve, reject) => { - download.body.pipe(file_stream); - download.body.on('error', reject); - - file_stream.on('finish', resolve); + download.body.pipe(file_stream) + download.body.on("error", reject) + file_stream.on("finish", resolve) }); logger.debug('Validating checksums'); - logger.debug(`Assert sha256(pkg.tar.gz) == ${this.checksum}`); + logger.debug(`Assert sha256(pkg.tar.gz) == ${this.checksum}`) const cs = crypto.create_hash("sha256") .update(fss.readFileSync(pkgpath)) .digest('hex'); - - if (cs !== this.checksum) { - throw new Error(`Checksum miss-match want: ${val} got: ${cs}`); - } + if(cs != this.checksum) throw new Error(`Checksum miss-match want: ${val} got: ${cs}`); logger.debug(`Extracting package files from archive ${pkgpath} in to ${this.install_path}`); - await new Promise((resolve, reject) => { + await new Promise((resolve, reject)=>{ const proc = cp.exec(`bash -c 'cd "${this.install_path}" && tar xzf ${pkgpath}'`); - - proc.once('exit', (code, _) => { - code === 0 ? resolve() : reject(); + proc.once('exit', (code,_)=>{ + if(code == 0) resolve(); + else reject(new Error('Failed to extract package')); }); - proc.stdout.pipe(process.stdout); proc.stderr.pipe(process.stderr); @@ -87,35 +80,28 @@ class Package { logger.debug('Registering runtime'); new runtime.Runtime(this.install_path); + logger.debug('Caching environment'); const get_env_command = `cd ${this.install_path}; source environment; env`; - const envout = await new Promise((resolve, reject) => { - let stdout = ''; - - const proc = cp - .spawn( - 'env', - ['-i','bash','-c',`${get_env_command}`], - { - stdio: ['ignore', 'pipe', 'pipe'] - } - ); - - proc.once('exit', (code, _) => { - code === 0 ? resolve(stdout) : reject(); + const envout = await new Promise((resolve, reject)=>{ + var stdout = ''; + const proc = cp.spawn('env',['-i','bash','-c',`${get_env_command}`], { + stdio: ['ignore', 'pipe', 'pipe']}); + proc.once('exit', (code,_)=>{ + if(code == 0) resolve(stdout); + else reject(new Error('Failed to cache environment')); }); - proc.stdout.on('data', data => { + proc.stdout.on('data', (data)=>{ stdout += data; }); proc.once('error', reject); }); - const filtered_env = envout - .split('\n') - .filter(l => !['PWD','OLDPWD','_', 'SHLVL'].includes(l.split('=',2)[0])) + const filtered_env = envout.split('\n') + .filter(l=>!['PWD','OLDPWD','_', 'SHLVL'].includes(l.split('=',2)[0])) .join('\n'); await fs.write_file(path.join(this.install_path, '.env'), filtered_env); @@ -130,9 +116,7 @@ class Package { version: this.version.raw }; } - } -module.exports = { - Package -}; + +module.exports = {Package}; \ No newline at end of file diff --git a/api/src/ppman/routes.js b/api/src/ppman/routes.js index fc8bbaf..c4f0b8a 100644 --- a/api/src/ppman/routes.js +++ b/api/src/ppman/routes.js @@ -4,98 +4,66 @@ const fetch = require('node-fetch'); const config = require('../config'); const { Package } = require('./package'); -const get_package_list = async () => { - const repo_content = await fetch(config.repo_url).then(x => x.text()); - const entries = repo_content - .split('\n') - .filter(x => x.length > 0); +async function get_package_list(){ + const repo_content = await fetch(config.repo_url).then(x=>x.text()); + + const entries = repo_content.split('\n').filter(x=>x.length > 0); return entries.map(line => { - const [ language, version, checksum, download ] = line.split(',', 4); + const [language, version, checksum, download] = line.split(',',4); + return new Package({language, version, checksum, download}); + }) +} - return new Package({ - language, - version, - checksum, - download - }); - }); -}; -const get_package = async (lang, version) => { +async function get_package(lang, version){ const packages = await get_package_list(); - - const candidates = packages - .filter(pkg => { - return pkg.language == lang && semver.satisfies(pkg.version, version) - }); - - candidates.sort((a, b) => semver.rcompare(a.version, b.version)); - - return candidates[0] || null; -}; + const candidates = packages.filter( + pkg => pkg.language == lang && semver.satisfies(pkg.version, version) + ); + return candidates.sort((a,b)=>semver.rcompare(a.version,b.version))[0] || null; +} module.exports = { - - // GET /packages - async package_list(req, res) { + + async package_list(req, res){ + // GET /packages logger.debug('Request to list packages'); - let packages = await get_package_list(); + const packages = await get_package_list(); - packages = packages - .map(pkg => { - return { - language: pkg.language, - language_version: pkg.version.raw, - installed: pkg.installed - }; - }); + res.json_success({ + packages: packages.map(pkg=>({ + language: pkg.language, + language_version: pkg.version.raw, + installed: pkg.installed + })) + }); - return res - .status(200) - .send(packages); }, + async package_install(req,res){ + // POST /packages/:language/:version - // POST /packages/:language/:version - async package_install(req, res) { logger.debug('Request to install package'); const pkg = await get_package(req.params.language, req.params.version); + if(pkg == null) return res.json_error(`Requested package ${req.params.language}-${req.params.version} does not exist`, 404); - if (pkg == null) { - return res - .status(404) - .send({ - message: `Requested package ${req.params.language}-${req.params.version} does not exist` - }); - } - - try { + try{ const response = await pkg.install(); - - return res - .status(200) - .send(response); - } catch(e) { - logger.error(`Error while installing package ${pkg.language}-${pkg.version}:`, e.message); - - return res - .status(500) - .send({ - message: e.message - }); + return res.json_success(response); + }catch(err){ + logger.error(`Error while installing package ${pkg.language}-${pkg.version}:`, err.message); + res.json_error(err.message,500); } + + }, + async package_uninstall(req,res){ + // DELETE /packages/:language/:version - // DELETE /packages/:language/:version - async package_uninstall(req, res) { - return res - .status(500) - .send({ - message: 'Not implemented' - }); + //res.json(req.body); //TODO + res.json_error('not implemented', 500); } - -}; +}; \ No newline at end of file diff --git a/api/src/runtime.js b/api/src/runtime.js index 2603835..5a01891 100644 --- a/api/src/runtime.js +++ b/api/src/runtime.js @@ -8,60 +8,53 @@ const path = require('path'); const runtimes = []; class Runtime { - + #env_vars + #compiled constructor(package_dir){ - let info = JSON.parse( + const {language, version, author, build_platform, aliases} = JSON.parse( fss.read_file_sync(path.join(package_dir, 'pkg-info.json')) ); - const { language, version, author, build_platform, aliases } = info; - this.pkgdir = package_dir; this.language = language; this.version = semver.parse(version); this.author = author; this.aliases = aliases; - if (build_platform !== globals.platform) { - logger.warn( - `Package ${language}-${version} was built for platform ${build_platform}, ` + - `but our platform is ${globals.platform}` - ); + if(build_platform != globals.platform){ + logger.warn(`Package ${language}-${version} was built for platform ${build_platform}, but our platform is ${globals.platform}`); } - + logger.debug(`Package ${language}-${version} was loaded`); - runtimes.push(this); } - get compiled() { - if (this._compiled === undefined) { - this._compiled = fss.exists_sync(path.join(this.pkgdir, 'compile')); - } - - return this._compiled; + get env_file_path(){ + return path.join(this.pkgdir, 'environment'); } - get env_vars() { - if (!this._env_vars) { + get compiled(){ + if(this.#compiled === undefined) this.#compiled = fss.exists_sync(path.join(this.pkgdir, 'compile')); + return this.#compiled; + } + + get env_vars(){ + if(!this.#env_vars){ const env_file = path.join(this.pkgdir, '.env'); const env_content = fss.read_file_sync(env_file).toString(); - - this._env_vars = {}; - + this.#env_vars = {}; env_content .trim() .split('\n') .map(line => line.split('=',2)) .forEach(([key,val]) => { - this._env_vars[key.trim()] = val.trim(); + this.#env_vars[key.trim()] = val.trim(); }); } - - return this._env_vars; + return this.#env_vars; } - toString() { + toString(){ return `${this.language}-${this.version.raw}`; } } @@ -75,3 +68,4 @@ module.exports.get_latest_runtime_matching_language_version = function(lang, ver return module.exports.get_runtimes_matching_language_version(lang, ver) .sort((a,b) => semver.rcompare(a.version, b.version))[0]; }; + diff --git a/cli/commands/ppman_commands/list.js b/cli/commands/ppman_commands/list.js index b4ad16c..5d6584e 100644 --- a/cli/commands/ppman_commands/list.js +++ b/cli/commands/ppman_commands/list.js @@ -18,7 +18,7 @@ exports.handler = async function({axios}){ const packages = await axios.get('/packages'); - const pkg_msg = packages.data + const pkg_msg = packages.data.data.packages .map(msg_format.color) .join('\n'); diff --git a/docker-compose.yaml b/docker-compose.yaml index 0a321a4..8b5f62f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -11,11 +11,11 @@ services: - ./data/piston:/piston - ./repo:/repo tmpfs: - - /piston/jobs:exec + - /piston/jobs piston_fs_repo: #Temporary solution until CI works build: repo - command: ['typescript-4.2.3'] # Only build typescript + command: ['deno-1.7.5'] # Only build deno volumes: - - ./repo:/piston/repo - - ./packages:/piston/packages \ No newline at end of file + - ./repo:/repo + - ./packages:/packages \ No newline at end of file diff --git a/packages/.gitignore b/packages/.gitignore index d98ab0b..92bd97e 100644 --- a/packages/.gitignore +++ b/packages/.gitignore @@ -1,8 +1,8 @@ -*/*/* +*/* *.pkg.tar.gz -!*/*/metadata.json -!*/*/build.sh -!*/*/environment -!*/*/run -!*/*/compile -!*/*/test.* \ No newline at end of file +!*/metadata.json +!*/build.sh +!*/environment +!*/run +!*/compile +!*/test.* \ No newline at end of file diff --git a/packages/CONTRIBUTING.MD b/packages/CONTRIBUTING.MD index 499cff8..0c5381a 100644 --- a/packages/CONTRIBUTING.MD +++ b/packages/CONTRIBUTING.MD @@ -8,11 +8,11 @@ In the example of NodeJS, we would call this `node`, after the main binary. ## Creating new languages -See [deno/1.7.5/](deno/1.7.5/) or any other directory for examples. +See [deno-1.7.5/](deno-1.7.5/) or any other directory for examples. 1. Create a new branch on your fork of engineer-man/piston -2. Create directories named `[language]/[version]`. See Naming Languages for how to determine the name for your language +2. Create a directory named `[language]-[version]`. See Naming Languages for how to determine the name for your language 3. Create a file named `build.sh`, adding a shebang for bash `#!/bin/bash` on the first line. In this file put any steps to compile the specified langauge. diff --git a/packages/Makefile b/packages/Makefile index c0cf6fe..80360f5 100644 --- a/packages/Makefile +++ b/packages/Makefile @@ -1,4 +1,4 @@ -PACKAGES=$(subst /,-,$(shell find * -maxdepth 1 -mindepth 1 -type d)) +PACKAGES=$(shell find * -maxdepth 0 -type d) BUILD_PLATFORM=$(or ${PLATFORM},baremetal-$(shell grep -oP "^ID=\K.+" /etc/os-release)) help: @@ -9,16 +9,14 @@ help: build build-all: $(addsuffix .pkg.tar.gz, ${PACKAGES}) - -define PKG_RULE -$(1).pkg.tar.gz: $(subst -,/,$(1))/ $(subst -,/,$(1))/pkg-info.json - cd $$< && chmod +x ./build.sh && ./build.sh - rm -f $$@ - tar czf $$@ $$< --transform='s|$$<||' -endef - -$(foreach pkg,$(PACKAGES),$(eval $(call PKG_RULE,$(pkg)))) +%.pkg.tar.gz: %/ %/pkg-info.json + cd $< && chmod +x ./build.sh && ./build.sh + rm -f $@ + tar czf $@ $* --transform='s|$*||' %/pkg-info.json: %/metadata.json jq '.build_platform="${BUILD_PLATFORM}"' $< > $@ + + + diff --git a/packages/bash/5.1.0/build.sh b/packages/bash/5.1.0/build.sh deleted file mode 100755 index 67ba7b8..0000000 --- a/packages/bash/5.1.0/build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to build your package in here -PREFIX=$(realpath $(dirname $0)) - -mkdir -p build - -cd build - -curl "https://ftp.gnu.org/gnu/bash/bash-5.1.tar.gz" -o bash.tar.gz - -tar xzf bash.tar.gz --strip-components=1 - -# === autoconf based === -./configure --prefix "$PREFIX" - -make -j$(nproc) -make install -j$(nproc) -cd ../ -rm -rf build diff --git a/packages/bash/5.1.0/environment b/packages/bash/5.1.0/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/bash/5.1.0/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/bash/5.1.0/metadata.json b/packages/bash/5.1.0/metadata.json deleted file mode 100644 index acd4c6b..0000000 --- a/packages/bash/5.1.0/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "bash", - "version": "5.1.0", - "aliases": ["sh"], - "author": "Thomas Hobson " -} diff --git a/packages/bash/5.1.0/run b/packages/bash/5.1.0/run deleted file mode 100644 index be4ec50..0000000 --- a/packages/bash/5.1.0/run +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime -bash $* diff --git a/packages/bash/5.1.0/test.bash b/packages/bash/5.1.0/test.bash deleted file mode 100644 index 727518f..0000000 --- a/packages/bash/5.1.0/test.bash +++ /dev/null @@ -1 +0,0 @@ -echo "OK" \ No newline at end of file diff --git a/packages/dart/2.12.1/build.sh b/packages/dart/2.12.1/build.sh deleted file mode 100755 index e01d7ce..0000000 --- a/packages/dart/2.12.1/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -curl -L "https://storage.googleapis.com/dart-archive/channels/stable/release/2.12.1/sdk/dartsdk-linux-x64-release.zip" -o dart.zip - -unzip dart.zip -rm dart.zip - -cp -r dart-sdk/* . -rm -rf dart-sdk - -chmod -R +rx bin \ No newline at end of file diff --git a/packages/dart/2.12.1/environment b/packages/dart/2.12.1/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/dart/2.12.1/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/dart/2.12.1/metadata.json b/packages/dart/2.12.1/metadata.json deleted file mode 100644 index 388121e..0000000 --- a/packages/dart/2.12.1/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "dart", - "version": "2.12.1", - "aliases": [], - "author": "Thomas Hobson " -} diff --git a/packages/dart/2.12.1/run b/packages/dart/2.12.1/run deleted file mode 100644 index dfdbd40..0000000 --- a/packages/dart/2.12.1/run +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime -dart run $* diff --git a/packages/dart/2.12.1/test.dart b/packages/dart/2.12.1/test.dart deleted file mode 100644 index 27e87b2..0000000 --- a/packages/dart/2.12.1/test.dart +++ /dev/null @@ -1,3 +0,0 @@ -void main() { - print('OK'); -} \ No newline at end of file diff --git a/packages/deno/1.7.5/build.sh b/packages/deno-1.7.5/build.sh similarity index 100% rename from packages/deno/1.7.5/build.sh rename to packages/deno-1.7.5/build.sh diff --git a/packages/deno/1.7.5/environment b/packages/deno-1.7.5/environment similarity index 100% rename from packages/deno/1.7.5/environment rename to packages/deno-1.7.5/environment diff --git a/packages/deno/1.7.5/metadata.json b/packages/deno-1.7.5/metadata.json similarity index 100% rename from packages/deno/1.7.5/metadata.json rename to packages/deno-1.7.5/metadata.json diff --git a/packages/deno/1.7.5/run b/packages/deno-1.7.5/run similarity index 100% rename from packages/deno/1.7.5/run rename to packages/deno-1.7.5/run diff --git a/packages/deno/1.7.5/test.ts b/packages/deno-1.7.5/test.ts similarity index 100% rename from packages/deno/1.7.5/test.ts rename to packages/deno-1.7.5/test.ts diff --git a/packages/gawk/5.1.0/build.sh b/packages/gawk/5.1.0/build.sh deleted file mode 100644 index 25a5566..0000000 --- a/packages/gawk/5.1.0/build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to build your package in here -PREFIX=$(realpath $(dirname $0)) - -mkdir -p build - -cd build - -curl "https://ftp.gnu.org/gnu/gawk/gawk-5.1.0.tar.gz" -o gawk.tar.gz - -tar xzf gawk.tar.gz --strip-components=1 - -# === autoconf based === -./configure --prefix "$PREFIX" - -make -j$(nproc) -make install -j$(nproc) -cd ../ -rm -rf build diff --git a/packages/gawk/5.1.0/compile b/packages/gawk/5.1.0/compile deleted file mode 100644 index e37a74c..0000000 --- a/packages/gawk/5.1.0/compile +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to compile source code, remove this file if the language does not require this stage diff --git a/packages/gawk/5.1.0/environment b/packages/gawk/5.1.0/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/gawk/5.1.0/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/gawk/5.1.0/metadata.json b/packages/gawk/5.1.0/metadata.json deleted file mode 100644 index a4f3ae2..0000000 --- a/packages/gawk/5.1.0/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "gawk", - "version": "5.1.0", - "aliases": ["awk"], - "author": "Thomas Hobson " -} diff --git a/packages/gawk/5.1.0/run b/packages/gawk/5.1.0/run deleted file mode 100644 index 567b400..0000000 --- a/packages/gawk/5.1.0/run +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime -gawk-5.1.0 -f $* diff --git a/packages/gawk/5.1.0/test.awk b/packages/gawk/5.1.0/test.awk deleted file mode 100644 index 25e1bd3..0000000 --- a/packages/gawk/5.1.0/test.awk +++ /dev/null @@ -1 +0,0 @@ -{print "OK"} \ No newline at end of file diff --git a/packages/gcc/10.2.0/build.sh b/packages/gcc/10.2.0/build.sh deleted file mode 100755 index 942e4ac..0000000 --- a/packages/gcc/10.2.0/build.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to build your package in here -[[ -d "bin" ]] && exit 0 -PREFIX=$(realpath $(dirname $0)) - -mkdir -p build obj - -cd build - -curl "https://ftp.gnu.org/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.gz" -o gcc.tar.gz - -tar xzf gcc.tar.gz --strip-components=1 - -./contrib/download_prerequisites - -cd ../obj - -# === autoconf based === -../build/configure --prefix "$PREFIX" --enable-languages=c,c++,d --disable-multilib --disable-bootstrap - -make -j$(nproc) -make install -j$(nproc) -cd ../ -rm -rf build obj diff --git a/packages/gcc/10.2.0/compile b/packages/gcc/10.2.0/compile deleted file mode 100644 index e83346d..0000000 --- a/packages/gcc/10.2.0/compile +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to compile source code, remove this file if the language does not require this stage - - -case "${PISTON_ALIAS}" in - gcc | c) - gcc -std=c11 $* -lm - ;; - g++ | c++ | cpp) - g++ -std=c++17 $* - ;; - gccgo | go) - gccgo $* - ;; - gdc | d) - gdc $* - ;; - *) - echo "How did you get here? (${PISTON_ALIAS})" - exit 1 - ;; -esac - -chmod +x a.out \ No newline at end of file diff --git a/packages/gcc/10.2.0/environment b/packages/gcc/10.2.0/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/gcc/10.2.0/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/gcc/10.2.0/metadata.json b/packages/gcc/10.2.0/metadata.json deleted file mode 100644 index 8f3e9b5..0000000 --- a/packages/gcc/10.2.0/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "gcc", - "version": "10.2.0", - "aliases": ["c","g++","c++","cpp","gdc","d"], - "author": "Thomas Hobson " -} diff --git a/packages/gcc/10.2.0/run b/packages/gcc/10.2.0/run deleted file mode 100644 index 63e3443..0000000 --- a/packages/gcc/10.2.0/run +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime - -shift # Discard main filename -./a.out $* diff --git a/packages/gcc/10.2.0/test.c b/packages/gcc/10.2.0/test.c deleted file mode 100644 index fafae75..0000000 --- a/packages/gcc/10.2.0/test.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(void) { - printf("OK"); - return 0; -} \ No newline at end of file diff --git a/packages/gcc/10.2.0/test.cpp b/packages/gcc/10.2.0/test.cpp deleted file mode 100644 index 9d0499e..0000000 --- a/packages/gcc/10.2.0/test.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(void) { - printf("OK"); - return 0; -} \ No newline at end of file diff --git a/packages/gcc/10.2.0/test.d b/packages/gcc/10.2.0/test.d deleted file mode 100644 index e74851d..0000000 --- a/packages/gcc/10.2.0/test.d +++ /dev/null @@ -1,5 +0,0 @@ -import std.stdio; - -void main() { - writeln("OK"); -} \ No newline at end of file diff --git a/packages/init b/packages/init deleted file mode 100755 index 2bf65cc..0000000 --- a/packages/init +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -if [[ $# -lt 3 ]]; then - echo "Usage: $0 [name] [version] [source]" - echo "" - echo "Initializes an empty package" - exit 1 -fi - -NAME=$1 -VERSION=$2 -AUTHOR="$(git config user.name) <$(git config user.email)>" -SOURCE=$3 - -DIR=$NAME/$VERSION - -mkdir -p $DIR - -build_instructions(){ - echo 'PREFIX=$(realpath $(dirname $0))' - echo - echo 'mkdir -p build' - echo - echo 'cd build' - echo - echo "curl \"$SOURCE\" -o $NAME.tar.gz" - echo - echo "tar xzf $NAME.tar.gz --strip-components=1" - echo - - echo "# === autoconf based ===" - echo './configure --prefix "$PREFIX"' - echo - echo 'make -j$(nproc)' - echo 'make install -j$(nproc)' - - echo 'cd ../' - echo 'rm -rf build' - -} - -cd $DIR - -for name in build.sh environment run compile; do - echo "#!/usr/bin/env bash" > "$name" - echo "" >> "$name" -done - -echo "# Put instructions to build your package in here" >> build.sh -echo "" -build_instructions >> build.sh - -echo "# Put 'export' statements here for environment variables" >> environment -echo "export PATH=\$PWD/bin:\$PATH" >> environment - -echo "# Put instructions to run the runtime" >> run -echo "$NAME-$VERSION \$*" >> run - -echo "# Put instructions to compile source code, remove this file if the language does not require this stage" >> compile - -jq '.language = "'$NAME'" | .version = "'$VERSION'" | .aliases = [] | .author = "'"$AUTHOR"'"' <<< "{}" > metadata.json - -cd - > /dev/null - -echo $DIR \ No newline at end of file diff --git a/packages/java/15.0.2/build.sh b/packages/java/15.0.2/build.sh deleted file mode 100755 index 3d56ee0..0000000 --- a/packages/java/15.0.2/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to build your package in here - -curl "https://download.java.net/java/GA/jdk15.0.2/0d1cfde4252546c6931946de8db48ee2/7/GPL/openjdk-15.0.2_linux-x64_bin.tar.gz" -o java.tar.gz - -tar xzf java.tar.gz --strip-components=1 -rm java.tar.gz diff --git a/packages/java/15.0.2/environment b/packages/java/15.0.2/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/java/15.0.2/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/java/15.0.2/metadata.json b/packages/java/15.0.2/metadata.json deleted file mode 100644 index 2f24706..0000000 --- a/packages/java/15.0.2/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "java", - "version": "15.0.2", - "aliases": [], - "author": "Thomas Hobson " -} diff --git a/packages/java/15.0.2/run b/packages/java/15.0.2/run deleted file mode 100644 index 2215edd..0000000 --- a/packages/java/15.0.2/run +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime -java $* diff --git a/packages/java/15.0.2/test.java b/packages/java/15.0.2/test.java deleted file mode 100644 index 2dc0eaa..0000000 --- a/packages/java/15.0.2/test.java +++ /dev/null @@ -1,5 +0,0 @@ -public class HelloWorld { - public static void main(String[] args) { - System.out.println("OK"); - } -} \ No newline at end of file diff --git a/packages/jelly/0.1.31/build.sh b/packages/jelly/0.1.31/build.sh deleted file mode 100755 index 8aec708..0000000 --- a/packages/jelly/0.1.31/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -source ../../python/3.9.1/build.sh - -mkdir -p build - -git clone -q https://github.com/DennisMitchell/jellylanguage.git build/jelly -cd build/jelly -../../bin/python3.9 setup.py install --optimize=1 - -cd ../../ -rm -rf build \ No newline at end of file diff --git a/packages/jelly/0.1.31/metadata.json b/packages/jelly/0.1.31/metadata.json deleted file mode 100644 index bf63814..0000000 --- a/packages/jelly/0.1.31/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "jelly", - "version": "0.1.31", - "author": "Thomas Hobson ", - "aliases": [] -} \ No newline at end of file diff --git a/packages/jelly/0.1.31/run b/packages/jelly/0.1.31/run deleted file mode 100644 index 7f4dd38..0000000 --- a/packages/jelly/0.1.31/run +++ /dev/null @@ -1 +0,0 @@ -jelly fu $* \ No newline at end of file diff --git a/packages/jelly/0.1.31/test.jelly b/packages/jelly/0.1.31/test.jelly deleted file mode 100644 index b32bbcd..0000000 --- a/packages/jelly/0.1.31/test.jelly +++ /dev/null @@ -1 +0,0 @@ -“OK” \ No newline at end of file diff --git a/packages/kotlin/1.4.31/build.sh b/packages/kotlin/1.4.31/build.sh deleted file mode 100755 index 4ea535d..0000000 --- a/packages/kotlin/1.4.31/build.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -source ../../java/15.0.2/build.sh - -curl -L "https://github.com/JetBrains/kotlin/releases/download/v1.4.31/kotlin-compiler-1.4.31.zip" -o kotlin.zip -unzip kotlin.zip -rm kotlin.zip - -cp -r kotlinc/* . -rm -rf kotlinc \ No newline at end of file diff --git a/packages/kotlin/1.4.31/compile b/packages/kotlin/1.4.31/compile deleted file mode 100644 index 8be38a7..0000000 --- a/packages/kotlin/1.4.31/compile +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to compile source code, remove this file if the language does not require this stage -kotlinc $* -include-runtime -d code.jar \ No newline at end of file diff --git a/packages/kotlin/1.4.31/environment b/packages/kotlin/1.4.31/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/kotlin/1.4.31/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/kotlin/1.4.31/metadata.json b/packages/kotlin/1.4.31/metadata.json deleted file mode 100644 index 87ffdf8..0000000 --- a/packages/kotlin/1.4.31/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "kotlin", - "version": "1.4.31", - "aliases": ["kt"], - "author": "Thomas Hobson " -} diff --git a/packages/kotlin/1.4.31/run b/packages/kotlin/1.4.31/run deleted file mode 100644 index d7c9501..0000000 --- a/packages/kotlin/1.4.31/run +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime -java -jar code.jar \ No newline at end of file diff --git a/packages/kotlin/1.4.31/test.kt b/packages/kotlin/1.4.31/test.kt deleted file mode 100644 index 31acf7b..0000000 --- a/packages/kotlin/1.4.31/test.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun main() { - println("OK") -} \ No newline at end of file diff --git a/packages/mono/6.12.0/build.sh b/packages/mono-6.12.0/build.sh similarity index 51% rename from packages/mono/6.12.0/build.sh rename to packages/mono-6.12.0/build.sh index 31bfaa9..59fb3ad 100755 --- a/packages/mono/6.12.0/build.sh +++ b/packages/mono-6.12.0/build.sh @@ -1,8 +1,6 @@ #!/bin/bash -PREFIX=$(realpath $(dirname $0)) - -mkdir -p build/mono +mkdir -p build/tmp build/mono cd build curl "https://download.mono-project.com/sources/mono/mono-6.12.0.122.tar.xz" -o mono.tar.xz @@ -10,10 +8,12 @@ tar xf mono.tar.xz --strip-components=1 -C mono cd mono -./configure --prefix "$PREFIX" +./configure --prefix /piston/packages/mono/6.12.0/mono-6.12.0 make -j$(nproc) -make install -j$(nproc) +DESTDIR=build/tmp make install -j$(nproc) + +mv build/tmp/piston/packages/mono/6.12.0/mono-6.12.0 ../../mono-6.12.0 cd ../../ rm -rf build diff --git a/packages/mono/6.12.0/compile b/packages/mono-6.12.0/compile similarity index 100% rename from packages/mono/6.12.0/compile rename to packages/mono-6.12.0/compile diff --git a/packages/mono/6.12.0/environment b/packages/mono-6.12.0/environment similarity index 100% rename from packages/mono/6.12.0/environment rename to packages/mono-6.12.0/environment diff --git a/packages/mono/6.12.0/metadata.json b/packages/mono-6.12.0/metadata.json similarity index 100% rename from packages/mono/6.12.0/metadata.json rename to packages/mono-6.12.0/metadata.json diff --git a/packages/mono/6.12.0/run b/packages/mono-6.12.0/run similarity index 100% rename from packages/mono/6.12.0/run rename to packages/mono-6.12.0/run diff --git a/packages/mono/6.12.0/test.cs b/packages/mono-6.12.0/test.cs similarity index 100% rename from packages/mono/6.12.0/test.cs rename to packages/mono-6.12.0/test.cs diff --git a/packages/nasm/2.15.5/build.sh b/packages/nasm/2.15.5/build.sh deleted file mode 100755 index 1e1f4c3..0000000 --- a/packages/nasm/2.15.5/build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to build your package in here -PREFIX=$(realpath $(dirname $0)) - -mkdir -p build - -cd build - -curl -L "https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.gz" -o nasm.tar.gz - -tar xzf nasm.tar.gz --strip-components=1 - -# === autoconf based === -./configure --prefix "$PREFIX" - -make -j$(nproc) -make install -j$(nproc) -cd ../ -rm -rf build diff --git a/packages/nasm/2.15.5/compile b/packages/nasm/2.15.5/compile deleted file mode 100644 index a8fe6da..0000000 --- a/packages/nasm/2.15.5/compile +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to compile source code, remove this file if the language does not require this stage - - -case "${PISTON_ALIAS}" in - nasm) - nasm -f elf32 -o binary.o $* - ld -m elf_i386 binary.o -o binary - ;; - nasm64) - nasm -f elf64 -o binary.o $* - ld -m elf_x86_64 binary.o -o binary - ;; - *) - echo "How did you get here? (${PISTON_ALIAS})" - exit 1 - ;; -esac - -chmod +x ./binary \ No newline at end of file diff --git a/packages/nasm/2.15.5/environment b/packages/nasm/2.15.5/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/nasm/2.15.5/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/nasm/2.15.5/metadata.json b/packages/nasm/2.15.5/metadata.json deleted file mode 100644 index e9d1507..0000000 --- a/packages/nasm/2.15.5/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "nasm", - "version": "2.15.5", - "aliases": ["nasm64"], - "author": "Thomas Hobson " -} diff --git a/packages/nasm/2.15.5/run b/packages/nasm/2.15.5/run deleted file mode 100644 index 53a6099..0000000 --- a/packages/nasm/2.15.5/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime -shift -./binary $* diff --git a/packages/nasm/2.15.5/test.nasm.asm b/packages/nasm/2.15.5/test.nasm.asm deleted file mode 100644 index d1e5a57..0000000 --- a/packages/nasm/2.15.5/test.nasm.asm +++ /dev/null @@ -1,16 +0,0 @@ -SECTION .DATA -good: db 'OK',10 -txtlen: equ $-good - -SECTION .TEXT -GLOBAL _start - -_start: -mov eax,4 -mov ebx,1 -mov ecx,good -mov edx,txtlen -int 80h -mov eax,1 -mov ebx,0 -int 80h \ No newline at end of file diff --git a/packages/nasm/2.15.5/test.nasm64.asm b/packages/nasm/2.15.5/test.nasm64.asm deleted file mode 100644 index 20ea316..0000000 --- a/packages/nasm/2.15.5/test.nasm64.asm +++ /dev/null @@ -1,18 +0,0 @@ -SECTION .data - good: db "OK", 0x0 - txtlen: equ $ - good - -SECTION .text -GLOBAL _start - -_start: - ;sys_write - mov rax, 1 - mov rdi, 1 - mov rsi, good - mov rdx, txtlen - syscall - ;sys_exit - mov rax, 60 - mov rdi, 0 - syscall \ No newline at end of file diff --git a/packages/node/15.10.0/build.sh b/packages/node-15.10.0/build.sh similarity index 100% rename from packages/node/15.10.0/build.sh rename to packages/node-15.10.0/build.sh diff --git a/packages/jelly/0.1.31/environment b/packages/node-15.10.0/environment similarity index 100% rename from packages/jelly/0.1.31/environment rename to packages/node-15.10.0/environment diff --git a/packages/node/15.10.0/metadata.json b/packages/node-15.10.0/metadata.json similarity index 100% rename from packages/node/15.10.0/metadata.json rename to packages/node-15.10.0/metadata.json diff --git a/packages/node/15.10.0/run b/packages/node-15.10.0/run similarity index 100% rename from packages/node/15.10.0/run rename to packages/node-15.10.0/run diff --git a/packages/node/15.10.0/test.js b/packages/node-15.10.0/test.js similarity index 100% rename from packages/node/15.10.0/test.js rename to packages/node-15.10.0/test.js diff --git a/packages/node/15.10.0/environment b/packages/node/15.10.0/environment deleted file mode 100644 index bd0ff98..0000000 --- a/packages/node/15.10.0/environment +++ /dev/null @@ -1 +0,0 @@ -export PATH=$PWD/bin:$PATH \ No newline at end of file diff --git a/packages/php-8.0.2/build.sh b/packages/php-8.0.2/build.sh new file mode 100755 index 0000000..ba78728 --- /dev/null +++ b/packages/php-8.0.2/build.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +mkdir -p build/tmp build/php +cd build + +curl "https://www.php.net/distributions/php-8.0.2.tar.gz" -o php.tar.gz +tar xzf php.tar.gz --strip-components=1 -C php + +cd php + + +./configure --prefix /piston/packages/php/8.0.2/php-8.0.2 + +make -j$(nproc) +INSTALL_ROOT=build/tmp make install -j$(nproc) + + +mv build/tmp/piston/packages/php/8.0.2/php-8.0.2 ../../php-8.0.2 + + diff --git a/packages/php/8.0.2/environment b/packages/php-8.0.2/environment similarity index 100% rename from packages/php/8.0.2/environment rename to packages/php-8.0.2/environment diff --git a/packages/php/8.0.2/metadata.json b/packages/php-8.0.2/metadata.json similarity index 100% rename from packages/php/8.0.2/metadata.json rename to packages/php-8.0.2/metadata.json diff --git a/packages/php/8.0.2/run b/packages/php-8.0.2/run similarity index 100% rename from packages/php/8.0.2/run rename to packages/php-8.0.2/run diff --git a/packages/php/8.0.2/test.php b/packages/php-8.0.2/test.php similarity index 100% rename from packages/php/8.0.2/test.php rename to packages/php-8.0.2/test.php diff --git a/packages/php/8.0.2/build.sh b/packages/php/8.0.2/build.sh deleted file mode 100755 index 0a94615..0000000 --- a/packages/php/8.0.2/build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -PREFIX=$(realpath $(dirname $0)) - -mkdir -p build/php -cd build - -curl "https://www.php.net/distributions/php-8.0.2.tar.gz" -o php.tar.gz -tar xzf php.tar.gz --strip-components=1 -C php - -cd php - - -./configure --prefix "$PREFIX" - -make -j$(nproc) -make install -j$(nproc) - -cd ../../ -rm -rf build \ No newline at end of file diff --git a/packages/python/3.9.1/build.sh b/packages/python-3.9.1/build.sh similarity index 51% rename from packages/python/3.9.1/build.sh rename to packages/python-3.9.1/build.sh index 875a191..1ee0843 100755 --- a/packages/python/3.9.1/build.sh +++ b/packages/python-3.9.1/build.sh @@ -1,20 +1,10 @@ #!/bin/bash -PREFIX=$(realpath $(dirname $0)) - -mkdir -p build - -cd build - curl "https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tgz" -o python.tar.gz tar xzf python.tar.gz --strip-components=1 rm python.tar.gz -./configure --prefix "$PREFIX" --with-ensurepip=install +./configure --prefix /piston/packages/python/3.9.1/python-3.9.1 make -j$(nproc) -make install -j$(nproc) - -cd .. - -rm -rf build +ln -s python python3.9 diff --git a/packages/python-3.9.1/environment b/packages/python-3.9.1/environment new file mode 100644 index 0000000..98fd770 --- /dev/null +++ b/packages/python-3.9.1/environment @@ -0,0 +1 @@ +export PATH=$PWD:$PATH \ No newline at end of file diff --git a/packages/python/3.9.1/metadata.json b/packages/python-3.9.1/metadata.json similarity index 100% rename from packages/python/3.9.1/metadata.json rename to packages/python-3.9.1/metadata.json diff --git a/packages/python/3.9.1/run b/packages/python-3.9.1/run similarity index 100% rename from packages/python/3.9.1/run rename to packages/python-3.9.1/run diff --git a/packages/python/3.9.1/test.py b/packages/python-3.9.1/test.py similarity index 100% rename from packages/python/3.9.1/test.py rename to packages/python-3.9.1/test.py diff --git a/packages/python/3.9.1/environment b/packages/python/3.9.1/environment deleted file mode 100644 index bd0ff98..0000000 --- a/packages/python/3.9.1/environment +++ /dev/null @@ -1 +0,0 @@ -export PATH=$PWD/bin:$PATH \ No newline at end of file diff --git a/packages/typescript/4.2.3/build.sh b/packages/typescript/4.2.3/build.sh deleted file mode 100755 index 83ab333..0000000 --- a/packages/typescript/4.2.3/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -source ../../node/15.10.0/build.sh - -source ./environment - -bin/npm install -g typescript@4.2.3 \ No newline at end of file diff --git a/packages/typescript/4.2.3/compile b/packages/typescript/4.2.3/compile deleted file mode 100644 index 1258d16..0000000 --- a/packages/typescript/4.2.3/compile +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to compile source code, remove this file if the language does not require this stage - -tsc $* \ No newline at end of file diff --git a/packages/typescript/4.2.3/environment b/packages/typescript/4.2.3/environment deleted file mode 100644 index 780b668..0000000 --- a/packages/typescript/4.2.3/environment +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -# Put 'export' statements here for environment variables -export PATH=$PWD/bin:$PATH diff --git a/packages/typescript/4.2.3/metadata.json b/packages/typescript/4.2.3/metadata.json deleted file mode 100644 index f4a54de..0000000 --- a/packages/typescript/4.2.3/metadata.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "language": "typescript", - "version": "4.2.3", - "aliases": ["ts","node-ts","tsc"], - "author": "Thomas Hobson " -} diff --git a/packages/typescript/4.2.3/run b/packages/typescript/4.2.3/run deleted file mode 100644 index dfd4249..0000000 --- a/packages/typescript/4.2.3/run +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -# Put instructions to run the runtime - -CODE=$(sed 's/ts$/js/' <<<"$1") -shift - -node $CODE $* diff --git a/packages/typescript/4.2.3/test.ts b/packages/typescript/4.2.3/test.ts deleted file mode 100644 index 56ed4a0..0000000 --- a/packages/typescript/4.2.3/test.ts +++ /dev/null @@ -1 +0,0 @@ -console.log("OK") \ No newline at end of file diff --git a/repo/entrypoint.sh b/repo/entrypoint.sh index 54261dc..83e7c73 100755 --- a/repo/entrypoint.sh +++ b/repo/entrypoint.sh @@ -1,11 +1,11 @@ -cd /piston/packages +cd /packages for pkg in "$@" do make -j16 $pkg.pkg.tar.gz done -cd /piston/repo +cd /repo ./mkindex.sh python3 -m http.server \ No newline at end of file diff --git a/shell.nix b/shell.nix index f43b1b4..f9063bc 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,5 @@ { pkgs ? import {} }: pkgs.mkShell { # nativeBuildInputs is usually what you want -- tools you need to run - nativeBuildInputs = [ pkgs.nodejs-15_x pkgs.yarn pkgs.jq ]; + nativeBuildInputs = [ pkgs.nodejs-15_x pkgs.yarn ]; } \ No newline at end of file