英文:
dmidecode inside go program running in a kubernetes pod
问题
我在Docker容器中运行了一个Go例程。我需要dmidecode命令的输出,但是输出为空。
Go代码:
func main() {
cmd := exec.Command("dmidecode", "-t 1")
x, _ := cmd.Output()
fmt.Println("output =======", string(x))
}
Docker运行命令:
docker run --device /dev/mem:/dev/mem --cap-add SYS_RAWIO -p 8086:8086 -it my_img:1.0.1
我在这里漏掉了什么?
更新:
在Dockerfile中添加以下内容后,上述代码在Docker中可以正常工作:
FROM alpine:latest
RUN apk --no-cache --update --verbose add grep bash dmidecode && \
rm -rf /var/cache/apk/* /tmp/* /sbin/halt /sbin/poweroff /sbin/reboot
在docker-compose文件中添加以下内容:
privileged: true
但是当我尝试在Kubernetes中使用上述代码时,无法获取dmidecode的输出。
非常感谢您的帮助。
英文:
I have a go routine running in docker container. I need output of the command dmidecode. But its coming blank.
Go:
func main() {
cmd := exec.Command("dmidecode","-t 1")
x,_ := cmd.Output()
fmt.Println("output =======", string(x))
}
Docker run:
docker run --device /dev/mem:/dev/mem --cap-add SYS_RAWIO -p 8086:8086 -it my_img:1.0.1
What am I missing here?
Updated:
The above worked in docker after I added below in Dockerfile:
FROM alpine:latest
RUN apk --no-cache --update --verbose add grep bash dmidecode &&
rm -rf /var/cache/apk/* /tmp/* /sbin/halt /sbin/poweroff /sbin/reboot
And below in docker compose file:
privileged: true
But When tried to use the above in kubernetes it not able to fetch demidecode output.
A help will be really appreciated.
答案1
得分: 3
我在这里可能遗漏了什么?
首先,错误处理。
x, _ := cmd.Output()
在Go语言中,绝对不能忽略错误。与像Python这样的语言不同,Go语言没有异常抛出机制,处理错误返回值是你唯一的机会来判断是否出现了错误。
其次,你还忽略了命令的标准输出流。当命令执行失败时,标准输出流通常包含有用的错误信息,因此os/exec
的Output()
方法会将其作为错误值的一部分返回,除非已经在Cmd
配置中捕获。你的错误处理部分应该对该错误值进行类型断言,如果不是nil,并且是有效的*exec.ExitError
类型,并且类型断言成功,可以通过检查其Stderr字段获取错误消息。
第三,从你的命令看,我可以看出你犯了一个简单的错误:
cmd := exec.Command("dmidecode", "-t 1")
在shell中,空格分隔参数。但这里没有shell;你将-t 1
作为一个参数传递给dmidecode
。你应该将它们作为单独的参数传递,几乎可以确定是这样的:
cmd := exec.Command("dmidecode", "-t", "1")
最后,你已经找到了https://stackoverflow.com/questions/54068234/cant-run-dmidecode-on-docker-container/70084824#70084824,但请确保阅读并理解被接受的答案。然后,配置你的Docker容器以便在没有Go的情况下运行dmidecode
。一旦在命令行中正常工作,相同的Docker配置应该允许在Go调用下正常工作。
英文:
> What am I missing here?
For starters ,error handling.
x,_ := cmd.Output()
Never, ever ignore an error in Go. Unlike languages like, say, Pyhton, there is no exception raising - handling error return values is your only chance to figure out if something went wrong.
Secondly, you're also ignoring your command's Standard Output stream. This is likely to contain a useful error message whenever a command execution doesn't work, so os/exec
's Output()
provides it as part of the error value if not already captured in the Cmd
configuration. Part of your error handling should be doing a type assertion on that error value, if not nil, and if it's a valid *exec.ExitError
, and if that type assertion succeeds, check its Stderr field for an error message.
Third, looking at your command, I can see you made an easy mistake:
cmd := exec.Command("dmidecode","-t 1")
At the shell, whitespace separates arguments. but there is no shell here; you're passing -t 1
all as one argument to dmidecode
. You should be passing them as separate arguments, almost certainly:
cmd := exec.Command("dmidecode","-t", "1")
Finally, you've already found https://stackoverflow.com/questions/54068234/cant-run-dmidecode-on-docker-container/70084824#70084824 , but make sure to read and understand the accepted answer. Then, get your docker container configured to be able to run dmidecode
without Go. Once it works at the command line, the same docker configuration should allow it to work under Go invocation as well.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论