Don't block the HTTP request while waiting on the installation
This commit is contained in:
parent
6ef2773c01
commit
5350a2d5a5
2
http.go
2
http.go
|
@ -431,7 +431,7 @@ func (rt *Router) routeServerInstall(w http.ResponseWriter, r *http.Request, ps
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusAccepted)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt *Router) routeServerUpdate(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
func (rt *Router) routeServerUpdate(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
|
|
|
@ -33,7 +33,28 @@ func (s *Server) Install() error {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.Execute()
|
go func(proc *InstallationProcess) {
|
||||||
|
installPath, err := proc.BeforeExecute()
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Errorw(
|
||||||
|
"failed to complete BeforeExecute step of installation process",
|
||||||
|
zap.String("server", proc.Server.Uuid),
|
||||||
|
zap.Error(errors.WithStack(err)),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := proc.Execute(installPath); err != nil {
|
||||||
|
zap.S().Errorw(
|
||||||
|
"failed to complete Execute step of installation process",
|
||||||
|
zap.String("server", proc.Server.Uuid),
|
||||||
|
zap.Error(errors.WithStack(err)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}(p)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type InstallationProcess struct {
|
type InstallationProcess struct {
|
||||||
|
@ -80,7 +101,7 @@ func (ip *InstallationProcess) writeScriptToDisk() (string, error) {
|
||||||
|
|
||||||
scanner := bufio.NewScanner(bytes.NewReader([]byte(ip.Script.Script)))
|
scanner := bufio.NewScanner(bytes.NewReader([]byte(ip.Script.Script)))
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
w.WriteString(scanner.Text()+"\n")
|
w.WriteString(scanner.Text() + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
|
@ -111,7 +132,7 @@ func (ip *InstallationProcess) pullInstallationImage() error {
|
||||||
// Runs before the container is executed. This pulls down the required docker container image
|
// Runs before the container is executed. This pulls down the required docker container image
|
||||||
// as well as writes the installation script to the disk. This process is executed in an async
|
// as well as writes the installation script to the disk. This process is executed in an async
|
||||||
// manner, if either one fails the error is returned.
|
// manner, if either one fails the error is returned.
|
||||||
func (ip *InstallationProcess) beforeExecute() (string, error) {
|
func (ip *InstallationProcess) BeforeExecute() (string, error) {
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(3)
|
wg.Add(3)
|
||||||
|
|
||||||
|
@ -163,18 +184,13 @@ func (ip *InstallationProcess) beforeExecute() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executes the installation process inside a specially created docker container.
|
// Executes the installation process inside a specially created docker container.
|
||||||
func (ip *InstallationProcess) Execute() error {
|
func (ip *InstallationProcess) Execute(installPath string) error {
|
||||||
installScriptPath, err := ip.beforeExecute()
|
|
||||||
if err != nil {
|
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
zap.S().Debugw(
|
zap.S().Debugw(
|
||||||
"creating server installer container",
|
"creating server installer container",
|
||||||
zap.String("server", ip.Server.Uuid),
|
zap.String("server", ip.Server.Uuid),
|
||||||
zap.String("script_path", installScriptPath+"/install.sh"),
|
zap.String("script_path", installPath+"/install.sh"),
|
||||||
)
|
)
|
||||||
|
|
||||||
conf := &container.Config{
|
conf := &container.Config{
|
||||||
|
@ -203,7 +219,7 @@ func (ip *InstallationProcess) Execute() error {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Target: "/mnt/install",
|
Target: "/mnt/install",
|
||||||
Source: installScriptPath,
|
Source: installPath,
|
||||||
Type: mount.TypeBind,
|
Type: mount.TypeBind,
|
||||||
ReadOnly: false,
|
ReadOnly: false,
|
||||||
},
|
},
|
||||||
|
@ -235,28 +251,15 @@ func (ip *InstallationProcess) Execute() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
stream, err := ip.client.ContainerAttach(ctx, r.ID, types.ContainerAttachOptions{
|
sChann, eChann := ip.client.ContainerWait(ctx, r.ID, container.WaitConditionNotRunning)
|
||||||
Stdout: true,
|
select {
|
||||||
Stderr: true,
|
case err := <-eChann:
|
||||||
Stream: true,
|
if err != nil {
|
||||||
})
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
if err != nil {
|
case <-sChann:
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
wg.Add(1)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer stream.Close()
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
io.Copy(os.Stdout, stream.Reader)
|
|
||||||
}()
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
zap.S().Infow("completed installation process", zap.String("server", ip.Server.Uuid))
|
zap.S().Infow("completed installation process", zap.String("server", ip.Server.Uuid))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue
Block a user