Document all exported functions outside minikube

pull/3839/head
Anders F Björklund 2019-03-16 14:12:18 +01:00
parent 46640cef68
commit edf46f003f
20 changed files with 118 additions and 3 deletions

View File

@ -43,6 +43,7 @@ func GetPort() (string, error) {
return strconv.Itoa(l.Addr().(*net.TCPAddr).Port), nil return strconv.Itoa(l.Addr().(*net.TCPAddr).Port), nil
} }
// KillMountProcess kills the mount process, if it is running
func KillMountProcess() error { func KillMountProcess() error {
out, err := ioutil.ReadFile(filepath.Join(constants.GetMinipath(), constants.MountProcessFileName)) out, err := ioutil.ReadFile(filepath.Join(constants.GetMinipath(), constants.MountProcessFileName))
if err != nil { if err != nil {
@ -59,6 +60,7 @@ func KillMountProcess() error {
return mountProc.Kill() return mountProc.Kill()
} }
// GetKubeConfigPath gets the path to the first kubeconfig
func GetKubeConfigPath() string { func GetKubeConfigPath() string {
kubeConfigEnv := os.Getenv(constants.KubeconfigEnvVar) kubeConfigEnv := os.Getenv(constants.KubeconfigEnvVar)
if kubeConfigEnv == "" { if kubeConfigEnv == "" {

View File

@ -30,10 +30,12 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// GetDiskPath returns the path of the machine disk image
func GetDiskPath(d *drivers.BaseDriver) string { func GetDiskPath(d *drivers.BaseDriver) string {
return filepath.Join(d.ResolveStorePath("."), d.GetMachineName()+".rawdisk") return filepath.Join(d.ResolveStorePath("."), d.GetMachineName()+".rawdisk")
} }
// CommonDriver is the common driver base class
type CommonDriver struct{} type CommonDriver struct{}
// GetCreateFlags is not implemented yet // GetCreateFlags is not implemented yet
@ -87,6 +89,7 @@ func Restart(d drivers.Driver) error {
return nil return nil
} }
// MakeDiskImage makes a boot2docker VM disk image.
func MakeDiskImage(d *drivers.BaseDriver, boot2dockerURL string, diskSize int) error { func MakeDiskImage(d *drivers.BaseDriver, boot2dockerURL string, diskSize int) error {
//TODO(r2d4): rewrite this, not using b2dutils //TODO(r2d4): rewrite this, not using b2dutils
b2dutils := mcnutils.NewB2dUtils(d.StorePath) b2dutils := mcnutils.NewB2dUtils(d.StorePath)

View File

@ -26,6 +26,7 @@ import (
"github.com/hooklift/iso9660" "github.com/hooklift/iso9660"
) )
// ExtractFile extracts a file from an ISO
func ExtractFile(isoPath, srcPath, destPath string) error { func ExtractFile(isoPath, srcPath, destPath string) error {
iso, err := os.Open(isoPath) iso, err := os.Open(isoPath)
defer iso.Close() defer iso.Close()
@ -53,7 +54,7 @@ func ExtractFile(isoPath, srcPath, destPath string) error {
return err return err
} }
func ReadFile(isoPath, srcPath string) (string, error) { func readFile(isoPath, srcPath string) (string, error) {
iso, err := os.Open(isoPath) iso, err := os.Open(isoPath)
defer iso.Close() defer iso.Close()
if err != nil { if err != nil {

View File

@ -30,11 +30,15 @@ import (
) )
const ( const (
LeasesPath = "/var/db/dhcpd_leases" // LeasesPath is the path to dhcpd leases
VMNetDomain = "/Library/Preferences/SystemConfiguration/com.apple.vmnet" 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" SharedNetAddrKey = "Shared_Net_Address"
) )
// DHCPEntry holds a parsed DNS entry
type DHCPEntry struct { type DHCPEntry struct {
Name string Name string
IPAddress string IPAddress string
@ -43,6 +47,7 @@ type DHCPEntry struct {
Lease string Lease string
} }
// GetIPAddressByMACAddress gets the IP address of a MAC address
func GetIPAddressByMACAddress(mac string) (string, error) { func GetIPAddressByMACAddress(mac string) (string, error) {
return getIPAddressFromFile(mac, LeasesPath) return getIPAddressFromFile(mac, LeasesPath)
} }
@ -119,6 +124,7 @@ func trimMacAddress(rawUUID string) string {
return mac return mac
} }
// GetNetAddr gets the network address for vmnet
func GetNetAddr() (net.IP, error) { func GetNetAddr() (net.IP, error) {
plistPath := VMNetDomain + ".plist" plistPath := VMNetDomain + ".plist"
if _, err := os.Stat(plistPath); err != nil { if _, err := os.Stat(plistPath); err != nil {

View File

@ -50,6 +50,7 @@ const devicesTmpl = `
{{end}} {{end}}
` `
// PCIDevice holds a parsed PCI device
type PCIDevice struct { type PCIDevice struct {
Domain string Domain string
Bus string Bus string

View File

@ -34,6 +34,7 @@ import (
pkgdrivers "k8s.io/minikube/pkg/drivers" pkgdrivers "k8s.io/minikube/pkg/drivers"
) )
// Driver is the machine driver for KVM
type Driver struct { type Driver struct {
*drivers.BaseDriver *drivers.BaseDriver
*pkgdrivers.CommonDriver *pkgdrivers.CommonDriver
@ -83,6 +84,7 @@ const (
defaultNetworkName = "default" defaultNetworkName = "default"
) )
// NewDriver creates a new driver for a host
func NewDriver(hostName, storePath string) *Driver { func NewDriver(hostName, storePath string) *Driver {
return &Driver{ return &Driver{
BaseDriver: &drivers.BaseDriver{ 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 { func (d *Driver) PreCommandCheck() error {
conn, err := getConnection() conn, err := getConnection()
if err != nil { if err != nil {
@ -116,6 +119,7 @@ func (d *Driver) PreCommandCheck() error {
return nil return nil
} }
// GetURL returns a Docker compatible host URL for connecting to this host
func (d *Driver) GetURL() (string, error) { func (d *Driver) GetURL() (string, error) {
if err := d.PreCommandCheck(); err != nil { if err := d.PreCommandCheck(); err != nil {
return "", errors.Wrap(err, "getting URL, precheck failed") 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 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) { func (d *Driver) GetState() (state.State, error) {
dom, conn, err := d.getDomain() dom, conn, err := d.getDomain()
if err != nil { 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) { func (d *Driver) GetIP() (string, error) {
s, err := d.GetState() s, err := d.GetState()
if err != nil { if err != nil {
@ -192,14 +198,17 @@ func (d *Driver) GetIP() (string, error) {
return ip, nil return ip, nil
} }
// GetSSHHostname returns hostname for use with ssh
func (d *Driver) GetSSHHostname() (string, error) { func (d *Driver) GetSSHHostname() (string, error) {
return d.GetIP() return d.GetIP()
} }
// DriverName returns the name of the driver
func (d *Driver) DriverName() string { func (d *Driver) DriverName() string {
return "kvm2" return "kvm2"
} }
// Kill stops a host forcefully, including any containers that we are managing.
func (d *Driver) Kill() error { func (d *Driver) Kill() error {
dom, conn, err := d.getDomain() dom, conn, err := d.getDomain()
if err != nil { if err != nil {
@ -210,10 +219,12 @@ func (d *Driver) Kill() error {
return dom.Destroy() return dom.Destroy()
} }
// Restart a host
func (d *Driver) Restart() error { func (d *Driver) Restart() error {
return pkgdrivers.Restart(d) return pkgdrivers.Restart(d)
} }
// Start a host
func (d *Driver) Start() error { func (d *Driver) Start() error {
// if somebody/something deleted the network in the meantime, // if somebody/something deleted the network in the meantime,
// we might need to recreate it. It's (nearly) a noop if the network exists. // 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 return nil
} }
// Create a host using the driver's config
func (d *Driver) Create() error { func (d *Driver) Create() error {
log.Info("Creating machine...") log.Info("Creating machine...")
log.Info("Creating network...") log.Info("Creating network...")
@ -323,6 +335,7 @@ func (d *Driver) Create() error {
return d.Start() return d.Start()
} }
// Stop a host gracefully
func (d *Driver) Stop() error { func (d *Driver) Stop() error {
d.IPAddress = "" d.IPAddress = ""
s, err := d.GetState() 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()) return fmt.Errorf("Could not stop VM, current state %s", s.String())
} }
// Remove a host
func (d *Driver) Remove() error { func (d *Driver) Remove() error {
log.Debug("Removing machine...") log.Debug("Removing machine...")
conn, err := getConnection() conn, err := getConnection()

View File

@ -79,6 +79,7 @@ func (d *Driver) PreCreateCheck() error {
return d.runtime.Available() return d.runtime.Available()
} }
// Create a host using the driver's config
func (d *Driver) Create() error { func (d *Driver) Create() error {
// creation for the none driver is handled by commands.go // creation for the none driver is handled by commands.go
return nil return nil

View File

@ -29,12 +29,14 @@ import (
"k8s.io/minikube/pkg/util" "k8s.io/minikube/pkg/util"
) )
// Addon is a named list of assets, that can be enabled
type Addon struct { type Addon struct {
Assets []*BinDataAsset Assets []*BinDataAsset
enabled bool enabled bool
addonName string addonName string
} }
// NewAddon creates a new Addon
func NewAddon(assets []*BinDataAsset, enabled bool, addonName string) *Addon { func NewAddon(assets []*BinDataAsset, enabled bool, addonName string) *Addon {
a := &Addon{ a := &Addon{
Assets: assets, Assets: assets,
@ -44,6 +46,7 @@ func NewAddon(assets []*BinDataAsset, enabled bool, addonName string) *Addon {
return a return a
} }
// IsEnabled checks if an Addon is enabled
func (a *Addon) IsEnabled() (bool, error) { func (a *Addon) IsEnabled() (bool, error) {
addonStatusText, err := config.Get(a.addonName) addonStatusText, err := config.Get(a.addonName)
if err == nil { if err == nil {
@ -56,6 +59,7 @@ func (a *Addon) IsEnabled() (bool, error) {
return a.enabled, nil return a.enabled, nil
} }
// Addons is the list of addons
var Addons = map[string]*Addon{ var Addons = map[string]*Addon{
"addon-manager": NewAddon([]*BinDataAsset{ "addon-manager": NewAddon([]*BinDataAsset{
NewBinDataAsset( NewBinDataAsset(
@ -281,6 +285,8 @@ var Addons = map[string]*Addon{
}, false, "gvisor"), }, false, "gvisor"),
} }
// AddMinikubeDirAssets adds all addons and files to the list
// of files to be copied to the vm.
func AddMinikubeDirAssets(assets *[]CopyableFile) error { func AddMinikubeDirAssets(assets *[]CopyableFile) error {
if err := addMinikubeDirToAssets(constants.MakeMiniPath("addons"), constants.AddonsPath, assets); err != nil { if err := addMinikubeDirToAssets(constants.MakeMiniPath("addons"), constants.AddonsPath, assets); err != nil {
return errors.Wrap(err, "adding addons folder to assets") return errors.Wrap(err, "adding addons folder to assets")

View File

@ -42,6 +42,7 @@ import (
"k8s.io/minikube/pkg/util" "k8s.io/minikube/pkg/util"
) )
// BuildrootProvisioner provisions the custom system based on Buildroot
type BuildrootProvisioner struct { type BuildrootProvisioner struct {
provision.SystemdProvisioner provision.SystemdProvisioner
} }
@ -52,6 +53,7 @@ func init() {
}) })
} }
// NewBuildrootProvisioner creates a new BuildrootProvisioner
func NewBuildrootProvisioner(d drivers.Driver) provision.Provisioner { func NewBuildrootProvisioner(d drivers.Driver) provision.Provisioner {
return &BuildrootProvisioner{ return &BuildrootProvisioner{
provision.NewSystemdProvisioner("buildroot", d), provision.NewSystemdProvisioner("buildroot", d),
@ -62,6 +64,7 @@ func (p *BuildrootProvisioner) String() string {
return "buildroot" return "buildroot"
} }
// GenerateDockerOptions generates the *provision.DockerOptions for this provisioner
func (p *BuildrootProvisioner) GenerateDockerOptions(dockerPort int) (*provision.DockerOptions, error) { func (p *BuildrootProvisioner) GenerateDockerOptions(dockerPort int) (*provision.DockerOptions, error) {
var engineCfg bytes.Buffer var engineCfg bytes.Buffer
@ -134,10 +137,12 @@ WantedBy=multi-user.target
}, nil }, nil
} }
// Package installs a package
func (p *BuildrootProvisioner) Package(name string, action pkgaction.PackageAction) error { func (p *BuildrootProvisioner) Package(name string, action pkgaction.PackageAction) error {
return nil return nil
} }
// Provision does the provisioning
func (p *BuildrootProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error { func (p *BuildrootProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error {
p.SwarmOptions = swarmOptions p.SwarmOptions = swarmOptions
p.AuthOptions = authOptions p.AuthOptions = authOptions

View File

@ -44,6 +44,7 @@ type hostPathProvisioner struct {
identity types.UID identity types.UID
} }
// NewHostPathProvisioner creates a new Provisioner using host paths
func NewHostPathProvisioner() controller.Provisioner { func NewHostPathProvisioner() controller.Provisioner {
return &hostPathProvisioner{ return &hostPathProvisioner{
pvDir: "/tmp/hostpath-provisioner", pvDir: "/tmp/hostpath-provisioner",

View File

@ -32,6 +32,7 @@ const (
DefaultServiceCIDR = "10.96.0.0/12" DefaultServiceCIDR = "10.96.0.0/12"
) )
// DefaultAdmissionControllers is the list of default admission controllers/plugins
var DefaultAdmissionControllers = []string{ var DefaultAdmissionControllers = []string{
"Initializers", "Initializers",
"NamespaceLifecycle", "NamespaceLifecycle",
@ -67,6 +68,7 @@ func GetDNSIP(serviceCIDR string) (net.IP, error) {
return ip, nil return ip, nil
} }
// GetAlternateDNS returns a list of alternate names for a domain
func GetAlternateDNS(domain string) []string { func GetAlternateDNS(domain string) []string {
return []string{"kubernetes.default.svc." + domain, "kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"} return []string{"kubernetes.default.svc." + domain, "kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"}
} }

View File

@ -33,6 +33,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// GenerateCACert generates a CA certificate and RSA key for a common name
func GenerateCACert(certPath, keyPath string, name string) error { func GenerateCACert(certPath, keyPath string, name string) error {
priv, err := rsa.GenerateKey(rand.Reader, 2048) priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil { 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. // 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. // 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 { func GenerateSignedCert(certPath, keyPath, cn string, ips []net.IP, alternateDNS []string, signerCertPath, signerKeyPath string) error {
signerCertBytes, err := ioutil.ReadFile(signerCertPath) signerCertBytes, err := ioutil.ReadFile(signerCertPath)
if err != nil { if err != nil {

View File

@ -31,13 +31,16 @@ import (
const fileScheme = "file" const fileScheme = "file"
// ISODownloader downloads an ISO
type ISODownloader interface { type ISODownloader interface {
GetISOFileURI(isoURL string) string GetISOFileURI(isoURL string) string
CacheMinikubeISOFromURL(isoURL string) error CacheMinikubeISOFromURL(isoURL string) error
} }
// DefaultDownloader is the default ISODownloader
type DefaultDownloader struct{} type DefaultDownloader struct{}
// GetISOFileURI gets the local destination for a remote source
func (f DefaultDownloader) GetISOFileURI(isoURL string) string { func (f DefaultDownloader) GetISOFileURI(isoURL string) string {
urlObj, err := url.Parse(isoURL) urlObj, err := url.Parse(isoURL)
if err != nil { if err != nil {
@ -51,6 +54,7 @@ func (f DefaultDownloader) GetISOFileURI(isoURL string) string {
return "file://" + filepath.ToSlash(isoPath) return "file://" + filepath.ToSlash(isoPath)
} }
// CacheMinikubeISOFromURL downloads the ISO, if it doesn't exist in cache
func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error { func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
if !f.ShouldCacheMinikubeISO(isoURL) { if !f.ShouldCacheMinikubeISO(isoURL) {
glog.Infof("Not caching ISO, using %s", isoURL) glog.Infof("Not caching ISO, using %s", isoURL)
@ -80,6 +84,7 @@ func (f DefaultDownloader) CacheMinikubeISOFromURL(isoURL string) error {
return nil return nil
} }
// ShouldCacheMinikubeISO returns if we need to download the ISO
func (f DefaultDownloader) ShouldCacheMinikubeISO(isoURL string) bool { func (f DefaultDownloader) ShouldCacheMinikubeISO(isoURL string) bool {
// store the minikube-iso inside the .minikube dir // store the minikube-iso inside the .minikube dir
@ -96,10 +101,12 @@ func (f DefaultDownloader) ShouldCacheMinikubeISO(isoURL string) bool {
return true return true
} }
// GetISOCacheFilepath returns the path of an ISO in the local cache
func (f DefaultDownloader) GetISOCacheFilepath(isoURL string) string { func (f DefaultDownloader) GetISOCacheFilepath(isoURL string) string {
return filepath.Join(constants.GetMinipath(), "cache", "iso", filepath.Base(isoURL)) 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 { func (f DefaultDownloader) IsMinikubeISOCached(isoURL string) bool {
if _, err := os.Stat(f.GetISOCacheFilepath(isoURL)); os.IsNotExist(err) { if _, err := os.Stat(f.GetISOCacheFilepath(isoURL)); os.IsNotExist(err) {
return false return false

View File

@ -21,6 +21,7 @@ import (
"strings" "strings"
) )
// ExtraOption is an extra option
type ExtraOption struct { type ExtraOption struct {
Component string Component string
Key string Key string
@ -31,8 +32,10 @@ func (e *ExtraOption) String() string {
return fmt.Sprintf("%s.%s=%s", e.Component, e.Key, e.Value) return fmt.Sprintf("%s.%s=%s", e.Component, e.Key, e.Value)
} }
// ExtraOptionSlice is a slice of ExtraOption
type ExtraOptionSlice []ExtraOption type ExtraOptionSlice []ExtraOption
// Set parses the string value into a slice
func (es *ExtraOptionSlice) Set(value string) error { func (es *ExtraOptionSlice) Set(value string) error {
// The component is the value before the first dot. // The component is the value before the first dot.
componentSplit := strings.SplitN(value, ".", 2) componentSplit := strings.SplitN(value, ".", 2)
@ -56,6 +59,7 @@ func (es *ExtraOptionSlice) Set(value string) error {
return nil return nil
} }
// String converts the slice to a string value
func (es *ExtraOptionSlice) String() string { func (es *ExtraOptionSlice) String() string {
s := []string{} s := []string{}
for _, e := range *es { for _, e := range *es {
@ -64,6 +68,7 @@ func (es *ExtraOptionSlice) String() string {
return strings.Join(s, " ") return strings.Join(s, " ")
} }
// Type returns the type
func (es *ExtraOptionSlice) Type() string { func (es *ExtraOptionSlice) Type() string {
return "ExtraOption" return "ExtraOption"
} }

View File

@ -34,6 +34,7 @@ import (
"k8s.io/minikube/pkg/util" "k8s.io/minikube/pkg/util"
) )
// KubeConfigSetup is the kubeconfig setup
type KubeConfigSetup struct { type KubeConfigSetup struct {
// The name of the cluster for this context // The name of the cluster for this context
ClusterName string ClusterName string
@ -61,10 +62,12 @@ type KubeConfigSetup struct {
kubeConfigFile atomic.Value kubeConfigFile atomic.Value
} }
// SetKubeConfigFile sets the kubeconfig file
func (k *KubeConfigSetup) SetKubeConfigFile(kubeConfigFile string) { func (k *KubeConfigSetup) SetKubeConfigFile(kubeConfigFile string) {
k.kubeConfigFile.Store(kubeConfigFile) k.kubeConfigFile.Store(kubeConfigFile)
} }
// GetKubeConfigFile gets the kubeconfig file
func (k *KubeConfigSetup) GetKubeConfigFile() string { func (k *KubeConfigSetup) GetKubeConfigFile() string {
return k.kubeConfigFile.Load().(string) return k.kubeConfigFile.Load().(string)
} }

View File

@ -45,12 +45,14 @@ var (
ReasonableStartTime = time.Minute * 10 ReasonableStartTime = time.Minute * 10
) )
// PodStore stores pods
type PodStore struct { type PodStore struct {
cache.Store cache.Store
stopCh chan struct{} stopCh chan struct{}
Reflector *cache.Reflector Reflector *cache.Reflector
} }
// List lists the pods
func (s *PodStore) List() []*v1.Pod { func (s *PodStore) List() []*v1.Pod {
objects := s.Store.List() objects := s.Store.List()
pods := make([]*v1.Pod, 0) pods := make([]*v1.Pod, 0)
@ -60,10 +62,12 @@ func (s *PodStore) List() []*v1.Pod {
return pods return pods
} }
// Stop stops the pods
func (s *PodStore) Stop() { func (s *PodStore) Stop() {
close(s.stopCh) close(s.stopCh)
} }
// GetClient gets the client from config
func GetClient() (kubernetes.Interface, error) { func GetClient() (kubernetes.Interface, error) {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
configOverrides := &clientcmd.ConfigOverrides{} configOverrides := &clientcmd.ConfigOverrides{}
@ -79,6 +83,7 @@ func GetClient() (kubernetes.Interface, error) {
return client, nil return client, nil
} }
// NewPodStore creates a new PodStore
func NewPodStore(c kubernetes.Interface, namespace string, label labels.Selector, field fields.Selector) *PodStore { func NewPodStore(c kubernetes.Interface, namespace string, label labels.Selector, field fields.Selector) *PodStore {
lw := &cache.ListWatch{ lw := &cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { 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} 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 { func StartPods(c kubernetes.Interface, namespace string, pod v1.Pod, waitForRunning bool) error {
pod.ObjectMeta.Labels["name"] = pod.Name pod.ObjectMeta.Labels["name"] = pod.Name
if waitForRunning { if waitForRunning {
@ -285,6 +291,7 @@ func countEndpointsNum(e *v1.Endpoints) int {
return num return num
} }
// IsRetryableAPIError returns if this error is retryable or not
func IsRetryableAPIError(err error) bool { func IsRetryableAPIError(err error) bool {
return apierrs.IsTimeout(err) || apierrs.IsServerTimeout(err) || apierrs.IsTooManyRequests(err) || apierrs.IsInternalError(err) return apierrs.IsTimeout(err) || apierrs.IsServerTimeout(err) || apierrs.IsTooManyRequests(err) || apierrs.IsInternalError(err)
} }

View File

@ -35,19 +35,24 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// ErrPrefix notes an error
const ErrPrefix = "! " const ErrPrefix = "! "
// OutPrefix notes output
const OutPrefix = "> " const OutPrefix = "> "
const ( const (
downloadURL = "https://storage.googleapis.com/minikube/releases/%s/minikube-%s-amd64%s" downloadURL = "https://storage.googleapis.com/minikube/releases/%s/minikube-%s-amd64%s"
) )
// RetriableError is an error that can be tried again
type RetriableError struct { type RetriableError struct {
Err error Err error
} }
func (r RetriableError) Error() string { return "Temporary Error: " + r.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 { func CalculateDiskSizeInMB(humanReadableDiskSize string) int {
diskSize, err := units.FromHumanSize(humanReadableDiskSize) diskSize, err := units.FromHumanSize(humanReadableDiskSize)
if err != nil { 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 { func Pad(str string) string {
return fmt.Sprintf("\n%s\n", str) return fmt.Sprintf("\n%s\n", str)
} }
@ -95,10 +101,12 @@ func CanReadFile(path string) bool {
return true return true
} }
// Retry retries a number of attempts
func Retry(attempts int, callback func() error) (err error) { func Retry(attempts int, callback func() error) (err error) {
return RetryAfter(attempts, callback, 0) 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) { func RetryAfter(attempts int, callback func() error, d time.Duration) (err error) {
m := MultiError{} m := MultiError{}
for i := 0; i < attempts; i++ { 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() return m.ToError()
} }
// ParseSHAFromURL downloads and reads a SHA checksum from an URL
func ParseSHAFromURL(url string) (string, error) { func ParseSHAFromURL(url string) (string, error) {
r, err := http.Get(url) r, err := http.Get(url)
if err != nil { if err != nil {
@ -137,6 +146,7 @@ func ParseSHAFromURL(url string) (string, error) {
return strings.Trim(string(body), "\n"), nil return strings.Trim(string(body), "\n"), nil
} }
// GetBinaryDownloadURL returns a suitable URL for the platform
func GetBinaryDownloadURL(version, platform string) string { func GetBinaryDownloadURL(version, platform string) string {
switch platform { switch platform {
case "windows": case "windows":
@ -146,16 +156,19 @@ func GetBinaryDownloadURL(version, platform string) string {
} }
} }
// MultiError holds multiple errors
type MultiError struct { type MultiError struct {
Errors []error Errors []error
} }
// Collect adds the error
func (m *MultiError) Collect(err error) { func (m *MultiError) Collect(err error) {
if err != nil { if err != nil {
m.Errors = append(m.Errors, err) m.Errors = append(m.Errors, err)
} }
} }
// ToError converts all errors into one
func (m MultiError) ToError() error { func (m MultiError) ToError() error {
if len(m.Errors) == 0 { if len(m.Errors) == 0 {
return nil return nil
@ -168,6 +181,7 @@ func (m MultiError) ToError() error {
return errors.New(strings.Join(errStrings, "\n")) return errors.New(strings.Join(errStrings, "\n"))
} }
// IsDirectory checks if path is a directory
func IsDirectory(path string) (bool, error) { func IsDirectory(path string) (bool, error) {
fileInfo, err := os.Stat(path) fileInfo, err := os.Stat(path)
if err != nil { if err != nil {
@ -176,6 +190,7 @@ func IsDirectory(path string) (bool, error) {
return fileInfo.IsDir(), nil return fileInfo.IsDir(), nil
} }
// ChownR does a recursive os.Chown
func ChownR(path string, uid, gid int) error { func ChownR(path string, uid, gid int) error {
return filepath.Walk(path, func(name string, info os.FileInfo, err error) error { return filepath.Walk(path, func(name string, info os.FileInfo, err error) error {
if err == nil { 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 { func MaybeChownDirRecursiveToMinikubeUser(dir string) error {
if os.Getenv("CHANGE_MINIKUBE_NONE_USER") != "" && os.Getenv("SUDO_USER") != "" { if os.Getenv("CHANGE_MINIKUBE_NONE_USER") != "" && os.Getenv("SUDO_USER") != "" {
username := os.Getenv("SUDO_USER") username := os.Getenv("SUDO_USER")

View File

@ -22,6 +22,7 @@ import (
"github.com/blang/semver" "github.com/blang/semver"
) )
// VersionPrefix is the prefix of the git tag for a version
const VersionPrefix = "v" const VersionPrefix = "v"
// The current version of the minikube // The current version of the minikube
@ -34,18 +35,22 @@ var isoVersion = "v0.0.0-unset"
var isoPath = "minikube/iso" var isoPath = "minikube/iso"
// GetVersion returns the current minikube version
func GetVersion() string { func GetVersion() string {
return version return version
} }
// GetISOVersion returns the current minikube.iso version
func GetISOVersion() string { func GetISOVersion() string {
return isoVersion return isoVersion
} }
// GetISOPath returns the remote path to the minikube.iso
func GetISOPath() string { func GetISOPath() string {
return isoPath return isoPath
} }
// GetSemverVersion returns the current minikube semantic version (semver)
func GetSemverVersion() (semver.Version, error) { func GetSemverVersion() (semver.Version, error) {
return semver.Make(strings.TrimPrefix(GetVersion(), VersionPrefix)) return semver.Make(strings.TrimPrefix(GetVersion(), VersionPrefix))
} }

View File

@ -24,6 +24,7 @@ import (
"k8s.io/minikube/test/integration/util" "k8s.io/minikube/test/integration/util"
) )
// TestMain is the test main
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
flag.Parse() flag.Parse()
os.Exit(m.Run()) 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 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") 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 { func NewMinikubeRunner(t *testing.T) util.MinikubeRunner {
return util.MinikubeRunner{ return util.MinikubeRunner{
Args: *args, Args: *args,

View File

@ -39,6 +39,7 @@ import (
const kubectlBinary = "kubectl" const kubectlBinary = "kubectl"
// MinikubeRunner runs a command
type MinikubeRunner struct { type MinikubeRunner struct {
T *testing.T T *testing.T
BinaryPath string BinaryPath string
@ -57,11 +58,13 @@ func Logf(str string, args ...interface{}) {
fmt.Println(fmt.Sprintf(str, args...)) fmt.Println(fmt.Sprintf(str, args...))
} }
// Run executes a command
func (m *MinikubeRunner) Run(cmd string) error { func (m *MinikubeRunner) Run(cmd string) error {
_, err := m.SSH(cmd) _, err := m.SSH(cmd)
return err return err
} }
// Copy copies a file
func (m *MinikubeRunner) Copy(f assets.CopyableFile) error { func (m *MinikubeRunner) Copy(f assets.CopyableFile) error {
path, _ := filepath.Abs(m.BinaryPath) path, _ := filepath.Abs(m.BinaryPath)
cmd := exec.Command("/bin/bash", "-c", path, "ssh", "--", fmt.Sprintf("cat >> %s", filepath.Join(f.GetTargetDir(), f.GetTargetName()))) 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() return cmd.Run()
} }
// CombinedOutput executes a command, returning the combined stdout and stderr
func (m *MinikubeRunner) CombinedOutput(cmd string) (string, error) { func (m *MinikubeRunner) CombinedOutput(cmd string) (string, error) {
return m.SSH(cmd) return m.SSH(cmd)
} }
// Remove removes a file
func (m *MinikubeRunner) Remove(f assets.CopyableFile) error { func (m *MinikubeRunner) Remove(f assets.CopyableFile) error {
_, err := m.SSH(fmt.Sprintf("rm -rf %s", filepath.Join(f.GetTargetDir(), f.GetTargetName()))) _, err := m.SSH(fmt.Sprintf("rm -rf %s", filepath.Join(f.GetTargetDir(), f.GetTargetName())))
return err return err
@ -111,6 +116,7 @@ func (m *MinikubeRunner) teeRun(cmd *exec.Cmd) (string, string, error) {
return outB.String(), errB.String(), err return outB.String(), errB.String(), err
} }
// RunCommand executes a command, optionally checking for error
func (m *MinikubeRunner) RunCommand(command string, checkError bool) string { func (m *MinikubeRunner) RunCommand(command string, checkError bool) string {
commandArr := strings.Split(command, " ") commandArr := strings.Split(command, " ")
path, _ := filepath.Abs(m.BinaryPath) path, _ := filepath.Abs(m.BinaryPath)
@ -136,6 +142,7 @@ func (m *MinikubeRunner) RunWithContext(ctx context.Context, command string) (st
return m.teeRun(cmd) return m.teeRun(cmd)
} }
// RunDaemon executes a command, returning the stdout
func (m *MinikubeRunner) RunDaemon(command string) (*exec.Cmd, *bufio.Reader) { func (m *MinikubeRunner) RunDaemon(command string) (*exec.Cmd, *bufio.Reader) {
commandArr := strings.Split(command, " ") commandArr := strings.Split(command, " ")
path, _ := filepath.Abs(m.BinaryPath) 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) { func (m *MinikubeRunner) RunDaemon2(command string) (*exec.Cmd, *bufio.Reader, *bufio.Reader) {
commandArr := strings.Split(command, " ") commandArr := strings.Split(command, " ")
path, _ := filepath.Abs(m.BinaryPath) path, _ := filepath.Abs(m.BinaryPath)
@ -189,6 +197,7 @@ func (m *MinikubeRunner) SetRuntime(runtime string) {
m.Runtime = runtime m.Runtime = runtime
} }
// SSH returns the output of running a command using SSH
func (m *MinikubeRunner) SSH(command string) (string, error) { func (m *MinikubeRunner) SSH(command string) (string, error) {
path, _ := filepath.Abs(m.BinaryPath) path, _ := filepath.Abs(m.BinaryPath)
cmd := exec.Command(path, "ssh", command) cmd := exec.Command(path, "ssh", command)
@ -202,6 +211,7 @@ func (m *MinikubeRunner) SSH(command string) (string, error) {
return string(stdout), nil return string(stdout), nil
} }
// Start starts the container runtime
func (m *MinikubeRunner) Start() { func (m *MinikubeRunner) Start() {
opts := "" opts := ""
// TODO(tstromberg): Deprecate this in favor of making it possible for tests to define explicit flags. // 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() { func (m *MinikubeRunner) EnsureRunning() {
if m.GetStatus() != "Running" { if m.GetStatus() != "Running" {
m.Start() m.Start()
@ -232,20 +243,24 @@ func (m *MinikubeRunner) ParseEnvCmdOutput(out string) map[string]string {
return env return env
} }
// GetStatus returns the status of a service
func (m *MinikubeRunner) GetStatus() string { func (m *MinikubeRunner) GetStatus() string {
return m.RunCommand(fmt.Sprintf("status --format={{.Host}} %s", m.Args), false) return m.RunCommand(fmt.Sprintf("status --format={{.Host}} %s", m.Args), false)
} }
// GetLogs returns the logs of a service
func (m *MinikubeRunner) GetLogs() string { func (m *MinikubeRunner) GetLogs() string {
return m.RunCommand(fmt.Sprintf("logs %s", m.Args), true) 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) { func (m *MinikubeRunner) CheckStatus(desired string) {
if err := m.CheckStatusNoFail(desired); err != nil { if err := m.CheckStatusNoFail(desired); err != nil {
m.T.Fatalf("%v", err) m.T.Fatalf("%v", err)
} }
} }
// CheckStatusNoFail makes sure the service has the desired status, returning error
func (m *MinikubeRunner) CheckStatusNoFail(desired string) error { func (m *MinikubeRunner) CheckStatusNoFail(desired string) error {
s := m.GetStatus() s := m.GetStatus()
if s != desired { if s != desired {
@ -254,11 +269,13 @@ func (m *MinikubeRunner) CheckStatusNoFail(desired string) error {
return nil return nil
} }
// KubectlRunner runs a command using kubectl
type KubectlRunner struct { type KubectlRunner struct {
T *testing.T T *testing.T
BinaryPath string BinaryPath string
} }
// NewKubectlRunner creates a new KubectlRunner
func NewKubectlRunner(t *testing.T) *KubectlRunner { func NewKubectlRunner(t *testing.T) *KubectlRunner {
p, err := exec.LookPath(kubectlBinary) p, err := exec.LookPath(kubectlBinary)
if err != nil { if err != nil {
@ -267,6 +284,7 @@ func NewKubectlRunner(t *testing.T) *KubectlRunner {
return &KubectlRunner{BinaryPath: p, T: t} return &KubectlRunner{BinaryPath: p, T: t}
} }
// RunCommandParseOutput runs a command and parses the JSON output
func (k *KubectlRunner) RunCommandParseOutput(args []string, outputObj interface{}) error { func (k *KubectlRunner) RunCommandParseOutput(args []string, outputObj interface{}) error {
args = append(args, "-o=json") args = append(args, "-o=json")
output, err := k.RunCommand(args) output, err := k.RunCommand(args)
@ -280,6 +298,7 @@ func (k *KubectlRunner) RunCommandParseOutput(args []string, outputObj interface
return nil return nil
} }
// RunCommand runs a command, returning stdout
func (k *KubectlRunner) RunCommand(args []string) (stdout []byte, err error) { func (k *KubectlRunner) RunCommand(args []string) (stdout []byte, err error) {
inner := func() error { inner := func() error {
cmd := exec.Command(k.BinaryPath, args...) cmd := exec.Command(k.BinaryPath, args...)
@ -296,6 +315,7 @@ func (k *KubectlRunner) RunCommand(args []string) (stdout []byte, err error) {
return stdout, err return stdout, err
} }
// CreateRandomNamespace creates a random namespace
func (k *KubectlRunner) CreateRandomNamespace() string { func (k *KubectlRunner) CreateRandomNamespace() string {
const strLen = 20 const strLen = 20
name := genRandString(strLen) name := genRandString(strLen)
@ -315,11 +335,13 @@ func genRandString(strLen int) string {
return string(result) return string(result)
} }
// DeleteNamespace deletes the namespace
func (k *KubectlRunner) DeleteNamespace(namespace string) error { func (k *KubectlRunner) DeleteNamespace(namespace string) error {
_, err := k.RunCommand([]string{"delete", "namespace", namespace}) _, err := k.RunCommand([]string{"delete", "namespace", namespace})
return err return err
} }
// WaitForBusyboxRunning waits until busybox pod to be running
func WaitForBusyboxRunning(t *testing.T, namespace string) error { func WaitForBusyboxRunning(t *testing.T, namespace string) error {
client, err := commonutil.GetClient() client, err := commonutil.GetClient()
if err != nil { if err != nil {
@ -329,6 +351,7 @@ func WaitForBusyboxRunning(t *testing.T, namespace string) error {
return commonutil.WaitForPodsWithLabelRunning(client, namespace, selector) return commonutil.WaitForPodsWithLabelRunning(client, namespace, selector)
} }
// WaitForIngressControllerRunning waits until ingress controller pod to be running
func WaitForIngressControllerRunning(t *testing.T) error { func WaitForIngressControllerRunning(t *testing.T) error {
client, err := commonutil.GetClient() client, err := commonutil.GetClient()
if err != nil { if err != nil {
@ -347,6 +370,7 @@ func WaitForIngressControllerRunning(t *testing.T) error {
return nil return nil
} }
// WaitForIngressDefaultBackendRunning waits until ingress default backend pod to be running
func WaitForIngressDefaultBackendRunning(t *testing.T) error { func WaitForIngressDefaultBackendRunning(t *testing.T) error {
client, err := commonutil.GetClient() client, err := commonutil.GetClient()
if err != nil { if err != nil {
@ -422,6 +446,7 @@ func WaitForFailedCreatePodSandBoxEvent() error {
return nil return nil
} }
// WaitForNginxRunning waits for nginx service to be up
func WaitForNginxRunning(t *testing.T) error { func WaitForNginxRunning(t *testing.T) error {
client, err := commonutil.GetClient() client, err := commonutil.GetClient()
@ -440,6 +465,7 @@ func WaitForNginxRunning(t *testing.T) error {
return nil 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) { func Retry(t *testing.T, callback func() error, d time.Duration, attempts int) (err error) {
for i := 0; i < attempts; i++ { for i := 0; i < attempts; i++ {
err = callback() err = callback()