This commit is contained in:
2019-06-07 23:04:57 +08:00
commit 36b92f19e0
67 changed files with 18266 additions and 0 deletions

168
src/websocket/container.js Normal file
View File

@ -0,0 +1,168 @@
import { Transform } from 'stream'
import chalk from 'chalk'
const WIN_IMAGE_NAME = 'electronuserland/builder:wine-mono'
const LINUX_IMAGE_NAME = 'electronuserland/builder:10'
export default (io, socket, docker) => {
socket.on('exec', function (id, w, h) {
var container = docker.getContainer(id)
var cmd = {
'AttachStdout': true,
'AttachStderr': true,
'AttachStdin': true,
'Tty': true,
Cmd: ['/bin/bash']
}
container.exec(cmd, (err, exec) => {
var options = {
'Tty': true,
stream: true,
stdin: true,
stdout: true,
stderr: true,
// fix vim
hijack: true
}
container.wait((err, data) => {
console.log(err)
socket.emit('end', 'ended')
})
if (err) {
return
}
exec.start(options, (err, stream) => {
console.log(err)
var dimensions = {
h,
w
}
if (dimensions.h !== 0 && dimensions.w !== 0) {
exec.resize(dimensions, () => {})
}
stream.on('data', (chunk) => {
socket.emit('show', chunk.toString())
})
socket.on('cmd', (data) => {
stream.write(data)
})
})
})
})
socket.on('logs', function (id) {
const container = docker.getContainer(id)
const logsOpts = {
follow: true,
stdout: true,
stderr: true,
timestamps: false
}
container.logs(logsOpts, (err, stream) => {
if (err) {
console.log(err)
socket.emit('err', chalk.red('Error:\n') + err + '.\n')
return
}
stream.on('data', (data) => { socket.emit('show', data.toString('utf-8')) })
stream.on('end', function () {
socket.emit('show', '\n===Stream finished===\n')
stream.destroy()
})
})
})
socket.on('pull', function (type) {
let imageName = null
switch (type) {
case 'win':
imageName = WIN_IMAGE_NAME
break
case 'linux':
imageName = LINUX_IMAGE_NAME
break
}
docker.pull(imageName, function (err, stream) {
if (err) {
console.log(err)
socket.emit('err', chalk.red('Error:\n') + err + '.\n')
return
}
const bytesToSize = (bytes) => {
if (bytes === 0) return '0 B'
const k = 1000 // or 1024
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]
}
let downTmp = []
let downTmpId = []
const commaSplitter = new Transform({
readableObjectMode: true,
transform (chunk, encoding, callback) {
let tmp = ''
try {
var result = chunk.toString().match(/{(.*)}/)
result = result ? result[0] : null
if (!result) callback()
tmp = JSON.parse(result)
if (tmp.id) {
if (downTmpId.includes(tmp.id)) {
for (const n in downTmp) {
if (downTmp[n].id === tmp.id) {
if (tmp.progressDetail && tmp.progressDetail.current && tmp.progressDetail.total) {
const percentage = Math.floor(100 * tmp.progressDetail.current / tmp.progressDetail.total)
downTmp[n].val = ': [' + percentage + '%] Total ' + bytesToSize(tmp.progressDetail.total)
} else if (tmp.status) {
downTmp[n].val = ': ' + tmp.status
}
}
}
} else {
downTmpId.push(tmp.id)
const temp = {}
temp.id = tmp.id
if (tmp.progressDetail && tmp.progressDetail.current && tmp.progressDetail.total) {
const percentage = Math.floor(100 * tmp.progressDetail.current / tmp.progressDetail.total)
temp.val = ': [' + percentage + '%] Total ' + bytesToSize(tmp.progressDetail.total)
} else if (tmp.status) {
temp.val = ': ' + tmp.status
}
downTmp.push(temp)
}
let str = ''
for (const n in downTmp) {
str += downTmp[n].id + downTmp[n].val + '\n'
}
socket.emit('progress', str)
}
} catch (err) {
// console.log(err)
}
callback()
}
})
stream.pipe(commaSplitter)
stream.once('end', () => {
socket.emit('progress', chalk.green('All: [100%] Finish。\n'))
// socket.emit('end', imageName + ' install ' + chalk.green('success') + '.\n')
downTmp = []
downTmpId = []
})
})
})
}

93
src/websocket/git.js Normal file
View File

@ -0,0 +1,93 @@
import git from 'simple-git'
import chalk from 'chalk'
import fs from 'fs'
import path from 'path'
import { SYSTEM } from '../config'
const GIT_SSH_COMMAND = 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
const mkdirsSync = (dirname) => {
if (fs.existsSync(dirname)) {
return true
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname)
return true
}
}
}
export default (io, socket, docker) => {
socket.on('gitPull', (data) => {
const repoPath = SYSTEM.REPOPATH
const workPath = SYSTEM.WORKPATH
const sourcePath = path.join(workPath, '/source')
const linuxPath = path.join(workPath, '/linux')
const winPath = path.join(workPath, '/win')
const gitClone = (repoPath, workPath, type) => {
git().env({
...process.env,
GIT_SSH_COMMAND
})
.clone(repoPath, workPath, (err) => {
if (err) {
socket.emit('err', chalk.red(type + ' clone error:\n') + err + '\n')
return
}
socket.emit('show', chalk.green(type + ' clone is finished!\n'))
})
}
const gitPull = (workPath, type) => {
git(workPath).env({
...process.env,
GIT_SSH_COMMAND
})
.pull((err, update) => {
if (err) {
socket.emit('err', chalk.red(type + ' pull error:\n') + err + '\n')
return
}
if (update && update.summary.changes) {
socket.emit('show', chalk.green(type + ' update success.\n'))
} else {
socket.emit('show', chalk.green(type + ' update success, no change.\n'))
}
})
}
if (!fs.existsSync(sourcePath)) {
mkdirsSync(sourcePath)
gitClone(repoPath, sourcePath, 'Source')
} else {
if (fs.readdirSync(sourcePath).includes('.git')) {
gitPull(sourcePath, 'Source')
} else {
gitClone(repoPath, sourcePath, 'Source')
}
}
if (!fs.existsSync(linuxPath)) {
mkdirsSync(linuxPath)
gitClone(repoPath, linuxPath, 'Linux')
} else {
if (fs.readdirSync(linuxPath).includes('.git')) {
gitPull(linuxPath, 'Linux')
} else {
gitClone(repoPath, linuxPath, 'Linux')
}
}
if (!fs.existsSync(winPath)) {
mkdirsSync(winPath)
gitClone(repoPath, winPath, 'Win')
} else {
if (fs.readdirSync(winPath).includes('.git')) {
gitPull(winPath, 'Win')
} else {
gitClone(repoPath, winPath, 'Win')
}
}
})
}

30
src/websocket/index.js Normal file
View File

@ -0,0 +1,30 @@
import container from './container'
import git from './git'
import log from './log'
import JsSHA from 'jssha'
import {
SYSTEM
} from '../config'
export default (io, docker) => {
console.log('Websocket Runing...')
io.on('connection', function (socket) {
console.log('One user connected - ' + socket.id)
socket.emit('requireAuth', 'distribution')
socket.emit('opend', new Date())
socket.on('auth', function (token) {
const shaObj = new JsSHA('SHA-512', 'TEXT')
shaObj.update(SYSTEM.TOKEN)
const hash = shaObj.getHash('HEX')
if (token === hash) {
container(io, socket, docker)
git(io, socket, docker)
log(io, socket, docker)
socket.emit('auth', 'success')
} else {
socket.emit('auth', 'fail')
}
})
})
}

25
src/websocket/log.js Normal file
View File

@ -0,0 +1,25 @@
import fs from 'fs'
import db from '../lib/db'
export default (io, socket, docker) => {
socket.on('log', function (path) {
path = decodeURI(path)
const logLast = db.get('buildLog')
.filter({logPath: path})
.sortBy((item) => -item.startDate)
.take()
.first()
.value()
if (logLast && logLast.logPath) {
try {
socket.emit('show', fs.readFileSync(logLast.logPath) + '\n')
} catch (err) {
socket.emit('show', err.toString() + '\n')
}
} else {
socket.emit('show', 'No file.')
}
})
}