add public API to detect node providers

This commit is contained in:
Benjamin Elder
2021-02-12 16:17:00 -08:00
parent 1ebe6b0214
commit f960e32c64
2 changed files with 51 additions and 8 deletions

View File

@@ -22,6 +22,7 @@ import (
"sigs.k8s.io/kind/pkg/cluster/constants"
"sigs.k8s.io/kind/pkg/cluster/nodes"
"sigs.k8s.io/kind/pkg/cluster/nodeutils"
"sigs.k8s.io/kind/pkg/errors"
"sigs.k8s.io/kind/pkg/log"
internalcreate "sigs.k8s.io/kind/pkg/cluster/internal/create"
@@ -68,20 +69,54 @@ func NewProvider(options ...ProviderOption) *Provider {
}
}
// ensure a provider if none was set
// NOTE: depends on logger being set (see sorting above)
if p.provider == nil {
// auto-detect based on each package IsAvailable() function
// default to docker for backwards compatibility
if docker.IsAvailable() {
p.provider = docker.NewProvider(p.logger)
} else if podman.IsAvailable() {
p.provider = podman.NewProvider(p.logger)
} else {
p.provider = docker.NewProvider(p.logger)
// DetectNodeProvider does not fallback to allow callers to determine
// this behavior
// However for compatibility if the caller of NewProvider supplied no
// option and we autodetect internally, we default to the docker provider
// for fallback, to avoid a breaking change for now.
// This may change in the future.
// TODO: consider breaking this API for earlier errors.
providerOpt, _ := DetectNodeProvider()
if providerOpt == nil {
providerOpt = ProviderWithDocker()
}
providerOpt.apply(p)
}
return p
}
// NoNodeProviderDetectedError indicates that we could not autolocate an available
// NodeProvider backend on the host
var NoNodeProviderDetectedError = errors.NewWithoutStack("failed to detect any supported node provider")
// DetectNodeProvider allows callers to autodetect the node provider
// *without* fallback to the default.
//
// Pass the returned ProviderOption to NewProvider to pass the auto-detect Docker
// or Podman option explicitly (in the future there will be more options)
//
// NOTE: The kind *cli* also checks `KIND_EXPERIMENTAL_PROVIDER` for "podman" or
// "docker" currently and does not auto-detect / respects this if set.
//
// This will be replaced with some other mechanism in the future (likely when
// podman support is GA), in the meantime though your tool may wish to match this.
//
// In the future when this is not considered experimental,
// that logic will be in a public API as well.
func DetectNodeProvider() (ProviderOption, error) {
// auto-detect based on each node provider's IsAvailable() function
if docker.IsAvailable() {
return ProviderWithDocker(), nil
}
if podman.IsAvailable() {
return ProviderWithPodman(), nil
}
return nil, errors.WithStack(NoNodeProviderDetectedError)
}
// ProviderOption is an option for configuring a provider
type ProviderOption interface {
apply(p *Provider)

View File

@@ -17,6 +17,8 @@ limitations under the License.
package errors
import (
stderrors "errors"
pkgerrors "github.com/pkg/errors"
)
@@ -26,6 +28,12 @@ func New(message string) error {
return pkgerrors.New(message)
}
// NewWithoutStack is like new but does NOT wrap with a stack
// This is useful for exported errors
func NewWithoutStack(message string) error {
return stderrors.New(message)
}
// Errorf formats according to a format specifier and returns the string as a
// value that satisfies error. Errorf also records the stack trace at the
// point it was called.