@@ -22,6 +22,11 @@ import (
2222 "text/template"
2323)
2424
25+ const (
26+ InstallUsingNVIDIACTKInstaller = "nvidia-ctk-installer"
27+ InstallUsingPackagingImage = "packaging-image"
28+ )
29+
2530// dockerInstallTemplate is a template for installing the NVIDIA Container Toolkit
2631// on a host using Docker.
2732var dockerInstallTemplate = `
@@ -53,7 +58,7 @@ docker run --pid=host --rm -i --privileged \
5358 -v /var/run/docker.sock:/var/run/docker.sock \
5459 -v "$TEMP_DIR:$TEMP_DIR" \
5560 -v /etc/docker:/config-root \
56- {{.Image }} \
61+ {{.ToolkitImage }} \
5762 --root "$TEMP_DIR" \
5863 --runtime=docker \
5964 --config=/config-root/daemon.json \
@@ -62,37 +67,58 @@ docker run --pid=host --rm -i --privileged \
6267 --restart-mode=systemd
6368`
6469
65- type ToolkitInstaller struct {
66- runner Runner
67- template string
70+ var installFromImageTemplate = `
71+ # Create a temporary directory and rootfs path
72+ TMPDIR="$(mktemp -d)"
6873
74+ # Expose TMPDIR for the child namespace
75+ export TMPDIR
76+
77+ docker run --rm -v ${TMPDIR}:/host-tmpdir --entrypoint="sh" {{.ToolkitImage}}-packaging -c "cp -p -R /artifacts/* /host-tmpdir/"
78+ dpkg -i ${TMPDIR}/packages/ubuntu18.04/amd64/libnvidia-container1_*_amd64.deb ${TMPDIR}/packages/ubuntu18.04/amd64/nvidia-container-toolkit-base_*_amd64.deb ${TMPDIR}/packages/ubuntu18.04/amd64/libnvidia-container-tools_*_amd64.deb
79+
80+ nvidia-container-cli --version
81+ {{if .ConfigureDocker}}
82+ nvidia-ctk runtime configure
83+ {{end}}
84+ {{if .RestartDocker}}
85+ systemctl restart docker
86+ {{end}}
87+ `
88+
89+ type toolkitInstallerOptions struct {
90+ mode string
6991 Image string
7092}
7193
72- type installerOption func (* ToolkitInstaller )
94+ type toolkitInstallerTemplateOptions struct {
95+ ToolkitImage string
96+ ConfigureDocker bool
97+ RestartDocker bool
98+ }
7399
74- func WithRunner (r Runner ) installerOption {
75- return func (i * ToolkitInstaller ) {
76- i .runner = r
77- }
100+ type ToolkitInstaller struct {
101+ template string
102+ toolkitInstallerTemplateOptions
78103}
79104
105+ type installerOption func (* toolkitInstallerOptions )
106+
80107func WithImage (image string ) installerOption {
81- return func (i * ToolkitInstaller ) {
108+ return func (i * toolkitInstallerOptions ) {
82109 i .Image = image
83110 }
84111}
85112
86- func WithTemplate ( template string ) installerOption {
87- return func (i * ToolkitInstaller ) {
88- i .template = template
113+ func WithMode ( mode string ) installerOption {
114+ return func (i * toolkitInstallerOptions ) {
115+ i .mode = mode
89116 }
90117}
91118
92119func NewToolkitInstaller (opts ... installerOption ) (* ToolkitInstaller , error ) {
93- i := & ToolkitInstaller {
94- runner : localRunner {},
95- template : dockerInstallTemplate ,
120+ i := & toolkitInstallerOptions {
121+ mode : InstallUsingNVIDIACTKInstaller ,
96122 }
97123
98124 for _ , opt := range opts {
@@ -103,23 +129,53 @@ func NewToolkitInstaller(opts ...installerOption) (*ToolkitInstaller, error) {
103129 return nil , fmt .Errorf ("image is required" )
104130 }
105131
106- return i , nil
132+ template , err := i .getTemplate ()
133+ if err != nil {
134+ return nil , err
135+ }
136+
137+ ti := & ToolkitInstaller {
138+ template : template ,
139+ toolkitInstallerTemplateOptions : toolkitInstallerTemplateOptions {
140+ ToolkitImage : i .Image ,
141+ },
142+ }
143+ return ti , nil
144+ }
145+
146+ func (i * ToolkitInstaller ) Install (runner Runner ) (string , string , error ) {
147+ renderedScript , err := i .Render ()
148+ if err != nil {
149+ return "" , "" , err
150+ }
151+
152+ return runner .Run (renderedScript )
107153}
108154
109- func (i * ToolkitInstaller ) Install () error {
155+ func (i * ToolkitInstaller ) Render () ( string , error ) {
110156 // Parse the combined template
111157 tmpl , err := template .New ("installScript" ).Parse (i .template )
112158 if err != nil {
113- return fmt .Errorf ("error parsing template: %w" , err )
159+ return "" , fmt .Errorf ("error parsing template: %w" , err )
114160 }
115161
116162 // Execute the template
117163 var renderedScript bytes.Buffer
118- err = tmpl .Execute (& renderedScript , i )
164+ err = tmpl .Execute (& renderedScript , i . toolkitInstallerTemplateOptions )
119165 if err != nil {
120- return fmt .Errorf ("error executing template: %w" , err )
166+ return "" , fmt .Errorf ("error executing template: %w" , err )
121167 }
122168
123- _ , _ , err = i .runner .Run (renderedScript .String ())
124- return err
169+ return renderedScript .String (), nil
170+ }
171+
172+ func (i * toolkitInstallerOptions ) getTemplate () (string , error ) {
173+ switch i .mode {
174+ case InstallUsingNVIDIACTKInstaller :
175+ return dockerInstallTemplate , nil
176+ case InstallUsingPackagingImage :
177+ return installFromImageTemplate , nil
178+ default :
179+ return "" , fmt .Errorf ("unrecognized mode %q" , i .mode )
180+ }
125181}
0 commit comments