@@ -20,6 +20,7 @@ import (
2020 "github.com/hyperhq/hypercli/pkg/signal"
2121 "github.com/hyperhq/hypercli/pkg/stringid"
2222 runconfigopts "github.com/hyperhq/hypercli/runconfig/opts"
23+ "github.com/satori/go.uuid"
2324)
2425
2526type InitVolume struct {
@@ -121,13 +122,13 @@ func (cli *DockerCli) initSpecialVolumes(config *container.Config, hostConfig *c
121122 var (
122123 initConfig * container.Config
123124 initHostConfig * container.HostConfig
124- execJobs []string
125- execID string
125+ errCh chan error
126+ execCount uint32
127+ fip string
126128 )
127129
128130 initConfig = & container.Config {
129131 User : config .User ,
130- Env : config .Env ,
131132 Image : INIT_VOLUME_IMAGE ,
132133 StopSignal : config .StopSignal ,
133134 }
@@ -143,6 +144,8 @@ func (cli *DockerCli) initSpecialVolumes(config *container.Config, hostConfig *c
143144 for _ , vol := range initvols {
144145 initHostConfig .Binds = append (initHostConfig .Binds , vol .Name + ":" + INIT_VOLUME_PATH + vol .Destination )
145146 }
147+ passwd := uuid .NewV1 ()
148+ initConfig .Env = append (config .Env , "ROOTPASSWORD=" + passwd .String (), "LOCALROOT=" + INIT_VOLUME_PATH )
146149
147150 createResponse , err := cli .createContainer (initConfig , initHostConfig , networkingConfig , hostConfig .ContainerIDFile , "" )
148151 if err != nil {
@@ -154,12 +157,18 @@ func (cli *DockerCli) initSpecialVolumes(config *container.Config, hostConfig *c
154157 fmt .Fprintf (cli .err , "clean up init container failed: %s\n " , rmErr .Error ())
155158 }
156159 }
160+ if fip != "" {
161+ if rmErr := cli .releaseFip (fip ); rmErr != nil {
162+ fmt .Fprintf (cli .err , "failed to clean up container fip %s: %s\n " , fip , rmErr .Error ())
163+ }
164+ }
157165 }()
158166
159167 if err = cli .client .ContainerStart (createResponse .ID ); err != nil {
160168 return err
161169 }
162170
171+ errCh = make (chan error , len (initvols ))
163172 for _ , vol := range initvols {
164173 var cmd []string
165174 volType := checkSourceType (vol .Source )
@@ -170,36 +179,62 @@ func (cli *DockerCli) initSpecialVolumes(config *container.Config, hostConfig *c
170179 parts := strings .Split (vol .Source , "/" )
171180 cmd = append (cmd , "wget" , "--no-check-certificate" , "--tries=5" , "--mirror" , "--no-host-directories" , "--cut-dirs=" + strconv .Itoa (len (parts )), vol .Source , "--directory-prefix=" + INIT_VOLUME_PATH + vol .Destination )
172181 case "local" :
173- // TODO
182+ execCount ++
183+ if fip == "" {
184+ fip , err = cli .associateNewFip (createResponse .ID )
185+ if err != nil {
186+ return err
187+ }
188+ }
189+ go func (vol * InitVolume ) {
190+ err := cli .uploadLocalResource (vol .Source , INIT_VOLUME_PATH + vol .Destination , fip , "root" , passwd .String ())
191+ if err != nil {
192+ err = fmt .Errorf ("Failed to upload %s: %s" , vol .Source , err .Error ())
193+ }
194+ errCh <- err
195+ }(vol )
174196 default :
175197 continue
176198 }
177199 if len (cmd ) == 0 {
178200 continue
179201 }
180- if execID , err = cli .ExecCmd (initConfig .User , createResponse .ID , cmd ); err != nil {
181- return err
182- } else {
183- execJobs = append (execJobs , execID )
184- }
202+
203+ execCount ++
204+ go func () {
205+ execID , err := cli .ExecCmd (initConfig .User , createResponse .ID , cmd )
206+ if err != nil {
207+ errCh <- err
208+ } else {
209+ errCh <- cli .WaitExec (execID )
210+ }
211+ }()
185212 }
186213
187214 // wait results
188- for _ , execID = range execJobs {
189- if err = cli .WaitExec (execID ); err != nil {
215+ for ; execCount > 0 ; execCount -- {
216+ err = <- errCh
217+ if err != nil {
190218 return err
191219 }
192220 }
193221
194- // Need to sync before tearing down container because data might be still cached
195- if len (execJobs ) > 0 {
196- syncCmd := []string {"sync" }
197- if execID , err = cli .ExecCmd (initConfig .User , createResponse .ID , syncCmd ); err != nil {
198- return err
199- }
200- if err = cli .WaitExec (execID ); err != nil {
222+ // release fip
223+ if fip != "" {
224+ if err = cli .releaseContainerFip (createResponse .ID ); err != nil {
201225 return err
202226 }
227+ fip = ""
228+ }
229+
230+ // Need to sync before tearing down container because data might be still cached
231+ syncCmd := []string {"sync" }
232+ execID , err := cli .ExecCmd (initConfig .User , createResponse .ID , syncCmd )
233+ if err != nil {
234+ return err
235+ }
236+ if err = cli .WaitExec (execID ); err != nil {
237+ return err
203238 }
204239
205240 _ , err = cli .removeContainer (createResponse .ID , false , false , true )
0 commit comments