Skip to content

Commit

Permalink
new plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeTWC1984 committed Mar 4, 2024
1 parent 712b128 commit e392c13
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 151 deletions.
104 changes: 63 additions & 41 deletions bin/docker-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,7 @@ const fs = require('fs')
let job = {}
try { job = JSON.parse(fs.readFileSync(process.stdin.fd)) } catch { }


const docker = new Docker();
let stderr_msg

// PARAMETERS
const ENTRYPOINT_PATH = process.env['ENTRYPOINT_PATH'] || '/cronicle.sh'
const cname = 'cronicle-' + (process.env['JOB_ID'] || process.pid)
let imageName = process.env['IMAGE'] || 'alpine'
let script = process.env['SCRIPT'] ?? "#!/bin/sh\necho 'No script specified'"
const autoPull = !!parseInt(process.env['PULL_IMAGE'])
const autoRemove = !parseInt(process.env['KEEP_CONTAINER'])
const keepEntrypoint = !!parseInt(process.env['KEEP_ENTRYPOINT'])
const json = !!parseInt(process.env['JSON'])

let command = []
if((process.env['COMMAND'] || '').trim()) {
command = process.env['COMMAND'].trim().match(/(?:[^\s"]+|"[^"]*")+/g).map(e=> e.replace(/["]+/g, ''))
}

// helpers
// helpers functions
const print = (text) => process.stdout.write(text + EOL)
const printInfo = (text) => process.stdout.write(`[INFO] \x1b[32m${text}\x1b[0m` + EOL)
const printWarning = (text) => process.stdout.write(`[INFO] \x1b[33m${text}\x1b[0m` + EOL)
Expand All @@ -46,6 +27,53 @@ const exit = (message) => {
process.exit(1)
}

let dockerOpts = {}

let registryAuth = {
username: process.env['DOCKER_USER'],
password: process.env['DOCKER_PASSWORD']
}

// check if user specified DOCKER_HOST. If not just user socket default connection
let dh = process.env['DOCKER_HOST']

if (dh) {
try { // resolve password/user from uri
let uri = new URL(process.env[dh] || dh) // uri could be passed as a reference to env var
if(uri.password) dockerOpts.password = decodeURIComponent(uri.password)
if(uri.username) dockerOpts.username = uri.username

// for ssh:// also check env variables for auth
if(process.env['SSH_PASSWORD'] && uri.protocol.startsWith('ssh')) dockerOpts.password = process.env['SSH_PASSWORD']
if(process.env['SSH_KEY'] && uri.protocol.startsWith('ssh')) dockerOpts.sshOptions = { privateKey: process.env['SSH_KEY'] }

} catch (e) {
printError('Invalid DOCKER HOST format, use ssh://user:password@host:port or http://host:2375')
exit(e.message)
}
}


// DOCKER CLIENT

const docker = new Docker(dockerOpts)

// CONTAINER PARAMETERS
const ENTRYPOINT_PATH = process.env['ENTRYPOINT_PATH'] || '/cronicle.sh'
const cname = 'cronicle-' + (process.env['JOB_ID'] || process.pid)
let imageName = process.env['IMAGE'] || 'alpine'
let script = process.env['SCRIPT'] ?? "#!/bin/sh\necho 'No script specified'"
const autoPull = !!parseInt(process.env['PULL_IMAGE'])
const autoRemove = !parseInt(process.env['KEEP_CONTAINER'])
const keepEntrypoint = !!parseInt(process.env['KEEP_ENTRYPOINT'])
const json = !!parseInt(process.env['JSON'])
let stderr_msg

let command = []
if ((process.env['COMMAND'] || '').trim()) {
command = process.env['COMMAND'].trim().match(/(?:[^\s"]+|"[^"]*")+/g).map(e => e.replace(/["]+/g, ''))
}

sig = process.connected ? 'disconnect' : 'SIGTERM'
process.on(sig, async (message) => {
printInfo('Caught SIGTERM')
Expand All @@ -62,13 +90,13 @@ const stdout = new Writable({

if (line.match(/^\s*(\d+)\%\s*$/)) { // handle progress
let progress = Math.max(0, Math.min(100, parseInt(RegExp.$1))) / 100;
print(JSON.stringify({progress: progress}))
print(JSON.stringify({ progress: progress }))
}
else if (line.match(/^\s*\#(.{1,60})\#\s*$/)) { // handle memo
let memoText = RegExp.$1
print(JSON.stringify({memo: memoText}))
print(JSON.stringify({ memo: memoText }))
}
else {
else {
// hack: wrap line with ANSI color to prevent JSON interpretation (default Cronicle behavior)
print(json ? line : `\x1b[109m${line}\x1b[0m`)
}
Expand All @@ -88,7 +116,7 @@ const stderr = new Writable({
})

// env variables
let exclude = ['JOB_SECRET', 'SSH_HOST', 'SSH_KEY', 'PLUGIN_SECRET']
let exclude = ['SSH_HOST', 'SSH_KEY', 'SSH_PASSWORD', 'DOCKER_PASSWORD']
let include = ['BASE_URL', 'BASE_APP_URL', 'DOCKER_HOST', 'PULL_IMAGE', 'KEEP_CONTAINER', 'IMAGE', 'ENTRYPOINT_PATH']
let vars = Object.entries(process.env)
.filter(([k, v]) => ((k.startsWith('JOB_') || k.startsWith('DOCKER_') || k.startsWith('ARG') || include.indexOf(k) > -1) && exclude.indexOf(k) === -1))
Expand All @@ -108,7 +136,7 @@ const createOptions = {
},
};

if(!keepEntrypoint) {
if (!keepEntrypoint) {
createOptions.Entrypoint = [ENTRYPOINT_PATH]
createOptions.WorkingDir = path.dirname(ENTRYPOINT_PATH)
}
Expand All @@ -121,29 +149,23 @@ const dockerRun = async () => {
// create tar archive for entrypoint script
const pack = tar.pack()
pack.entry({ name: ENTRYPOINT_PATH, mode: 0o755 }, script)
if(job.chain_data) {
pack.entry({name: path.join(path.dirname(ENTRYPOINT_PATH), 'chain_data')}, JSON.stringify(job.chain_data))
if (job.chain_data) {
pack.entry({ name: path.join(path.dirname(ENTRYPOINT_PATH), 'chain_data') }, JSON.stringify(job.chain_data))
}
pack.finalize()
let chunks = []
for await (const data of pack) chunks.push(data)
let arch = Buffer.concat(chunks)
try {

try {
container = await docker.createContainer(createOptions)
// copy entrypoint file to root directory
container.putArchive(arch, { path: '/' })
if(docker.modem.host) printInfo('docker host: ' + docker.modem.protocol + '://' + docker.modem.host)
printInfo(`Container ready: name: [${createOptions.name}], image: [${imageName}], keep: ${!autoRemove}`)

// setTimeout(()=>{
// docker.getContainer(cname).stop()
// }, 8000)

// docker.getContainer(cname).

let stream = await container.attach({ stream: true, stdout: true, stderr: true })
container.modem.demuxStream(stream, stdout, stderr);


await container.start()
let exit = await container.wait()
Expand Down Expand Up @@ -185,12 +207,10 @@ async function main(image, onFinish) {
if (autoPull) { //
printWarning(`Image not found, pulling from registry`)
try {
let pullStream = await docker.pull(image)
let pullStream = await docker.pull(image, {'authconfig': registryAuth})
docker.modem.followProgress(pullStream, onFinish, onProgress)
}
catch (e) {
exit(e.message)
}
catch (e) { exit(e.message) }
}
else {
printError(`No such image [${image}], pull it manually or check "Pull Image" option`)
Expand All @@ -199,4 +219,6 @@ async function main(image, onFinish) {
}
}

main(imageName, dockerRun)
// ------ MAIN -----

main(imageName, dockerRun)
Loading

0 comments on commit e392c13

Please sign in to comment.