-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Ingest Manager] Make installer atomic on windows #24253
Changes from 8 commits
1a9e7d5
9c2ca6c
8a3cff1
2684d9c
d09eb7b
f2d31c9
e22fac2
e69e68a
f297533
6404d4d
9726d00
57116a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
// or more contributor license agreements. Licensed under the Elastic License; | ||
// you may not use this file except in compliance with the Elastic License. | ||
|
||
package awaitable | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
|
||
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" | ||
) | ||
|
||
type embeddedInstaller interface { | ||
Install(ctx context.Context, spec program.Spec, version, installDir string) error | ||
} | ||
|
||
type embeddedChecker interface { | ||
Check(ctx context.Context, spec program.Spec, version, installDir string) error | ||
} | ||
|
||
// Installer installs into temporary destination and moves to correct one after | ||
// successful finish. | ||
type Installer struct { | ||
installer embeddedInstaller | ||
checker embeddedChecker | ||
wg sync.WaitGroup | ||
} | ||
|
||
// NewInstaller creates a new AtomicInstaller | ||
func NewInstaller(i embeddedInstaller, ch embeddedChecker) (*Installer, error) { | ||
return &Installer{ | ||
installer: i, | ||
checker: ch, | ||
}, nil | ||
} | ||
|
||
// Wait allows caller to wait for install to be finished | ||
func (i *Installer) Wait() { | ||
i.wg.Wait() | ||
} | ||
|
||
// Install performs installation of program in a specific version. | ||
func (i *Installer) Install(ctx context.Context, spec program.Spec, version, installDir string) error { | ||
i.wg.Add(1) | ||
defer i.wg.Done() | ||
|
||
return i.installer.Install(ctx, spec, version, installDir) | ||
} | ||
|
||
// Check performs installation checks | ||
func (i *Installer) Check(ctx context.Context, spec program.Spec, version, installDir string) error { | ||
i.wg.Add(1) | ||
defer i.wg.Done() | ||
|
||
return i.checker.Check(ctx, spec, version, installDir) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,7 +37,7 @@ func NewInstaller(config *artifact.Config) (*Installer, error) { | |
|
||
// Install performs installation of program in a specific version. | ||
// It expects package to be already downloaded. | ||
func (i *Installer) Install(_ context.Context, spec program.Spec, version, installDir string) error { | ||
func (i *Installer) Install(ctx context.Context, spec program.Spec, version, installDir string) error { | ||
artifactPath, err := artifact.GetArtifactPath(spec, version, i.config.OS(), i.config.Arch(), i.config.TargetDirectory) | ||
if err != nil { | ||
return err | ||
|
@@ -49,7 +49,7 @@ func (i *Installer) Install(_ context.Context, spec program.Spec, version, insta | |
os.RemoveAll(installDir) | ||
} | ||
|
||
if err := i.unzip(artifactPath); err != nil { | ||
if err := i.unzip(ctx, artifactPath); err != nil { | ||
return err | ||
} | ||
|
||
|
@@ -69,7 +69,7 @@ func (i *Installer) Install(_ context.Context, spec program.Spec, version, insta | |
return nil | ||
} | ||
|
||
func (i *Installer) unzip(artifactPath string) error { | ||
func (i *Installer) unzip(ctx context.Context, artifactPath string) error { | ||
r, err := zip.OpenReader(artifactPath) | ||
if err != nil { | ||
return err | ||
|
@@ -120,6 +120,11 @@ func (i *Installer) unzip(artifactPath string) error { | |
} | ||
|
||
for _, f := range r.File { | ||
// if we were cancelled in between | ||
if err := ctx.Err(); err != nil { | ||
return err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Won't this still leave it broken? If the context is cancelled, then this will stop extracting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this will propagate error and prevent install to continue There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will prevent all of the files in the zip file from being extracted. So that mean that if a SIGTERM occurs it will cancel the context. When the context is cancelled and its in this loop then only part of the zip file will be extracted. What happens when this returns a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes that's the case, atomic installer removes the extracted files because error was returned |
||
} | ||
|
||
if err := unpackFile(f); err != nil { | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of the context cancelling won't this still leave it in a bad state? Because if the context is cancelled then the waitgroup would still be marked with
Done()
and theWait()
would not actually wait for this to finish.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when the context is cancelled we should finish install and return error here, then wg should be mark with done.
if context is not cancelled this should work as usuual.
please elaborate a bit more, i'm not seeing what you see atm