有Node的新手,所以请容忍我。我也知道以前有人问过这个问题,但我还不知道如何在我的情况下使用它,所以请再次尝试帮助我。
我正在尝试做的是-尝试使用express-handlebar以列表格式获取特定docker容器的图像。
代码-
app.get('/restore/:userid', async (req,res) => {
let userid = req.params.userid
let userData = await Users.findById(userid, async function(err, data) {
let site = await data.docker.site.slice(8)
let backupsRun = await spawnSync('sh', ['-c', `echo redhat237 | sudo -S docker images | grep ${site} | awk '{print $2}'`], {encoding: 'utf-8'})
let backupsStdout = await backupsRun.stdout
if (backupsRun.status != 0) {var getBackups = new Error("Cannot fetch Backups")}
let backupsStdoutDecoded = await unescape(encodeURIComponent(backupsStdout))
let backupsArr = await backupsStdoutDecoded.split("\n")
/*for (var i = 0; i < backupsArr.length; i++) {
var backups = await backupsArr[i].value
}*/
let backups = backupsArr
try {
console.log(backups + ' Try Block')
await res.render('restore', {
helpers: {
userid: function () {return req.params.userid},
site: site,
backups: backups
}
})
} catch (e) {
if (e.getBackups) {
res.send(e.getBackups)
} else {
res.send(e)
}
}
})
}) //close restore get我可以在console.log中看到输出,但它读取为1行,似乎有1个索引。
test.test.org-12-7-2021T12_13,test.test.org-12-07-21T12_10,test.test.org12-07-21T12_10,test.test.org, Try Block我的车把页面-
<h1>Restore for {{site}} - </h1>
<ul>
{{#each backups}}
<li><p>{{this}}</p></li>
{{else}}
<h3>ERROR - No Backups or we couldn't retrieve your backups</h3>
{{/each}}
</ul>
<div>
{{backups}} - Backups array in div
</div>奇怪的是,我可以在div部分看到我为调试而添加的输出,但是我不能让#each块迭代。
从以下情况我可以理解的是,虽然split()应该返回一个子字符串数组,但由于某种原因,似乎并没有发生这种情况。
我甚至尝试了join()和toString(),但结果是一样的。如果我取消对for循环的注释,并使用.value运行它,它会在console.log中返回"undefined“。
如果有人能指出我的错误并帮助我,我将不胜感激。
发布于 2021-08-04 06:26:31
将backups和site移动到传递给res.render的父对象
res.render('restore', {
helpers: {
userid: function () {return req.params.userid},
},
site,
backups,
})然后循环变量`{{#backups}}
<h1>Restore for {{site}} - </h1>
<ul>
{{#each backups}}
<li><p>{{this}}</p></li>
{{else}}
<h3>ERROR - No Backups or we couldn't retrieve your backups</h3>
{{/each}}
</ul>
<div>
{{ backups }} - Backups array in div
</div>更多清理
当are数组转换为字符串时,它们将使用,联接。console.log(backups + ' Try Block')正在执行此转换。
给予应用程序用户访问权限,无需密码即可通过sudoers运行sudo docker images (或者,如果需要,也可以使用sudo docker,但要了解security implications,即应用程序现在已完全控制主机)
在执行命令时避免使用shell。尽可能使用dockers过滤和输出修饰符,或者在JS中处理输出。
仅在调用async函数时使用await。
设置一个异步函数来运行您的docker命令,假设这可能是常见的。
const util = require('util')
const exec = util.promisify(require('child_process').exec)
async function dockerCommand(docker_args) {
try {
console.log('Running docker', docker_args)
const res = await exec(['sudo', 'docker', ...docker_args])
return res
} catch (e) {
console.error('Error running docker', docker_args, e)
throw e
}
}app.get('/restore/:userid', async (req, res) => {
try {
const userid = req.params.userid
const userData = await Users.findById(userid)
const site = userData.docker.site.slice(8)
const { stdout, stderr } = await dockerCommand('images', `--filter=*:${site}*`, '--format={ .Tag }')
const backups = stdout.split('\n')
console.log('backups for site[%s]', site, backups)
res.render('restore', {
helpers: {
userid: function () {return req.params.userid},
},
site,
backups,
})
} catch (e) {
console.error('Error retrieving backups', req.params.userid, e)
res.send('Error retrieving backups')
}
}) //close restore gethttps://stackoverflow.com/questions/68631350
复制相似问题