@@ -21,7 +21,6 @@ import (
2121 "github.com/arduino/go-paths-helper"
2222 "github.com/docker/cli/cli/command"
2323 "github.com/docker/docker/api/types/container"
24- dockerClient "github.com/docker/docker/client"
2524 yaml "github.com/goccy/go-yaml"
2625)
2726
@@ -49,30 +48,55 @@ type Provision struct {
4948 pythonImage string
5049}
5150
51+ // isPreEmbargo checks if the runner version is the pre-embargo version.
52+ // Before the embargo, boards are stuck to run the docker contains version 0.1.16.
53+ // We need to be sure that we aren't enabling features that aren't available in that version, such as:
54+ // - Disable dynamic provisioning
55+ // - Render group functionality
56+ func isPreEmbargo (cfg config.Configuration ) bool {
57+ return cfg .RunnerVersion == "0.1.16"
58+ }
59+
60+ func isDevelopmentMode (cfg config.Configuration ) bool {
61+ return cfg .RunnerVersion != cfg .UsedPythonImageTag
62+ }
63+
5264func NewProvision (
5365 docker command.Cli ,
5466 cfg config.Configuration ,
5567) (* Provision , error ) {
56- isDevelopmentMode := cfg .UsedPythonImageTag != cfg .RunnerVersion
57- if isDevelopmentMode {
58- dynamicProvisionDir := cfg .AssetsDir ().Join (cfg .UsedPythonImageTag )
68+ provision := & Provision {
69+ docker : docker ,
70+ pythonImage : cfg .PythonImage ,
71+ }
72+
73+ if isPreEmbargo (cfg ) && ! isDevelopmentMode (cfg ) {
74+ return provision , nil
75+ }
76+
77+ dynamicProvisionDir := cfg .AssetsDir ().Join (cfg .UsedPythonImageTag )
78+
79+ // In development mode we want to make sure everything is fresh.
80+ if isDevelopmentMode (cfg ) {
5981 _ = dynamicProvisionDir .RemoveAll ()
60- tmpProvisionDir , err := cfg .AssetsDir ().MkTempDir ("dynamic-provisioning" )
61- if err != nil {
62- return nil , fmt .Errorf ("failed to perform creation of dynamic provisioning dir: %w" , err )
63- }
64- if err := dynamicProvisioning (context .Background (), docker .Client (), cfg .PythonImage , tmpProvisionDir .String ()); err != nil {
65- return nil , fmt .Errorf ("failed to perform dynamic provisioning: %w" , err )
66- }
67- if err := tmpProvisionDir .Rename (dynamicProvisionDir ); err != nil {
68- return nil , fmt .Errorf ("failed to rename tmp provisioning folder: %w" , err )
69- }
7082 }
7183
72- return & Provision {
73- docker : docker ,
74- pythonImage : cfg .PythonImage ,
75- }, nil
84+ if dynamicProvisionDir .Exist () {
85+ return provision , nil
86+ }
87+
88+ tmpProvisionDir , err := cfg .AssetsDir ().MkTempDir ("dynamic-provisioning" )
89+ if err != nil {
90+ return nil , fmt .Errorf ("failed to perform creation of dynamic provisioning dir: %w" , err )
91+ }
92+ if err := provision .init (tmpProvisionDir .String ()); err != nil {
93+ return nil , fmt .Errorf ("failed to perform dynamic provisioning: %w" , err )
94+ }
95+ if err := tmpProvisionDir .Rename (dynamicProvisionDir ); err != nil {
96+ return nil , fmt .Errorf ("failed to rename tmp provisioning folder: %w" , err )
97+ }
98+
99+ return provision , nil
76100}
77101
78102func (p * Provision ) App (
@@ -96,13 +120,11 @@ func (p *Provision) App(
96120 return generateMainComposeFile (arduinoApp , bricksIndex , p .pythonImage , cfg , mapped_env , staticStore )
97121}
98122
99- func dynamicProvisioning (
100- ctx context.Context ,
101- docker dockerClient.APIClient ,
102- pythonImage , srcPath string ,
123+ func (p * Provision ) init (
124+ srcPath string ,
103125) error {
104126 containerCfg := & container.Config {
105- Image : pythonImage ,
127+ Image : p . pythonImage ,
106128 User : getCurrentUser (),
107129 Entrypoint : []string {
108130 "/bin/bash" ,
@@ -117,14 +139,14 @@ func dynamicProvisioning(
117139 Binds : []string {srcPath + ":/app" },
118140 AutoRemove : true ,
119141 }
120- resp , err := docker .ContainerCreate (ctx , containerCfg , containerHostCfg , nil , nil , "" )
142+ resp , err := p . docker .Client (). ContainerCreate (context . Background () , containerCfg , containerHostCfg , nil , nil , "" )
121143 if err != nil {
122144 if errors .Is (err , errdefs .ErrNotFound ) {
123- if err := pullBasePythonContainer (ctx , pythonImage ); err != nil {
145+ if err := pullBasePythonContainer (context . Background (), p . pythonImage ); err != nil {
124146 return fmt .Errorf ("provisioning failed to pull base image: %w" , err )
125147 }
126148 // Now that we have pulled the container we recreate it
127- resp , err = docker .ContainerCreate (ctx , containerCfg , containerHostCfg , nil , nil , "" )
149+ resp , err = p . docker .Client (). ContainerCreate (context . Background () , containerCfg , containerHostCfg , nil , nil , "" )
128150 }
129151 if err != nil {
130152 return fmt .Errorf ("provisiong failed to create container: %w" , err )
@@ -133,8 +155,8 @@ func dynamicProvisioning(
133155
134156 slog .Debug ("provisioning container created" , slog .String ("container_id" , resp .ID ))
135157
136- waitCh , errCh := docker .ContainerWait (ctx , resp .ID , container .WaitConditionNextExit )
137- if err := docker .ContainerStart (ctx , resp .ID , container.StartOptions {}); err != nil {
158+ waitCh , errCh := p . docker .Client (). ContainerWait (context . Background () , resp .ID , container .WaitConditionNextExit )
159+ if err := p . docker .Client (). ContainerStart (context . Background () , resp .ID , container.StartOptions {}); err != nil {
138160 return fmt .Errorf ("provisioning failed to start container: %w" , err )
139161 }
140162 slog .Debug ("provisioning container started" , slog .String ("container_id" , resp .ID ))
@@ -283,7 +305,11 @@ func generateMainComposeFile(
283305 }
284306
285307 devices := getDevices ()
286- groups := []string {"dialout" , "video" , "audio" , "render" }
308+
309+ groups := []string {"dialout" , "video" , "audio" }
310+ if ! isPreEmbargo (cfg ) || isDevelopmentMode (cfg ) {
311+ groups = append (groups , "render" )
312+ }
287313
288314 mainAppCompose .Services = & mainService {
289315 Main : service {
0 commit comments