Document all exported functions outside minikube
parent
46640cef68
commit
edf46f003f
|
@ -43,6 +43,7 @@ func GetPort() (string, error) {
|
|||
return strconv.Itoa(l.Addr().(*net.TCPAddr).Port), nil
|
||||
}
|
||||
|
||||
// KillMountProcess kills the mount process, if it is running
|
||||
func KillMountProcess() error {
|
||||
out, err := ioutil.ReadFile(filepath.Join(constants.GetMinipath(), constants.MountProcessFileName))
|
||||
if err != nil {
|
||||
|
@ -59,6 +60,7 @@ func KillMountProcess() error {
|
|||
return mountProc.Kill()
|
||||
}
|
||||
|
||||
// GetKubeConfigPath gets the path to the first kubeconfig
|
||||
func GetKubeConfigPath() string {
|
||||
kubeConfigEnv := os.Getenv(constants.KubeconfigEnvVar)
|
||||
if kubeConfigEnv == "" {
|
||||
|
|
|
@ -30,10 +30,12 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// GetDiskPath returns the path of the machine disk image
|
||||
func GetDiskPath(d *drivers.BaseDriver) string {
|
||||
return filepath.Join(d.ResolveStorePath("."), d.GetMachineName()+".rawdisk")
|
||||
}
|
||||
|
||||
// CommonDriver is the common driver base class
|
||||
type CommonDriver struct{}
|
||||
|
||||
// GetCreateFlags is not implemented yet
|
||||
|
@ -87,6 +89,7 @@ func Restart(d drivers.Driver) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MakeDiskImage makes a boot2docker VM disk image.
|
||||
func MakeDiskImage(d *drivers.BaseDriver, boot2dockerURL string, diskSize int) error {
|
||||
//TODO(r2d4): rewrite this, not using b2dutils
|
||||
b2dutils := mcnutils.NewB2dUtils(d.StorePath)
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/hooklift/iso9660"
|
||||
)
|
||||
|
||||
// ExtractFile extracts a file from an ISO
|
||||
func ExtractFile(isoPath, srcPath, destPath string) error {
|
||||
iso, err := os.Open(isoPath)
|
||||
defer iso.Close()
|
||||
|
@ -53,7 +54,7 @@ func ExtractFile(isoPath, srcPath, destPath string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func ReadFile(isoPath, srcPath string) (string, error) {
|
||||
func readFile(isoPath, srcPath string) (string, error) {
|
||||
iso, err := os.Open(isoPath)
|
||||
defer iso.Close()
|
||||
if err != nil {
|
||||
|
|
|
@ -30,11 +30,15 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
LeasesPath = "/var/db/dhcpd_leases"
|
||||
VMNetDomain = "/Library/Preferences/SystemConfiguration/com.apple.vmnet"
|
||||
// LeasesPath is the path to dhcpd leases
|
||||
LeasesPath = "/var/db/dhcpd_leases"
|
||||
// VMNetDomain is the domain for vmnet
|
||||
VMNetDomain = "/Library/Preferences/SystemConfiguration/com.apple.vmnet"
|
||||
// SharedNetAddrKey is the key for the network address
|
||||
SharedNetAddrKey = "Shared_Net_Address"
|
||||
)
|
||||
|
||||
// DHCPEntry holds a parsed DNS entry
|
||||
type DHCPEntry struct {
|
||||
Name string
|
||||
IPAddress string
|
||||
|
@ -43,6 +47,7 @@ type DHCPEntry struct {
|
|||
Lease string
|
||||
}
|
||||
|
||||
// GetIPAddressByMACAddress gets the IP address of a MAC address
|
||||
func GetIPAddressByMACAddress(mac string) (string, error) {
|
||||
return getIPAddressFromFile(mac, LeasesPath)
|
||||
}
|
||||
|
@ -119,6 +124,7 @@ func trimMacAddress(rawUUID string) string {
|
|||
return mac
|
||||
}
|
||||
|
||||
// GetNetAddr gets the network address for vmnet
|
||||
func GetNetAddr() (net.IP, error) {
|
||||
plistPath := VMNetDomain + ".plist"
|
||||
if _, err := os.Stat(plistPath); err != nil {
|
||||
|
|
|
@ -50,6 +50,7 @@ const devicesTmpl = `
|
|||
{{end}}
|
||||
`
|
||||
|
||||
// PCIDevice holds a parsed PCI device
|
||||
type PCIDevice struct {
|
||||
Domain string
|
||||
Bus string
|
||||
|
|
|
@ -34,6 +34,7 @@ import (
|
|||
pkgdrivers "k8s.io/minikube/pkg/drivers"
|
||||
)
|
||||
|
||||
// Driver is the machine driver for KVM
|
||||
type Driver struct {
|
||||
*drivers.BaseDriver
|
||||
*pkgdrivers.CommonDriver
|
||||
|
@ -83,6 +84,7 @@ const (
|
|||
defaultNetworkName = "default"
|
||||
)
|
||||
|
||||
// NewDriver creates a new driver for a host
|
||||
func NewDriver(hostName, storePath string) *Driver {
|
||||
return &Driver{
|
||||
BaseDriver: &drivers.BaseDriver{
|
||||
|
@ -102,6 +104,7 @@ func NewDriver(hostName, storePath string) *Driver {
|
|||
}
|
||||
}
|
||||
|
||||
// PreCommandCheck checks the connection before issuing a command
|
||||
func (d *Driver) PreCommandCheck() error {
|
||||
conn, err := getConnection()
|
||||
if err != nil {
|
||||
|
@ -116,6 +119,7 @@ func (d *Driver) PreCommandCheck() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetURL returns a Docker compatible host URL for connecting to this host
|
||||
func (d *Driver) GetURL() (string, error) {
|
||||
if err := d.PreCommandCheck(); err != nil {
|
||||
return "", errors.Wrap(err, "getting URL, precheck failed")
|
||||
|
@ -132,6 +136,7 @@ func (d *Driver) GetURL() (string, error) {
|
|||
return fmt.Sprintf("tcp://%s:2376", ip), nil
|
||||
}
|
||||
|
||||
// GetState returns the state that the host is in (running, stopped, etc)
|
||||
func (d *Driver) GetState() (state.State, error) {
|
||||
dom, conn, err := d.getDomain()
|
||||
if err != nil {
|
||||
|
@ -176,6 +181,7 @@ func (d *Driver) GetState() (state.State, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// GetIP returns an IP or hostname that this host is available at
|
||||
func (d *Driver) GetIP() (string, error) {
|
||||
s, err := d.GetState()
|
||||
if err != nil {
|
||||
|
@ -192,14 +198,17 @@ func (d *Driver) GetIP() (string, error) {
|
|||
return ip, nil
|
||||
}
|
||||
|
||||
// GetSSHHostname returns hostname for use with ssh
|
||||
func (d *Driver) GetSSHHostname() (string, error) {
|
||||
return d.GetIP()
|
||||
}
|
||||
|
||||
// DriverName returns the name of the driver
|
||||
func (d *Driver) DriverName() string {
|
||||
return "kvm2"
|
||||
}
|
||||
|
||||
// Kill stops a host forcefully, including any containers that we are managing.
|
||||
func (d *Driver) Kill() error {
|
||||
dom, conn, err := d.getDomain()
|
||||
if err != nil {
|
||||
|
@ -210,10 +219,12 @@ func (d *Driver) Kill() error {
|
|||
return dom.Destroy()
|
||||
}
|
||||
|
||||
// Restart a host
|
||||
func (d *Driver) Restart() error {
|
||||
return pkgdrivers.Restart(d)
|
||||
}
|
||||
|
||||
// Start a host
|
||||
func (d *Driver) Start() error {
|
||||
// if somebody/something deleted the network in the meantime,
|
||||
// we might need to recreate it. It's (nearly) a noop if the network exists.
|
||||
|
@ -274,6 +285,7 @@ func (d *Driver) Start() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Create a host using the driver's config
|
||||
func (d *Driver) Create() error {
|
||||
log.Info("Creating machine...")
|
||||
log.Info("Creating network...")
|
||||
|
@ -323,6 +335,7 @@ func (d *Driver) Create() error {
|
|||
return d.Start()
|
||||
}
|
||||
|
||||
// Stop a host gracefully
|
||||
func (d *Driver) Stop() error {
|
||||
d.IPAddress = ""
|
||||
s, err := d.GetState()
|
||||
|
@ -359,6 +372,7 @@ func (d *Driver) Stop() error {
|
|||
return fmt.Errorf("Could not stop VM, current state %s", s.String())
|
||||
}
|
||||
|
||||
// Remove a host
|
||||
func (d *Driver) Remove() error {
|
||||
log.Debug("Removing machine...")
|
||||
conn, err := getConnection()
|
||||
|
|
|
@ -79,6 +79,7 @@ func (d *Driver) PreCreateCheck() error {
|
|||
return d.runtime.Available()
|
||||
}
|
||||
|
||||
// Create a host using the driver's config
|
||||
func (d *Driver) Create() error {
|
||||
// creation for the none driver is handled by commands.go
|
||||
return nil
|
||||
|
|
|
@ -29,12 +29,14 @@ import (
|
|||
"k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
// Addon is a named list of assets, that can be enabled
|
||||
type Addon struct {
|
||||
Assets []*BinDataAsset
|
||||
enabled bool
|
||||
addonName string
|
||||
}
|
||||
|
||||
// NewAddon creates a new Addon
|
||||
func NewAddon(assets []*BinDataAsset, enabled bool, addonName string) *Addon {
|
||||
a := &Addon{
|
||||
Assets: assets,
|
||||
|
@ -44,6 +46,7 @@ func NewAddon(assets []*BinDataAsset, enabled bool, addonName string) *Addon {
|
|||
return a
|
||||
}
|
||||
|
||||
// IsEnabled checks if an Addon is enabled
|
||||
func (a *Addon) IsEnabled() (bool, error) {
|
||||
addonStatusText, err := config.Get(a.addonName)
|
||||
if err == nil {
|
||||
|
@ -56,6 +59,7 @@ func (a *Addon) IsEnabled() (bool, error) {
|
|||
return a.enabled, nil
|
||||
}
|
||||
|
||||
// Addons is the list of addons
|
||||
var Addons = map[string]*Addon{
|
||||
"addon-manager": NewAddon([]*BinDataAsset{
|
||||
NewBinDataAsset(
|
||||
|
@ -281,6 +285,8 @@ var Addons = map[string]*Addon{
|
|||
}, false, "gvisor"),
|
||||
}
|
||||
|
||||
// AddMinikubeDirAssets adds all addons and files to the list
|
||||
// of files to be copied to the vm.
|
||||
func AddMinikubeDirAssets(assets *[]CopyableFile) error {
|
||||
if err := addMinikubeDirToAssets(constants.MakeMiniPath("addons"), constants.AddonsPath, assets); err != nil {
|
||||
return errors.Wrap(err, "adding addons folder to assets")
|
||||
|
|
|
@ -42,6 +42,7 @@ import (
|
|||
"k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
// BuildrootProvisioner provisions the custom system based on Buildroot
|
||||
type BuildrootProvisioner struct {
|
||||
provision.SystemdProvisioner
|
||||
}
|
||||
|
@ -52,6 +53,7 @@ func init() {
|
|||
})
|
||||
}
|
||||
|
||||
// NewBuildrootProvisioner creates a new BuildrootProvisioner
|
||||
func NewBuildrootProvisioner(d drivers.Driver) provision.Provisioner {
|
||||
return &BuildrootProvisioner{
|
||||
provision.NewSystemdProvisioner("buildroot", d),
|
||||
|
@ -62,6 +64,7 @@ func (p *BuildrootProvisioner) String() string {
|
|||
return "buildroot"
|
||||
}
|
||||
|
||||
// GenerateDockerOptions generates the *provision.DockerOptions for this provisioner
|
||||
func (p *BuildrootProvisioner) GenerateDockerOptions(dockerPort int) (*provision.DockerOptions, error) {
|
||||
var engineCfg bytes.Buffer
|
||||
|
||||
|
@ -134,10 +137,12 @@ WantedBy=multi-user.target
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Package installs a package
|
||||
func (p *BuildrootProvisioner) Package(name string, action pkgaction.PackageAction) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Provision does the provisioning
|
||||
func (p *BuildrootProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error {
|
||||
p.SwarmOptions = swarmOptions
|
||||
p.AuthOptions = authOptions
|
||||
|
|
|
@ -44,6 +44,7 @@ type hostPathProvisioner struct {
|
|||
identity types.UID
|
||||
}
|
||||
|
||||
// NewHostPathProvisioner creates a new Provisioner using host paths
|
||||
func NewHostPathProvisioner() controller.Provisioner {
|
||||
return &hostPathProvisioner{
|
||||
pvDir: "/tmp/hostpath-provisioner",
|
||||
|
|
|
@ -32,6 +32,7 @@ const (
|
|||
DefaultServiceCIDR = "10.96.0.0/12"
|
||||
)
|
||||
|
||||
// DefaultAdmissionControllers is the list of default admission controllers/plugins
|
||||
var DefaultAdmissionControllers = []string{
|
||||
"Initializers",
|
||||
"NamespaceLifecycle",
|
||||
|
@ -67,6 +68,7 @@ func GetDNSIP(serviceCIDR string) (net.IP, error) {
|
|||
return ip, nil
|
||||
}
|
||||
|
||||
// GetAlternateDNS returns a list of alternate names for a domain
|
||||
func GetAlternateDNS(domain string) []string {
|
||||
return []string{"kubernetes.default.svc." + domain, "kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// GenerateCACert generates a CA certificate and RSA key for a common name
|
||||
func GenerateCACert(certPath, keyPath string, name string) error {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
|
@ -61,6 +62,7 @@ func GenerateCACert(certPath, keyPath string, name string) error {
|
|||
// If the certificate or key files already exist, they will be overwritten.
|
||||
// Any parent directories of the certPath or keyPath will be created as needed with file mode 0755.
|
||||
|
||||
// GenerateSignedCert generates a signed certificate and key
|
||||
func GenerateSignedCert(certPath, keyPath, cn string, ips []net.IP, alternateDNS []string, signerCertPath, signerKeyPath string) error {
|
||||
signerCertBytes, err := ioutil.ReadFile(signerCertPath)
|
||||
if err != nil {
|
||||
|
|
|
@ -31,13 +31,16 @@ import (
|
|||
|
||||
const fileScheme = "file"
|
||||
|
||||
// ISODownloader downloads an ISO
|
||||
type ISODownloader interface {
|
||||
GetISOFileURI(isoURL string) string
|
||||
CacheMinikubeISOFromURL(isoURL string) error
|
||||
}
|
||||
|
||||
// DefaultDownloader is the default ISODownloader
|
||||
type DefaultDownloader struct{}
|
||||
|
||||
// GetISOFileURI gets the local destination for a remote source
|
||||
func (f DefaultDownloader) GetISOFileURI(isoURL string) string {
|
||||
urlObj, err := url.Parse(isoURL)
|
||||
if err != nil {
|
||||
|
@ -51,6 +54,7 @@ func (f DefaultDownloader) GetISOFileURI(isoURL string) string {
|
|||
return "file://" + filepath.ToSlash(isoPath)
|
||||
}
|
||||
|
||||
// CacheMinikubeISOFromURL downloads the ISO, if it doesn't exist in cache
|
||||
func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
|
||||
if !f.ShouldCacheMinikubeISO(isoURL) {
|
||||
glog.Infof("Not caching ISO, using %s", isoURL)
|
||||
|
@ -80,6 +84,7 @@ func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ShouldCacheMinikubeISO returns if we need to download the ISO
|
||||
func (f DefaultDownloader) ShouldCacheMinikubeISO(isoURL string) bool {
|
||||
// store the minikube-iso inside the .minikube dir
|
||||
|
||||
|
@ -96,10 +101,12 @@ func (f DefaultDownloader) ShouldCacheMinikubeISO(isoURL string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// GetISOCacheFilepath returns the path of an ISO in the local cache
|
||||
func (f DefaultDownloader) GetISOCacheFilepath(isoURL string) string {
|
||||
return filepath.Join(constants.GetMinipath(), "cache", "iso", filepath.Base(isoURL))
|
||||
}
|
||||
|
||||
// IsMinikubeISOCached returns if an ISO exists in the local cache
|
||||
func (f DefaultDownloader) IsMinikubeISOCached(isoURL string) bool {
|
||||
if _, err := os.Stat(f.GetISOCacheFilepath(isoURL)); os.IsNotExist(err) {
|
||||
return false
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// ExtraOption is an extra option
|
||||
type ExtraOption struct {
|
||||
Component string
|
||||
Key string
|
||||
|
@ -31,8 +32,10 @@ func (e *ExtraOption) String() string {
|
|||
return fmt.Sprintf("%s.%s=%s", e.Component, e.Key, e.Value)
|
||||
}
|
||||
|
||||
// ExtraOptionSlice is a slice of ExtraOption
|
||||
type ExtraOptionSlice []ExtraOption
|
||||
|
||||
// Set parses the string value into a slice
|
||||
func (es *ExtraOptionSlice) Set(value string) error {
|
||||
// The component is the value before the first dot.
|
||||
componentSplit := strings.SplitN(value, ".", 2)
|
||||
|
@ -56,6 +59,7 @@ func (es *ExtraOptionSlice) Set(value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// String converts the slice to a string value
|
||||
func (es *ExtraOptionSlice) String() string {
|
||||
s := []string{}
|
||||
for _, e := range *es {
|
||||
|
@ -64,6 +68,7 @@ func (es *ExtraOptionSlice) String() string {
|
|||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
// Type returns the type
|
||||
func (es *ExtraOptionSlice) Type() string {
|
||||
return "ExtraOption"
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import (
|
|||
"k8s.io/minikube/pkg/util"
|
||||
)
|
||||
|
||||
// KubeConfigSetup is the kubeconfig setup
|
||||
type KubeConfigSetup struct {
|
||||
// The name of the cluster for this context
|
||||
ClusterName string
|
||||
|
@ -61,10 +62,12 @@ type KubeConfigSetup struct {
|
|||
kubeConfigFile atomic.Value
|
||||
}
|
||||
|
||||
// SetKubeConfigFile sets the kubeconfig file
|
||||
func (k *KubeConfigSetup) SetKubeConfigFile(kubeConfigFile string) {
|
||||
k.kubeConfigFile.Store(kubeConfigFile)
|
||||
}
|
||||
|
||||
// GetKubeConfigFile gets the kubeconfig file
|
||||
func (k *KubeConfigSetup) GetKubeConfigFile() string {
|
||||
return k.kubeConfigFile.Load().(string)
|
||||
}
|
||||
|
|
|
@ -45,12 +45,14 @@ var (
|
|||
ReasonableStartTime = time.Minute * 10
|
||||
)
|
||||
|
||||
// PodStore stores pods
|
||||
type PodStore struct {
|
||||
cache.Store
|
||||
stopCh chan struct{}
|
||||
Reflector *cache.Reflector
|
||||
}
|
||||
|
||||
// List lists the pods
|
||||
func (s *PodStore) List() []*v1.Pod {
|
||||
objects := s.Store.List()
|
||||
pods := make([]*v1.Pod, 0)
|
||||
|
@ -60,10 +62,12 @@ func (s *PodStore) List() []*v1.Pod {
|
|||
return pods
|
||||
}
|
||||
|
||||
// Stop stops the pods
|
||||
func (s *PodStore) Stop() {
|
||||
close(s.stopCh)
|
||||
}
|
||||
|
||||
// GetClient gets the client from config
|
||||
func GetClient() (kubernetes.Interface, error) {
|
||||
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
||||
configOverrides := &clientcmd.ConfigOverrides{}
|
||||
|
@ -79,6 +83,7 @@ func GetClient() (kubernetes.Interface, error) {
|
|||
return client, nil
|
||||
}
|
||||
|
||||
// NewPodStore creates a new PodStore
|
||||
func NewPodStore(c kubernetes.Interface, namespace string, label labels.Selector, field fields.Selector) *PodStore {
|
||||
lw := &cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
|
@ -100,6 +105,7 @@ func NewPodStore(c kubernetes.Interface, namespace string, label labels.Selector
|
|||
return &PodStore{Store: store, stopCh: stopCh, Reflector: reflector}
|
||||
}
|
||||
|
||||
// StartPods starts all pods
|
||||
func StartPods(c kubernetes.Interface, namespace string, pod v1.Pod, waitForRunning bool) error {
|
||||
pod.ObjectMeta.Labels["name"] = pod.Name
|
||||
if waitForRunning {
|
||||
|
@ -285,6 +291,7 @@ func countEndpointsNum(e *v1.Endpoints) int {
|
|||
return num
|
||||
}
|
||||
|
||||
// IsRetryableAPIError returns if this error is retryable or not
|
||||
func IsRetryableAPIError(err error) bool {
|
||||
return apierrs.IsTimeout(err) || apierrs.IsServerTimeout(err) || apierrs.IsTooManyRequests(err) || apierrs.IsInternalError(err)
|
||||
}
|
||||
|
|
|
@ -35,19 +35,24 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ErrPrefix notes an error
|
||||
const ErrPrefix = "! "
|
||||
|
||||
// OutPrefix notes output
|
||||
const OutPrefix = "> "
|
||||
|
||||
const (
|
||||
downloadURL = "https://storage.googleapis.com/minikube/releases/%s/minikube-%s-amd64%s"
|
||||
)
|
||||
|
||||
// RetriableError is an error that can be tried again
|
||||
type RetriableError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (r RetriableError) Error() string { return "Temporary Error: " + r.Err.Error() }
|
||||
|
||||
// CalculateDiskSizeInMB returns the number of MB in the human readable string
|
||||
func CalculateDiskSizeInMB(humanReadableDiskSize string) int {
|
||||
diskSize, err := units.FromHumanSize(humanReadableDiskSize)
|
||||
if err != nil {
|
||||
|
@ -78,6 +83,7 @@ func Until(fn func() error, w io.Writer, name string, sleep time.Duration, done
|
|||
}
|
||||
}
|
||||
|
||||
// Pad pads the string with newlines
|
||||
func Pad(str string) string {
|
||||
return fmt.Sprintf("\n%s\n", str)
|
||||
}
|
||||
|
@ -95,10 +101,12 @@ func CanReadFile(path string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// Retry retries a number of attempts
|
||||
func Retry(attempts int, callback func() error) (err error) {
|
||||
return RetryAfter(attempts, callback, 0)
|
||||
}
|
||||
|
||||
// RetryAfter retries a number of attempts, after a delay
|
||||
func RetryAfter(attempts int, callback func() error, d time.Duration) (err error) {
|
||||
m := MultiError{}
|
||||
for i := 0; i < attempts; i++ {
|
||||
|
@ -120,6 +128,7 @@ func RetryAfter(attempts int, callback func() error, d time.Duration) (err error
|
|||
return m.ToError()
|
||||
}
|
||||
|
||||
// ParseSHAFromURL downloads and reads a SHA checksum from an URL
|
||||
func ParseSHAFromURL(url string) (string, error) {
|
||||
r, err := http.Get(url)
|
||||
if err != nil {
|
||||
|
@ -137,6 +146,7 @@ func ParseSHAFromURL(url string) (string, error) {
|
|||
return strings.Trim(string(body), "\n"), nil
|
||||
}
|
||||
|
||||
// GetBinaryDownloadURL returns a suitable URL for the platform
|
||||
func GetBinaryDownloadURL(version, platform string) string {
|
||||
switch platform {
|
||||
case "windows":
|
||||
|
@ -146,16 +156,19 @@ func GetBinaryDownloadURL(version, platform string) string {
|
|||
}
|
||||
}
|
||||
|
||||
// MultiError holds multiple errors
|
||||
type MultiError struct {
|
||||
Errors []error
|
||||
}
|
||||
|
||||
// Collect adds the error
|
||||
func (m *MultiError) Collect(err error) {
|
||||
if err != nil {
|
||||
m.Errors = append(m.Errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
// ToError converts all errors into one
|
||||
func (m MultiError) ToError() error {
|
||||
if len(m.Errors) == 0 {
|
||||
return nil
|
||||
|
@ -168,6 +181,7 @@ func (m MultiError) ToError() error {
|
|||
return errors.New(strings.Join(errStrings, "\n"))
|
||||
}
|
||||
|
||||
// IsDirectory checks if path is a directory
|
||||
func IsDirectory(path string) (bool, error) {
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
|
@ -176,6 +190,7 @@ func IsDirectory(path string) (bool, error) {
|
|||
return fileInfo.IsDir(), nil
|
||||
}
|
||||
|
||||
// ChownR does a recursive os.Chown
|
||||
func ChownR(path string, uid, gid int) error {
|
||||
return filepath.Walk(path, func(name string, info os.FileInfo, err error) error {
|
||||
if err == nil {
|
||||
|
@ -185,6 +200,7 @@ func ChownR(path string, uid, gid int) error {
|
|||
})
|
||||
}
|
||||
|
||||
// MaybeChownDirRecursiveToMinikubeUser changes ownership of a dir, if requested
|
||||
func MaybeChownDirRecursiveToMinikubeUser(dir string) error {
|
||||
if os.Getenv("CHANGE_MINIKUBE_NONE_USER") != "" && os.Getenv("SUDO_USER") != "" {
|
||||
username := os.Getenv("SUDO_USER")
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/blang/semver"
|
||||
)
|
||||
|
||||
// VersionPrefix is the prefix of the git tag for a version
|
||||
const VersionPrefix = "v"
|
||||
|
||||
// The current version of the minikube
|
||||
|
@ -34,18 +35,22 @@ var isoVersion = "v0.0.0-unset"
|
|||
|
||||
var isoPath = "minikube/iso"
|
||||
|
||||
// GetVersion returns the current minikube version
|
||||
func GetVersion() string {
|
||||
return version
|
||||
}
|
||||
|
||||
// GetISOVersion returns the current minikube.iso version
|
||||
func GetISOVersion() string {
|
||||
return isoVersion
|
||||
}
|
||||
|
||||
// GetISOPath returns the remote path to the minikube.iso
|
||||
func GetISOPath() string {
|
||||
return isoPath
|
||||
}
|
||||
|
||||
// GetSemverVersion returns the current minikube semantic version (semver)
|
||||
func GetSemverVersion() (semver.Version, error) {
|
||||
return semver.Make(strings.TrimPrefix(GetVersion(), VersionPrefix))
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"k8s.io/minikube/test/integration/util"
|
||||
)
|
||||
|
||||
// TestMain is the test main
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
os.Exit(m.Run())
|
||||
|
@ -35,6 +36,7 @@ var startArgs = flag.String("minikube-start-args", "", "Arguments to pass to min
|
|||
var mountArgs = flag.String("minikube-mount-args", "", "Arguments to pass to minikube mount")
|
||||
var testdataDir = flag.String("testdata-dir", "testdata", "the directory relative to test/integration where the testdata lives")
|
||||
|
||||
// NewMinikubeRunner creates a new MinikubeRunner
|
||||
func NewMinikubeRunner(t *testing.T) util.MinikubeRunner {
|
||||
return util.MinikubeRunner{
|
||||
Args: *args,
|
||||
|
|
|
@ -39,6 +39,7 @@ import (
|
|||
|
||||
const kubectlBinary = "kubectl"
|
||||
|
||||
// MinikubeRunner runs a command
|
||||
type MinikubeRunner struct {
|
||||
T *testing.T
|
||||
BinaryPath string
|
||||
|
@ -57,11 +58,13 @@ func Logf(str string, args ...interface{}) {
|
|||
fmt.Println(fmt.Sprintf(str, args...))
|
||||
}
|
||||
|
||||
// Run executes a command
|
||||
func (m *MinikubeRunner) Run(cmd string) error {
|
||||
_, err := m.SSH(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy copies a file
|
||||
func (m *MinikubeRunner) Copy(f assets.CopyableFile) error {
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command("/bin/bash", "-c", path, "ssh", "--", fmt.Sprintf("cat >> %s", filepath.Join(f.GetTargetDir(), f.GetTargetName())))
|
||||
|
@ -69,10 +72,12 @@ func (m *MinikubeRunner) Copy(f assets.CopyableFile) error {
|
|||
return cmd.Run()
|
||||
}
|
||||
|
||||
// CombinedOutput executes a command, returning the combined stdout and stderr
|
||||
func (m *MinikubeRunner) CombinedOutput(cmd string) (string, error) {
|
||||
return m.SSH(cmd)
|
||||
}
|
||||
|
||||
// Remove removes a file
|
||||
func (m *MinikubeRunner) Remove(f assets.CopyableFile) error {
|
||||
_, err := m.SSH(fmt.Sprintf("rm -rf %s", filepath.Join(f.GetTargetDir(), f.GetTargetName())))
|
||||
return err
|
||||
|
@ -111,6 +116,7 @@ func (m *MinikubeRunner) teeRun(cmd *exec.Cmd) (string, string, error) {
|
|||
return outB.String(), errB.String(), err
|
||||
}
|
||||
|
||||
// RunCommand executes a command, optionally checking for error
|
||||
func (m *MinikubeRunner) RunCommand(command string, checkError bool) string {
|
||||
commandArr := strings.Split(command, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
@ -136,6 +142,7 @@ func (m *MinikubeRunner) RunWithContext(ctx context.Context, command string) (st
|
|||
return m.teeRun(cmd)
|
||||
}
|
||||
|
||||
// RunDaemon executes a command, returning the stdout
|
||||
func (m *MinikubeRunner) RunDaemon(command string) (*exec.Cmd, *bufio.Reader) {
|
||||
commandArr := strings.Split(command, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
@ -164,6 +171,7 @@ func (m *MinikubeRunner) RunDaemon(command string) (*exec.Cmd, *bufio.Reader) {
|
|||
|
||||
}
|
||||
|
||||
// RunDaemon2 executes a command, returning the stdout and stderr
|
||||
func (m *MinikubeRunner) RunDaemon2(command string) (*exec.Cmd, *bufio.Reader, *bufio.Reader) {
|
||||
commandArr := strings.Split(command, " ")
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
|
@ -189,6 +197,7 @@ func (m *MinikubeRunner) SetRuntime(runtime string) {
|
|||
m.Runtime = runtime
|
||||
}
|
||||
|
||||
// SSH returns the output of running a command using SSH
|
||||
func (m *MinikubeRunner) SSH(command string) (string, error) {
|
||||
path, _ := filepath.Abs(m.BinaryPath)
|
||||
cmd := exec.Command(path, "ssh", command)
|
||||
|
@ -202,6 +211,7 @@ func (m *MinikubeRunner) SSH(command string) (string, error) {
|
|||
return string(stdout), nil
|
||||
}
|
||||
|
||||
// Start starts the container runtime
|
||||
func (m *MinikubeRunner) Start() {
|
||||
opts := ""
|
||||
// TODO(tstromberg): Deprecate this in favor of making it possible for tests to define explicit flags.
|
||||
|
@ -215,6 +225,7 @@ func (m *MinikubeRunner) Start() {
|
|||
|
||||
}
|
||||
|
||||
// EnsureRunning makes sure the container runtime is running
|
||||
func (m *MinikubeRunner) EnsureRunning() {
|
||||
if m.GetStatus() != "Running" {
|
||||
m.Start()
|
||||
|
@ -232,20 +243,24 @@ func (m *MinikubeRunner) ParseEnvCmdOutput(out string) map[string]string {
|
|||
return env
|
||||
}
|
||||
|
||||
// GetStatus returns the status of a service
|
||||
func (m *MinikubeRunner) GetStatus() string {
|
||||
return m.RunCommand(fmt.Sprintf("status --format={{.Host}} %s", m.Args), false)
|
||||
}
|
||||
|
||||
// GetLogs returns the logs of a service
|
||||
func (m *MinikubeRunner) GetLogs() string {
|
||||
return m.RunCommand(fmt.Sprintf("logs %s", m.Args), true)
|
||||
}
|
||||
|
||||
// CheckStatus makes sure the service has the desired status, or cause fatal error
|
||||
func (m *MinikubeRunner) CheckStatus(desired string) {
|
||||
if err := m.CheckStatusNoFail(desired); err != nil {
|
||||
m.T.Fatalf("%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// CheckStatusNoFail makes sure the service has the desired status, returning error
|
||||
func (m *MinikubeRunner) CheckStatusNoFail(desired string) error {
|
||||
s := m.GetStatus()
|
||||
if s != desired {
|
||||
|
@ -254,11 +269,13 @@ func (m *MinikubeRunner) CheckStatusNoFail(desired string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// KubectlRunner runs a command using kubectl
|
||||
type KubectlRunner struct {
|
||||
T *testing.T
|
||||
BinaryPath string
|
||||
}
|
||||
|
||||
// NewKubectlRunner creates a new KubectlRunner
|
||||
func NewKubectlRunner(t *testing.T) *KubectlRunner {
|
||||
p, err := exec.LookPath(kubectlBinary)
|
||||
if err != nil {
|
||||
|
@ -267,6 +284,7 @@ func NewKubectlRunner(t *testing.T) *KubectlRunner {
|
|||
return &KubectlRunner{BinaryPath: p, T: t}
|
||||
}
|
||||
|
||||
// RunCommandParseOutput runs a command and parses the JSON output
|
||||
func (k *KubectlRunner) RunCommandParseOutput(args []string, outputObj interface{}) error {
|
||||
args = append(args, "-o=json")
|
||||
output, err := k.RunCommand(args)
|
||||
|
@ -280,6 +298,7 @@ func (k *KubectlRunner) RunCommandParseOutput(args []string, outputObj interface
|
|||
return nil
|
||||
}
|
||||
|
||||
// RunCommand runs a command, returning stdout
|
||||
func (k *KubectlRunner) RunCommand(args []string) (stdout []byte, err error) {
|
||||
inner := func() error {
|
||||
cmd := exec.Command(k.BinaryPath, args...)
|
||||
|
@ -296,6 +315,7 @@ func (k *KubectlRunner) RunCommand(args []string) (stdout []byte, err error) {
|
|||
return stdout, err
|
||||
}
|
||||
|
||||
// CreateRandomNamespace creates a random namespace
|
||||
func (k *KubectlRunner) CreateRandomNamespace() string {
|
||||
const strLen = 20
|
||||
name := genRandString(strLen)
|
||||
|
@ -315,11 +335,13 @@ func genRandString(strLen int) string {
|
|||
return string(result)
|
||||
}
|
||||
|
||||
// DeleteNamespace deletes the namespace
|
||||
func (k *KubectlRunner) DeleteNamespace(namespace string) error {
|
||||
_, err := k.RunCommand([]string{"delete", "namespace", namespace})
|
||||
return err
|
||||
}
|
||||
|
||||
// WaitForBusyboxRunning waits until busybox pod to be running
|
||||
func WaitForBusyboxRunning(t *testing.T, namespace string) error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
|
@ -329,6 +351,7 @@ func WaitForBusyboxRunning(t *testing.T, namespace string) error {
|
|||
return commonutil.WaitForPodsWithLabelRunning(client, namespace, selector)
|
||||
}
|
||||
|
||||
// WaitForIngressControllerRunning waits until ingress controller pod to be running
|
||||
func WaitForIngressControllerRunning(t *testing.T) error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
|
@ -347,6 +370,7 @@ func WaitForIngressControllerRunning(t *testing.T) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// WaitForIngressDefaultBackendRunning waits until ingress default backend pod to be running
|
||||
func WaitForIngressDefaultBackendRunning(t *testing.T) error {
|
||||
client, err := commonutil.GetClient()
|
||||
if err != nil {
|
||||
|
@ -422,6 +446,7 @@ func WaitForFailedCreatePodSandBoxEvent() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// WaitForNginxRunning waits for nginx service to be up
|
||||
func WaitForNginxRunning(t *testing.T) error {
|
||||
client, err := commonutil.GetClient()
|
||||
|
||||
|
@ -440,6 +465,7 @@ func WaitForNginxRunning(t *testing.T) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Retry tries the callback for a number of attempts, with a delay between attempts
|
||||
func Retry(t *testing.T, callback func() error, d time.Duration, attempts int) (err error) {
|
||||
for i := 0; i < attempts; i++ {
|
||||
err = callback()
|
||||
|
|
Loading…
Reference in New Issue