This repository has been archived by the owner on Dec 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 228
preflight before start operation #360
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
e3c8113
pkg/util/norm_string: add helper to convert strings within array to l…
najeal 25a5b9a
pkg/preflight: add preflight check mechanism for start operation
najeal f020e6a
cmd/ignite/run/start: launch preflight before launching the start ope…
najeal dcef0b2
go.mod: add testify dependency for the tests
najeal c787090
make autogen tidy
najeal af5d06b
pkg/runtime: add preflight checker
najeal 27d59bb
pkg/constants: add ignite bin dependencies as constants
najeal 383e1de
pkg/preflight: add check for bin dependencies and socket
najeal 33df71e
cmd/ignite/run: update imports with new path for preflight checkers
najeal 0256496
pkg/preflight/checkers: use Checker interface from preflight package …
najeal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package constants | ||
|
||
var Dependencies = [...]string{ | ||
"mount", | ||
"unmount", | ||
"tar", | ||
"mkfs.ext4", | ||
"e2fsck", | ||
"resize2fs", | ||
"strings", | ||
"docker", | ||
"dmsetup", | ||
"ssh", | ||
"git", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package checkers | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"net" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
|
||
api "github.com/weaveworks/ignite/pkg/apis/ignite" | ||
"github.com/weaveworks/ignite/pkg/constants" | ||
"github.com/weaveworks/ignite/pkg/preflight" | ||
"github.com/weaveworks/ignite/pkg/providers" | ||
"k8s.io/apimachinery/pkg/util/sets" | ||
) | ||
|
||
const ( | ||
oldPathString = "/" | ||
newPathString = "-" | ||
noReplaceLimit = -1 | ||
) | ||
|
||
type PortOpenChecker struct { | ||
port uint64 | ||
} | ||
|
||
func (poc PortOpenChecker) Check() error { | ||
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", poc.port)) | ||
if err != nil { | ||
return fmt.Errorf("Port %d is in use", poc.port) | ||
} | ||
if err := listener.Close(); err != nil { | ||
return fmt.Errorf("Port %d is in used, failed to close it", poc.port) | ||
} | ||
return nil | ||
} | ||
|
||
func (poc PortOpenChecker) Name() string { | ||
return fmt.Sprintf("Port-%d", poc.port) | ||
} | ||
|
||
func (poc PortOpenChecker) Type() string { | ||
return "Port" | ||
} | ||
|
||
type ExistingFileChecker struct { | ||
filePath string | ||
} | ||
|
||
func NewExistingFileChecker(filePath string) ExistingFileChecker { | ||
return ExistingFileChecker{ | ||
filePath: filePath, | ||
} | ||
} | ||
|
||
func (efc ExistingFileChecker) Check() error { | ||
if _, err := os.Stat(efc.filePath); os.IsNotExist(err) { | ||
return fmt.Errorf("File %s, does not exist", efc.filePath) | ||
} | ||
return nil | ||
} | ||
|
||
func (efc ExistingFileChecker) Name() string { | ||
return fmt.Sprintf("ExistingFile-%s", strings.Replace(efc.filePath, oldPathString, newPathString, noReplaceLimit)) | ||
} | ||
|
||
func (efc ExistingFileChecker) Type() string { | ||
return "ExistingFile" | ||
} | ||
|
||
type BinInPathChecker struct { | ||
bin string | ||
} | ||
|
||
func (bipc BinInPathChecker) Check() error { | ||
_, err := exec.LookPath(bipc.bin) | ||
if err != nil { | ||
return fmt.Errorf("Bin %s is not in your PATH", bipc.bin) | ||
} | ||
return nil | ||
} | ||
|
||
func (bipc BinInPathChecker) Name() string { | ||
return "" | ||
} | ||
|
||
func (bipc BinInPathChecker) Type() string { | ||
return "" | ||
} | ||
|
||
type AvailablePathChecker struct { | ||
path string | ||
} | ||
|
||
func StartCmdChecks(vm *api.VM, ignoredPreflightErrors sets.String) error { | ||
// the number "4" is chosen for the static preflight checkers see below | ||
nCheckers := 4 + len(vm.Spec.Network.Ports) + len(constants.Dependencies) | ||
checks := make([]preflight.Checker, 0, nCheckers) | ||
checks = append(checks, ExistingFileChecker{filePath: "/dev/mapper/control"}) | ||
checks = append(checks, ExistingFileChecker{filePath: "/dev/net/tun"}) | ||
checks = append(checks, ExistingFileChecker{filePath: "/dev/kvm"}) | ||
checks = append(checks, providers.Runtime.PreflightChecker()) | ||
for _, port := range vm.Spec.Network.Ports { | ||
checks = append(checks, PortOpenChecker{port: port.HostPort}) | ||
} | ||
for _, dependency := range constants.Dependencies { | ||
checks = append(checks, BinInPathChecker{bin: dependency}) | ||
} | ||
return runChecks(checks, ignoredPreflightErrors) | ||
} | ||
|
||
func runChecks(checks []preflight.Checker, ignoredPreflightErrors sets.String) error { | ||
var errBuffer bytes.Buffer | ||
|
||
for _, check := range checks { | ||
name := check.Name() | ||
checkType := check.Type() | ||
|
||
err := check.Check() | ||
if isIgnoredPreflightError(ignoredPreflightErrors, checkType) { | ||
err = nil | ||
} | ||
|
||
if err != nil { | ||
errBuffer.WriteString(fmt.Sprintf("[ERROR %s]: %v\n", name, err)) | ||
} | ||
} | ||
if errBuffer.Len() > 0 { | ||
return fmt.Errorf(errBuffer.String()) | ||
} | ||
return nil | ||
} | ||
|
||
func isIgnoredPreflightError(ignoredPreflightError sets.String, checkType string) bool { | ||
return ignoredPreflightError.Has("all") || ignoredPreflightError.Has(strings.ToLower(checkType)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package checkers | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"k8s.io/apimachinery/pkg/util/sets" | ||
) | ||
|
||
type fakeChecker struct { | ||
info string | ||
} | ||
|
||
func (fc fakeChecker) Check() error { | ||
if fc.info == "error" { | ||
return fmt.Errorf("error") | ||
} | ||
return nil | ||
} | ||
|
||
func (fc fakeChecker) Name() string { | ||
return "FakeChecker" | ||
} | ||
|
||
func TestRunChecks(t *testing.T) { | ||
utests := []struct { | ||
checkers []Checker | ||
ignoredErrors []string | ||
expectedError bool | ||
}{ | ||
{ | ||
checkers: []Checker{fakeChecker{info: ""}}, | ||
ignoredErrors: []string{}, | ||
expectedError: false, | ||
}, | ||
{ | ||
checkers: []Checker{fakeChecker{info: ""}, fakeChecker{info: "error"}}, | ||
ignoredErrors: []string{}, | ||
expectedError: true, | ||
}, | ||
{ | ||
checkers: []Checker{fakeChecker{info: ""}, fakeChecker{info: "error"}}, | ||
ignoredErrors: []string{"fakechecker"}, | ||
expectedError: false, | ||
}, | ||
} | ||
for _, utest := range utests { | ||
ignoredErrors := sets.NewString(utest.ignoredErrors...) | ||
err := runChecks(utest.checkers, ignoredErrors) | ||
assert.Equal(t, utest.expectedError, (err != nil)) | ||
} | ||
} | ||
|
||
func TestIsIgnoredPreflightError(t *testing.T) { | ||
const ( | ||
all = "all" | ||
ignoredError = "my-ignored-error" | ||
notIgnoredError = "not-ignored-error" | ||
) | ||
utests := []struct { | ||
name string | ||
ignoredErrors []string | ||
searchedError string | ||
expectedResponse bool | ||
}{ | ||
{ | ||
name: "IgnoreAll", | ||
ignoredErrors: []string{all}, | ||
searchedError: notIgnoredError, | ||
expectedResponse: true, | ||
}, | ||
{ | ||
name: "IgnoreSpecificError1", | ||
ignoredErrors: []string{ignoredError}, | ||
searchedError: ignoredError, | ||
expectedResponse: true, | ||
}, | ||
{ | ||
name: "IgnoreSpecificError2", | ||
ignoredErrors: []string{ignoredError}, | ||
searchedError: notIgnoredError, | ||
expectedResponse: false, | ||
}, | ||
{ | ||
name: "IgnoreAllAndSpecificError1", | ||
ignoredErrors: []string{all, ignoredError}, | ||
searchedError: ignoredError, | ||
expectedResponse: true, | ||
}, | ||
{ | ||
name: "IgnoreAllAndSpecificError2", | ||
ignoredErrors: []string{all, ignoredError}, | ||
searchedError: notIgnoredError, | ||
expectedResponse: true, | ||
}, | ||
{ | ||
name: "NoIgnore", | ||
ignoredErrors: []string{}, | ||
searchedError: notIgnoredError, | ||
expectedResponse: false, | ||
}, | ||
} | ||
|
||
for _, utest := range utests { | ||
t.Run(utest.name, func(t *testing.T) { | ||
ignoredErrors := sets.NewString(utest.ignoredErrors...) | ||
isIgnored := isIgnoredPreflightError(ignoredErrors, utest.searchedError) | ||
assert.Equal(t, utest.expectedResponse, isIgnored) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package preflight | ||
|
||
type Checker interface { | ||
Check() error | ||
Name() string | ||
Type() string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package util | ||
|
||
import ( | ||
"strings" | ||
) | ||
|
||
func ToLower(a []string) []string { | ||
b := make([]string, 0, len(a)) | ||
for _, c := range a { | ||
b = append(b, strings.ToLower(c)) | ||
} | ||
return b | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This could be an inline constructor instead of 4 allocations
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.
@najeal could you please address this per @twelho comment.