# TODO (ayurchuk) Refactor the get_* functions to use filters
# TODO (ayurchuk) Refactor the get_* functions to use filters
# TODO (bburns) Parameterize this for multiple cluster per project
# TODO (bburns) Parameterize this for multiple cluster per project
function get_instance_ids {
python -c"import json,sys; lst = [str(instance['InstanceId']) for reservation in json.load(sys.stdin)['Reservations'] for instance in reservation['Instances'] for tag in instance.get('Tags', []) if tag['Value'].startswith('${MASTER_TAG}') or tag['Value'].startswith('${MINION_TAG}')]; print ' '.join(lst)"
}
function get_vpc_id {
function get_vpc_id {
python -c'import json,sys; lst = [str(vpc["VpcId"]) for vpc in json.load(sys.stdin)["Vpcs"] for tag in vpc.get("Tags", []) if tag["Value"] == "kubernetes-vpc"]; print "".join(lst)'
$AWS_CMD--output text describe-vpcs \
--filtersName=tag:Name,Values=kubernetes-vpc \
Name=tag:KubernetesCluster,Values=${CLUSTER_ID}\
--query Vpcs[].VpcId
}
}
function get_subnet_id {
function get_subnet_id {
...
@@ -69,7 +69,9 @@ function expect_instance_states {
...
@@ -69,7 +69,9 @@ function expect_instance_states {
orderseed=flag.Int64("orderseed",0,"If non-zero, seed of random test shuffle order. (Otherwise random.)")
orderseed=flag.Int64("orderseed",0,"If non-zero, seed of random test shuffle order. (Otherwise random.)")
reportDir=flag.String("report_dir","","Path to the directory where the JUnit XML reports should be saved. Default is empty, which doesn't generate these reports.")
reportDir=flag.String("report_dir","","Path to the directory where the JUnit XML reports should be saved. Default is empty, which doesn't generate these reports.")
...
@@ -47,9 +50,11 @@ func init() {
...
@@ -47,9 +50,11 @@ func init() {
flag.StringVar(&context.Host,"host","","The host, or apiserver, to connect to")
flag.StringVar(&context.Host,"host","","The host, or apiserver, to connect to")
flag.StringVar(&context.RepoRoot,"repo_root","./","Root directory of kubernetes repository, for finding test files. Default assumes working directory is repository root")
flag.StringVar(&context.RepoRoot,"repo_root","./","Root directory of kubernetes repository, for finding test files. Default assumes working directory is repository root")
flag.StringVar(&context.Provider,"provider","","The name of the Kubernetes provider (gce, gke, local, vagrant, etc.)")
flag.StringVar(&context.Provider,"provider","","The name of the Kubernetes provider (gce, gke, local, vagrant, etc.)")
flag.StringVar(&gceConfig.MasterName,"kube_master","","Name of the kubernetes master. Only required if provider is gce or gke")
flag.StringVar(&gceConfig.ProjectID,"gce_project","","The GCE project being used, if applicable")
// TODO: Flags per provider? Rename gce_project/gce_zone?
flag.StringVar(&gceConfig.Zone,"gce_zone","","GCE zone being used, if applicable")
flag.StringVar(&cloudConfig.MasterName,"kube_master","","Name of the kubernetes master. Only required if provider is gce or gke")
flag.StringVar(&cloudConfig.ProjectID,"gce_project","","The GCE project being used, if applicable")
flag.StringVar(&cloudConfig.Zone,"gce_zone","","GCE zone being used, if applicable")
}
}
funcmain(){
funcmain(){
...
@@ -63,5 +68,22 @@ func main() {
...
@@ -63,5 +68,22 @@ func main() {
glog.Error("Invalid --times (negative or no testing requested)!")
glog.Error("Invalid --times (negative or no testing requested)!")
// Source represents the location and type of a volume to mount.
// Source represents the location and type of a volume to mount.
// This is optional for now. If not specified, the Volume is implied to be an EmptyDir.
// This is optional for now. If not specified, the Volume is implied to be an EmptyDir.
// This implied behavior is deprecated and will be removed in a future version.
// This implied behavior is deprecated and will be removed in a future version.
SourceVolumeSource`json:"source,omitempty" description:"location and type of volume to mount; at most one of HostDir, EmptyDir, GCEPersistentDisk, or GitRepo; default is EmptyDir"`
SourceVolumeSource`json:"source,omitempty" description:"location and type of volume to mount; at most one of HostDir, EmptyDir, GCEPersistentDisk, AWSElasticBlockStore, or GitRepo; default is EmptyDir"`
}
}
// VolumeSource represents the source location of a volume to mount.
// VolumeSource represents the source location of a volume to mount.
...
@@ -105,6 +105,9 @@ type VolumeSource struct {
...
@@ -105,6 +105,9 @@ type VolumeSource struct {
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// kubelet's host machine and then exposed to the pod.
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource attached to the host machine on demand"`
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource attached to the host machine on demand"`
// AWSElasticBlockStore represents an AWS Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
AWSElasticBlockStore*AWSElasticBlockStoreVolumeSource`json:"awsElasticBlockStore" description:"AWS disk resource attached to the host machine on demand"`
// GitRepo represents a git repository at a particular revision.
// GitRepo represents a git repository at a particular revision.
GitRepo*GitRepoVolumeSource`json:"gitRepo" description:"git repository at a particular revision"`
GitRepo*GitRepoVolumeSource`json:"gitRepo" description:"git repository at a particular revision"`
// Secret represents a secret to populate the volume with
// Secret represents a secret to populate the volume with
...
@@ -124,6 +127,9 @@ type PersistentVolumeSource struct {
...
@@ -124,6 +127,9 @@ type PersistentVolumeSource struct {
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// kubelet's host machine and then exposed to the pod.
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource provisioned by an admin"`
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource provisioned by an admin"`
// AWSElasticBlockStore represents an AWS EBS volume that is attached to a
// kubelet's host machine and then exposed to the pod.
AWSElasticBlockStore*AWSElasticBlockStoreVolumeSource`json:"awsElasticBlockStore" description:"AWS disk resource provisioned by an admin"`
// HostPath represents a directory on the host.
// HostPath represents a directory on the host.
// This is useful for development and testing only.
// This is useful for development and testing only.
// on-host storage is not supported in any way.
// on-host storage is not supported in any way.
...
@@ -302,6 +308,29 @@ type ISCSIVolumeSource struct {
...
@@ -302,6 +308,29 @@ type ISCSIVolumeSource struct {
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
}
}
// AWSElasticBlockStoreVolumeSource represents a Persistent Disk resource in AWS.
//
// An AWS PD must exist and be formatted before mounting to a container.
// The disk must also be in the same AWS zone as the kubelet.
// A AWS PD can only be mounted on a single machine.
typeAWSElasticBlockStoreVolumeSourcestruct{
// Unique id of the PD resource. Used to identify the disk in AWS
VolumeIDstring`json:"volumeID" description:"unique id of the PD resource in AWS"`
// Required: Filesystem type to mount.
// Must be a filesystem type supported by the host operating system.
// Ex. "ext4", "xfs", "ntfs"
// TODO: how do we prevent errors in the filesystem from compromising the machine
// TODO: why omitempty if required?
FSTypestring`json:"fsType,omitempty" description:"file system type to mount, such as ext4, xfs, ntfs"`
// Optional: Partition on the disk to mount.
// If omitted, kubelet will attempt to mount the device name.
// Ex. For /dev/sda1, this field is "1", for /dev/sda, this field 0 or empty.
Partitionint`json:"partition,omitempty" description:"partition on the disk to mount (e.g., '1' for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted"`
// Optional: Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
}
// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created.
// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created.
// Source represents the location and type of a volume to mount.
// Source represents the location and type of a volume to mount.
// This is optional for now. If not specified, the Volume is implied to be an EmptyDir.
// This is optional for now. If not specified, the Volume is implied to be an EmptyDir.
// This implied behavior is deprecated and will be removed in a future version.
// This implied behavior is deprecated and will be removed in a future version.
SourceVolumeSource`json:"source,omitempty" description:"location and type of volume to mount; at most one of HostDir, EmptyDir, GCEPersistentDisk, or GitRepo; default is EmptyDir"`
SourceVolumeSource`json:"source,omitempty" description:"location and type of volume to mount; at most one of HostDir, EmptyDir, GCEPersistentDisk, AWSElasticBlockStore, or GitRepo; default is EmptyDir"`
}
}
// VolumeSource represents the source location of a volume to mount.
// VolumeSource represents the source location of a volume to mount.
...
@@ -74,6 +74,9 @@ type VolumeSource struct {
...
@@ -74,6 +74,9 @@ type VolumeSource struct {
// A persistent disk that is mounted to the
// A persistent disk that is mounted to the
// kubelet's host machine and then exposed to the pod.
// kubelet's host machine and then exposed to the pod.
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource attached to the host machine on demand"`
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource attached to the host machine on demand"`
// An AWS persistent disk that is mounted to the
// kubelet's host machine and then exposed to the pod.
AWSElasticBlockStore*AWSElasticBlockStoreVolumeSource`json:"awsElasticBlockStore" description:"AWS disk resource attached to the host machine on demand"`
// GitRepo represents a git repository at a particular revision.
// GitRepo represents a git repository at a particular revision.
GitRepo*GitRepoVolumeSource`json:"gitRepo" description:"git repository at a particular revision"`
GitRepo*GitRepoVolumeSource`json:"gitRepo" description:"git repository at a particular revision"`
// Secret is a secret to populate the volume with
// Secret is a secret to populate the volume with
...
@@ -93,6 +96,9 @@ type PersistentVolumeSource struct {
...
@@ -93,6 +96,9 @@ type PersistentVolumeSource struct {
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// kubelet's host machine and then exposed to the pod.
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource provisioned by an admin"`
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"persistentDisk" description:"GCE disk resource provisioned by an admin"`
// AWSElasticBlockStore represents an AWS Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
AWSElasticBlockStore*AWSElasticBlockStoreVolumeSource`json:"awsElasticBlockStore" description:"AWS disk resource provisioned by an admin"`
// HostPath represents a directory on the host.
// HostPath represents a directory on the host.
// This is useful for development and testing only.
// This is useful for development and testing only.
// on-host storage is not supported in any way.
// on-host storage is not supported in any way.
...
@@ -284,6 +290,29 @@ type GCEPersistentDiskVolumeSource struct {
...
@@ -284,6 +290,29 @@ type GCEPersistentDiskVolumeSource struct {
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
}
}
// AWSElasticBlockStoreVolumeSource represents a Persistent Disk resource in AWS.
//
// An AWS PD must exist and be formatted before mounting to a container.
// The disk must also be in the same AWS zone as the kubelet.
// A AWS PD can only be mounted on a single machine.
typeAWSElasticBlockStoreVolumeSourcestruct{
// Unique id of the PD resource. Used to identify the disk in AWS
VolumeIDstring`json:"volumeID" description:"unique id of the PD resource in AWS"`
// Required: Filesystem type to mount.
// Must be a filesystem type supported by the host operating system.
// Ex. "ext4", "xfs", "ntfs"
// TODO: how do we prevent errors in the filesystem from compromising the machine
// TODO: why omitempty if required?
FSTypestring`json:"fsType,omitempty" description:"file system type to mount, such as ext4, xfs, ntfs"`
// Optional: Partition on the disk to mount.
// If omitted, kubelet will attempt to mount the device name.
// Ex. For /dev/sda1, this field is "1", for /dev/sda, this field 0 or empty.
Partitionint`json:"partition,omitempty" description:"partition on the disk to mount (e.g., '1' for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted"`
// Optional: Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
}
// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created.
// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created.
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// kubelet's host machine and then exposed to the pod.
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"gcePersistentDisk" description:"GCE disk resource attached to the host machine on demand"`
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"gcePersistentDisk" description:"GCE disk resource attached to the host machine on demand"`
// AWSElasticBlockStore represents an AWS Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
AWSElasticBlockStore*AWSElasticBlockStoreVolumeSource`json:"awsElasticBlockStore" description:"AWS disk resource attached to the host machine on demand"`
// GitRepo represents a git repository at a particular revision.
// GitRepo represents a git repository at a particular revision.
GitRepo*GitRepoVolumeSource`json:"gitRepo" description:"git repository at a particular revision"`
GitRepo*GitRepoVolumeSource`json:"gitRepo" description:"git repository at a particular revision"`
// Secret represents a secret that should populate this volume.
// Secret represents a secret that should populate this volume.
...
@@ -225,6 +228,9 @@ type PersistentVolumeSource struct {
...
@@ -225,6 +228,9 @@ type PersistentVolumeSource struct {
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// GCEPersistentDisk represents a GCE Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
// kubelet's host machine and then exposed to the pod.
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"gcePersistentDisk" description:"GCE disk resource provisioned by an admin"`
GCEPersistentDisk*GCEPersistentDiskVolumeSource`json:"gcePersistentDisk" description:"GCE disk resource provisioned by an admin"`
// AWSElasticBlockStore represents an AWS Disk resource that is attached to a
// kubelet's host machine and then exposed to the pod.
AWSElasticBlockStore*AWSElasticBlockStoreVolumeSource`json:"awsElasticBlockStore" description:"AWS disk resource provisioned by an admin"`
// HostPath represents a directory on the host.
// HostPath represents a directory on the host.
// This is useful for development and testing only.
// This is useful for development and testing only.
// on-host storage is not supported in any way.
// on-host storage is not supported in any way.
...
@@ -400,6 +406,29 @@ type GCEPersistentDiskVolumeSource struct {
...
@@ -400,6 +406,29 @@ type GCEPersistentDiskVolumeSource struct {
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
}
}
// AWSElasticBlockStoreVolumeSource represents a Persistent Disk resource in AWS.
//
// An AWS PD must exist and be formatted before mounting to a container.
// The disk must also be in the same AWS zone as the kubelet.
// A AWS PD can only be mounted on a single machine.
typeAWSElasticBlockStoreVolumeSourcestruct{
// Unique id of the PD resource. Used to identify the disk in AWS
VolumeIDstring`json:"volumeID" description:"unique id of the PD resource in AWS"`
// Required: Filesystem type to mount.
// Must be a filesystem type supported by the host operating system.
// Ex. "ext4", "xfs", "ntfs"
// TODO: how do we prevent errors in the filesystem from compromising the machine
// TODO: why omitempty if required?
FSTypestring`json:"fsType,omitempty" description:"file system type to mount, such as ext4, xfs, ntfs"`
// Optional: Partition on the disk to mount.
// If omitted, kubelet will attempt to mount the device name.
// Ex. For /dev/sda1, this field is "1", for /dev/sda, this field 0 or empty.
Partitionint`json:"partition,omitempty" description:"partition on the disk to mount (e.g., '1' for /dev/sda1); if omitted the plain device name (e.g., /dev/sda) will be mounted"`
// Optional: Defaults to false (read/write). ReadOnly here will force
// the ReadOnly setting in VolumeMounts.
ReadOnlybool`json:"readOnly,omitempty" description:"read-only if true, read-write otherwise (false or unspecified)"`
}
// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created.
// GitRepoVolumeSource represents a volume that is pulled from git when the pod is created.
allErrs=append(allErrs,errs.NewFieldInvalid("GCEPersistentDisk.ReadOnly",false,"ReadOnly must be true for replicated pods > 1, as GCE PD can only be mounted on multiple machines if it is read-only."))
allErrs=append(allErrs,errs.NewFieldInvalid("GCEPersistentDisk.ReadOnly",false,"ReadOnly must be true for replicated pods > 1, as GCE PD can only be mounted on multiple machines if it is read-only."))
}
}
}
}
// TODO: What to do for AWS? It doesn't support replicas