Downward API implementation for resources limits and requests

This commit is contained in:
Avesh Agarwal 2016-05-23 18:08:22 -04:00
parent 5303794ef0
commit 1931931494
27 changed files with 2686 additions and 725 deletions

View File

@ -1709,8 +1709,7 @@
"id": "v1.DownwardAPIVolumeFile",
"description": "DownwardAPIVolumeFile represents information to create the file containing the pod field",
"required": [
"path",
"fieldRef"
"path"
],
"properties": {
"path": {
@ -1720,6 +1719,10 @@
"fieldRef": {
"$ref": "v1.ObjectFieldSelector",
"description": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
}
}
},
@ -1740,6 +1743,27 @@
}
}
},
"v1.ResourceFieldSelector": {
"id": "v1.ResourceFieldSelector",
"description": "ResourceFieldSelector represents container resources (cpu, memory) and their output format",
"required": [
"resource"
],
"properties": {
"containerName": {
"type": "string",
"description": "Container name: required for volumes, optional for env vars"
},
"resource": {
"type": "string",
"description": "Required: resource to select"
},
"divisor": {
"type": "string",
"description": "Specifies the output format of the exposed resources, defaults to \"1\""
}
}
},
"v1.FCVolumeSource": {
"id": "v1.FCVolumeSource",
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
@ -1982,6 +2006,10 @@
"$ref": "v1.ObjectFieldSelector",
"description": "Selects a field of the pod; only name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
},
"configMapKeyRef": {
"$ref": "v1.ConfigMapKeySelector",
"description": "Selects a key of a ConfigMap."

View File

@ -1714,8 +1714,7 @@
"id": "v1.DownwardAPIVolumeFile",
"description": "DownwardAPIVolumeFile represents information to create the file containing the pod field",
"required": [
"path",
"fieldRef"
"path"
],
"properties": {
"path": {
@ -1725,6 +1724,10 @@
"fieldRef": {
"$ref": "v1.ObjectFieldSelector",
"description": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
}
}
},
@ -1745,6 +1748,27 @@
}
}
},
"v1.ResourceFieldSelector": {
"id": "v1.ResourceFieldSelector",
"description": "ResourceFieldSelector represents container resources (cpu, memory) and their output format",
"required": [
"resource"
],
"properties": {
"containerName": {
"type": "string",
"description": "Container name: required for volumes, optional for env vars"
},
"resource": {
"type": "string",
"description": "Required: resource to select"
},
"divisor": {
"type": "string",
"description": "Specifies the output format of the exposed resources, defaults to \"1\""
}
}
},
"v1.FCVolumeSource": {
"id": "v1.FCVolumeSource",
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
@ -1987,6 +2011,10 @@
"$ref": "v1.ObjectFieldSelector",
"description": "Selects a field of the pod; only name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
},
"configMapKeyRef": {
"$ref": "v1.ConfigMapKeySelector",
"description": "Selects a key of a ConfigMap."

View File

@ -7021,8 +7021,7 @@
"id": "v1.DownwardAPIVolumeFile",
"description": "DownwardAPIVolumeFile represents information to create the file containing the pod field",
"required": [
"path",
"fieldRef"
"path"
],
"properties": {
"path": {
@ -7032,6 +7031,10 @@
"fieldRef": {
"$ref": "v1.ObjectFieldSelector",
"description": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
}
}
},
@ -7052,6 +7055,27 @@
}
}
},
"v1.ResourceFieldSelector": {
"id": "v1.ResourceFieldSelector",
"description": "ResourceFieldSelector represents container resources (cpu, memory) and their output format",
"required": [
"resource"
],
"properties": {
"containerName": {
"type": "string",
"description": "Container name: required for volumes, optional for env vars"
},
"resource": {
"type": "string",
"description": "Required: resource to select"
},
"divisor": {
"type": "string",
"description": "Specifies the output format of the exposed resources, defaults to \"1\""
}
}
},
"v1.FCVolumeSource": {
"id": "v1.FCVolumeSource",
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
@ -7294,6 +7318,10 @@
"$ref": "v1.ObjectFieldSelector",
"description": "Selects a field of the pod; only name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
},
"configMapKeyRef": {
"$ref": "v1.ConfigMapKeySelector",
"description": "Selects a key of a ConfigMap."

View File

@ -17105,8 +17105,7 @@
"id": "v1.DownwardAPIVolumeFile",
"description": "DownwardAPIVolumeFile represents information to create the file containing the pod field",
"required": [
"path",
"fieldRef"
"path"
],
"properties": {
"path": {
@ -17116,6 +17115,10 @@
"fieldRef": {
"$ref": "v1.ObjectFieldSelector",
"description": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
}
}
},
@ -17136,6 +17139,27 @@
}
}
},
"v1.ResourceFieldSelector": {
"id": "v1.ResourceFieldSelector",
"description": "ResourceFieldSelector represents container resources (cpu, memory) and their output format",
"required": [
"resource"
],
"properties": {
"containerName": {
"type": "string",
"description": "Container name: required for volumes, optional for env vars"
},
"resource": {
"type": "string",
"description": "Required: resource to select"
},
"divisor": {
"type": "string",
"description": "Specifies the output format of the exposed resources, defaults to \"1\""
}
}
},
"v1.ConfigMapVolumeSource": {
"id": "v1.ConfigMapVolumeSource",
"description": "Adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. ConfigMap volumes support ownership management and SELinux relabeling.",
@ -17309,6 +17333,10 @@
"$ref": "v1.ObjectFieldSelector",
"description": "Selects a field of the pod; only name and namespace are supported."
},
"resourceFieldRef": {
"$ref": "v1.ResourceFieldSelector",
"description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported."
},
"configMapKeyRef": {
"$ref": "v1.ConfigMapKeySelector",
"description": "Selects a key of a ConfigMap."

View File

@ -2754,6 +2754,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resourceFieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_resourcefieldselector">v1.ResourceFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">configMapKeyRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a key of a ConfigMap.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
@ -3198,6 +3205,54 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_resourcefieldselector">v1.ResourceFieldSelector</h3>
<div class="paragraph">
<p>ResourceFieldSelector represents container resources (cpu, memory) and their output format</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">containerName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Container name: required for volumes, optional for env vars</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resource</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: resource to select</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">divisor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the output format of the exposed resources, defaults to "1"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_probe">v1.Probe</h3>
@ -3546,10 +3601,17 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_objectfieldselector">v1.ObjectFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resourceFieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_resourcefieldselector">v1.ResourceFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
@ -4034,7 +4096,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-05-21 03:08:23 UTC
Last updated 2016-05-24 11:53:33 UTC
</div>
</div>
</body>

View File

@ -1342,47 +1342,6 @@ Examples:<br>
<div class="sect2">
<h3 id="__versioned_event">*versioned.Event</h3>
</div>
<div class="sect2">
<h3 id="_v1_capabilities">v1.Capabilities</h3>
<div class="paragraph">
<p>Adds and removes POSIX capabilities from running containers.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">add</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Added capabilities</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_capability">v1.Capability</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">drop</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Removed capabilities</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_capability">v1.Capability</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1beta1_jobstatus">v1beta1.JobStatus</h3>
@ -1452,6 +1411,47 @@ Examples:<br>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_capabilities">v1.Capabilities</h3>
<div class="paragraph">
<p>Adds and removes POSIX capabilities from running containers.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">add</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Added capabilities</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_capability">v1.Capability</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">drop</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Removed capabilities</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_capability">v1.Capability</a> array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_localobjectreference">v1.LocalObjectReference</h3>
@ -2345,6 +2345,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resourceFieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_resourcefieldselector">v1.ResourceFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">configMapKeyRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a key of a ConfigMap.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
@ -2940,6 +2947,54 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_resourcefieldselector">v1.ResourceFieldSelector</h3>
<div class="paragraph">
<p>ResourceFieldSelector represents container resources (cpu, memory) and their output format</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">containerName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Container name: required for volumes, optional for env vars</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resource</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: resource to select</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">divisor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the output format of the exposed resources, defaults to "1"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_probe">v1.Probe</h3>
@ -3288,10 +3343,17 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_objectfieldselector">v1.ObjectFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resourceFieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_resourcefieldselector">v1.ResourceFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
@ -6024,7 +6086,7 @@ Both these may change in the future. Incoming requests are matched against the h
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-05-21 03:08:18 UTC
Last updated 2016-05-24 11:53:27 UTC
</div>
</div>
</body>

View File

@ -2952,6 +2952,13 @@ The resulting set of endpoints can be viewed as:<br>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resourceFieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_resourcefieldselector">v1.ResourceFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">configMapKeyRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a key of a ConfigMap.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
@ -3627,6 +3634,54 @@ The resulting set of endpoints can be viewed as:<br>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_resourcefieldselector">v1.ResourceFieldSelector</h3>
<div class="paragraph">
<p>ResourceFieldSelector represents container resources (cpu, memory) and their output format</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
<col style="width:20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Schema</th>
<th class="tableblock halign-left valign-top">Default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">containerName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Container name: required for volumes, optional for env vars</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resource</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: resource to select</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">divisor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies the output format of the exposed resources, defaults to "1"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_v1_probe">v1.Probe</h3>
@ -4092,10 +4147,17 @@ The resulting set of endpoints can be viewed as:<br>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_objectfieldselector">v1.ObjectFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resourceFieldRef</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_v1_resourcefieldselector">v1.ResourceFieldSelector</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
@ -7922,7 +7984,7 @@ The resulting set of endpoints can be viewed as:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2016-05-21 03:08:11 UTC
Last updated 2016-05-24 11:53:20 UTC
</div>
</div>
</body>

View File

@ -154,6 +154,7 @@ func init() {
DeepCopy_api_ReplicationControllerList,
DeepCopy_api_ReplicationControllerSpec,
DeepCopy_api_ReplicationControllerStatus,
DeepCopy_api_ResourceFieldSelector,
DeepCopy_api_ResourceQuota,
DeepCopy_api_ResourceQuotaList,
DeepCopy_api_ResourceQuotaSpec,
@ -666,9 +667,24 @@ func DeepCopy_api_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *convers
func DeepCopy_api_DownwardAPIVolumeFile(in DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, c *conversion.Cloner) error {
out.Path = in.Path
if err := DeepCopy_api_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil {
if in.FieldRef != nil {
in, out := in.FieldRef, &out.FieldRef
*out = new(ObjectFieldSelector)
if err := DeepCopy_api_ObjectFieldSelector(*in, *out, c); err != nil {
return err
}
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(ResourceFieldSelector)
if err := DeepCopy_api_ResourceFieldSelector(*in, *out, c); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
return nil
}
@ -818,6 +834,15 @@ func DeepCopy_api_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(ResourceFieldSelector)
if err := DeepCopy_api_ResourceFieldSelector(*in, *out, c); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
if in.ConfigMapKeyRef != nil {
in, out := in.ConfigMapKeyRef, &out.ConfigMapKeyRef
*out = new(ConfigMapKeySelector)
@ -2572,6 +2597,15 @@ func DeepCopy_api_ReplicationControllerStatus(in ReplicationControllerStatus, ou
return nil
}
func DeepCopy_api_ResourceFieldSelector(in ResourceFieldSelector, out *ResourceFieldSelector, c *conversion.Cloner) error {
out.ContainerName = in.ContainerName
out.Resource = in.Resource
if err := resource.DeepCopy_resource_Quantity(in.Divisor, &out.Divisor, c); err != nil {
return err
}
return nil
}
func DeepCopy_api_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *conversion.Cloner) error {
if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err

View File

@ -243,6 +243,7 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source)
func(m *api.DownwardAPIVolumeFile, c fuzz.Continue) {
m.Path = c.RandString()
versions := []string{"v1"}
m.FieldRef = &api.ObjectFieldSelector{}
m.FieldRef.APIVersion = versions[c.Rand.Intn(len(versions))]
m.FieldRef.FieldPath = c.RandString()
},

View File

@ -13445,14 +13445,16 @@ func (x *DownwardAPIVolumeFile) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [2]bool
var yyq2 [3]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[1] = x.FieldRef != nil
yyq2[2] = x.ResourceFieldRef != nil
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(2)
r.EncodeArrayStart(3)
} else {
yynn2 = 2
yynn2 = 1
for _, b := range yyq2 {
if b {
yynn2++
@ -13482,14 +13484,49 @@ func (x *DownwardAPIVolumeFile) CodecEncodeSelf(e *codec1978.Encoder) {
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yy7 := &x.FieldRef
yy7.CodecEncodeSelf(e)
if yyq2[1] {
if x.FieldRef == nil {
r.EncodeNil()
} else {
x.FieldRef.CodecEncodeSelf(e)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[1] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("fieldRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yy9 := &x.FieldRef
yy9.CodecEncodeSelf(e)
if x.FieldRef == nil {
r.EncodeNil()
} else {
x.FieldRef.CodecEncodeSelf(e)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("resourceFieldRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
@ -13560,10 +13597,25 @@ func (x *DownwardAPIVolumeFile) codecDecodeSelfFromMap(l int, d *codec1978.Decod
}
case "fieldRef":
if r.TryDecodeAsNil() {
x.FieldRef = ObjectFieldSelector{}
if x.FieldRef != nil {
x.FieldRef = nil
}
} else {
yyv5 := &x.FieldRef
yyv5.CodecDecodeSelf(d)
if x.FieldRef == nil {
x.FieldRef = new(ObjectFieldSelector)
}
x.FieldRef.CodecDecodeSelf(d)
}
case "resourceFieldRef":
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
default:
z.DecStructFieldNotFound(-1, yys3)
@ -13576,16 +13628,16 @@ func (x *DownwardAPIVolumeFile) codecDecodeSelfFromArray(l int, d *codec1978.Dec
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj6 int
var yyb6 bool
var yyhl6 bool = l >= 0
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
var yyj7 int
var yyb7 bool
var yyhl7 bool = l >= 0
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb6 = r.CheckBreak()
yyb7 = r.CheckBreak()
}
if yyb6 {
if yyb7 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -13595,35 +13647,60 @@ func (x *DownwardAPIVolumeFile) codecDecodeSelfFromArray(l int, d *codec1978.Dec
} else {
x.Path = string(r.DecodeString())
}
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb6 = r.CheckBreak()
yyb7 = r.CheckBreak()
}
if yyb6 {
if yyb7 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.FieldRef = ObjectFieldSelector{}
if x.FieldRef != nil {
x.FieldRef = nil
}
} else {
yyv8 := &x.FieldRef
yyv8.CodecDecodeSelf(d)
if x.FieldRef == nil {
x.FieldRef = new(ObjectFieldSelector)
}
x.FieldRef.CodecDecodeSelf(d)
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb7 = r.CheckBreak()
}
if yyb7 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
for {
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb6 = r.CheckBreak()
yyb7 = r.CheckBreak()
}
if yyb6 {
if yyb7 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj6-1, "")
z.DecStructFieldNotFound(yyj7-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
@ -15445,15 +15522,16 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [3]bool
var yyq2 [4]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.FieldRef != nil
yyq2[1] = x.ConfigMapKeyRef != nil
yyq2[2] = x.SecretKeyRef != nil
yyq2[1] = x.ResourceFieldRef != nil
yyq2[2] = x.ConfigMapKeyRef != nil
yyq2[3] = x.SecretKeyRef != nil
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(3)
r.EncodeArrayStart(4)
} else {
yynn2 = 0
for _, b := range yyq2 {
@ -15490,6 +15568,29 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[1] {
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[1] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("resourceFieldRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if x.ConfigMapKeyRef == nil {
r.EncodeNil()
} else {
@ -15499,7 +15600,7 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
r.EncodeNil()
}
} else {
if yyq2[1] {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("configMapKeyRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
@ -15512,7 +15613,7 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if yyq2[3] {
if x.SecretKeyRef == nil {
r.EncodeNil()
} else {
@ -15522,7 +15623,7 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
r.EncodeNil()
}
} else {
if yyq2[2] {
if yyq2[3] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("secretKeyRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
@ -15605,6 +15706,17 @@ func (x *EnvVarSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
}
x.FieldRef.CodecDecodeSelf(d)
}
case "resourceFieldRef":
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
case "configMapKeyRef":
if r.TryDecodeAsNil() {
if x.ConfigMapKeyRef != nil {
@ -15638,16 +15750,16 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj7 int
var yyb7 bool
var yyhl7 bool = l >= 0
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
var yyj8 int
var yyb8 bool
var yyhl8 bool = l >= 0
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -15662,13 +15774,34 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
}
x.FieldRef.CodecDecodeSelf(d)
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -15683,13 +15816,13 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
}
x.ConfigMapKeyRef.CodecDecodeSelf(d)
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -15705,17 +15838,17 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
x.SecretKeyRef.CodecDecodeSelf(d)
}
for {
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj7-1, "")
z.DecStructFieldNotFound(yyj8-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
@ -15923,6 +16056,290 @@ func (x *ObjectFieldSelector) codecDecodeSelfFromArray(l int, d *codec1978.Decod
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *ResourceFieldSelector) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [3]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.ContainerName != ""
yyq2[2] = true
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(3)
} else {
yynn2 = 1
for _, b := range yyq2 {
if b {
yynn2++
}
}
r.EncodeMapStart(yynn2)
yynn2 = 0
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[0] {
yym4 := z.EncBinary()
_ = yym4
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.ContainerName))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[0] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("containerName"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym5 := z.EncBinary()
_ = yym5
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.ContainerName))
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Resource))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("resource"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Resource))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
yy10 := &x.Divisor
yym11 := z.EncBinary()
_ = yym11
if false {
} else if z.HasExtensions() && z.EncExt(yy10) {
} else if !yym11 && z.IsJSONHandle() {
z.EncJSONMarshal(yy10)
} else {
z.EncFallback(yy10)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("divisor"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yy12 := &x.Divisor
yym13 := z.EncBinary()
_ = yym13
if false {
} else if z.HasExtensions() && z.EncExt(yy12) {
} else if !yym13 && z.IsJSONHandle() {
z.EncJSONMarshal(yy12)
} else {
z.EncFallback(yy12)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
z.EncSendContainerState(codecSelfer_containerMapEnd1234)
}
}
}
}
func (x *ResourceFieldSelector) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym1 := z.DecBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeMap1234 {
yyl2 := r.ReadMapStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
} else if yyct2 == codecSelferValueTypeArray1234 {
yyl2 := r.ReadArrayStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
x.codecDecodeSelfFromArray(yyl2, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
}
}
}
func (x *ResourceFieldSelector) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys3Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys3Slc
var yyhl3 bool = l >= 0
for yyj3 := 0; ; yyj3++ {
if yyhl3 {
if yyj3 >= l {
break
}
} else {
if r.CheckBreak() {
break
}
}
z.DecSendContainerState(codecSelfer_containerMapKey1234)
yys3Slc = r.DecodeBytes(yys3Slc, true, true)
yys3 := string(yys3Slc)
z.DecSendContainerState(codecSelfer_containerMapValue1234)
switch yys3 {
case "containerName":
if r.TryDecodeAsNil() {
x.ContainerName = ""
} else {
x.ContainerName = string(r.DecodeString())
}
case "resource":
if r.TryDecodeAsNil() {
x.Resource = ""
} else {
x.Resource = string(r.DecodeString())
}
case "divisor":
if r.TryDecodeAsNil() {
x.Divisor = pkg3_resource.Quantity{}
} else {
yyv6 := &x.Divisor
yym7 := z.DecBinary()
_ = yym7
if false {
} else if z.HasExtensions() && z.DecExt(yyv6) {
} else if !yym7 && z.IsJSONHandle() {
z.DecJSONUnmarshal(yyv6)
} else {
z.DecFallback(yyv6, false)
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
}
func (x *ResourceFieldSelector) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj8 int
var yyb8 bool
var yyhl8 bool = l >= 0
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.ContainerName = ""
} else {
x.ContainerName = string(r.DecodeString())
}
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Resource = ""
} else {
x.Resource = string(r.DecodeString())
}
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Divisor = pkg3_resource.Quantity{}
} else {
yyv11 := &x.Divisor
yym12 := z.DecBinary()
_ = yym12
if false {
} else if z.HasExtensions() && z.DecExt(yyv11) {
} else if !yym12 && z.IsJSONHandle() {
z.DecJSONUnmarshal(yyv11)
} else {
z.DecFallback(yyv11, false)
}
}
for {
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj8-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *ConfigMapKeySelector) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
@ -52961,7 +53378,7 @@ func (x codecSelfer1234) decSliceDownwardAPIVolumeFile(v *[]DownwardAPIVolumeFil
yyrg1 := len(yyv1) > 0
yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 48)
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 32)
if yyrt1 {
if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1]

View File

@ -706,7 +706,10 @@ type DownwardAPIVolumeFile struct {
// Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'
Path string `json:"path"`
// Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
FieldRef ObjectFieldSelector `json:"fieldRef"`
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty"`
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty"`
}
// AzureFile represents an Azure File Service mount on the host and bind mount to the pod.
@ -811,6 +814,9 @@ type EnvVar struct {
type EnvVarSource struct {
// Selects a field of the pod; only name and namespace are supported.
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty"`
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty"`
// Selects a key of a ConfigMap.
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
// Selects a key of a secret in the pod's namespace.
@ -827,6 +833,16 @@ type ObjectFieldSelector struct {
FieldPath string `json:"fieldPath"`
}
// ResourceFieldSelector represents container resources (cpu, memory) and their output format
type ResourceFieldSelector struct {
// Container name: required for volumes, optional for env vars
ContainerName string `json:"containerName,omitempty"`
// Required: resource to select
Resource string `json:"resource"`
// Specifies the output format of the exposed resources, defaults to "1"
Divisor resource.Quantity `json:"divisor,omitempty"`
}
// Selects a key from a ConfigMap.
type ConfigMapKeySelector struct {
// The ConfigMap to select from.

View File

@ -269,6 +269,8 @@ func init() {
Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec,
Convert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStatus,
Convert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus,
Convert_v1_ResourceFieldSelector_To_api_ResourceFieldSelector,
Convert_api_ResourceFieldSelector_To_v1_ResourceFieldSelector,
Convert_v1_ResourceQuota_To_api_ResourceQuota,
Convert_api_ResourceQuota_To_v1_ResourceQuota,
Convert_v1_ResourceQuotaList_To_api_ResourceQuotaList,
@ -1442,9 +1444,24 @@ func Convert_api_DeleteOptions_To_v1_DeleteOptions(in *api.DeleteOptions, out *D
func autoConvert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardAPIVolumeFile, out *api.DownwardAPIVolumeFile, s conversion.Scope) error {
out.Path = in.Path
if err := Convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil {
if in.FieldRef != nil {
in, out := &in.FieldRef, &out.FieldRef
*out = new(api.ObjectFieldSelector)
if err := Convert_v1_ObjectFieldSelector_To_api_ObjectFieldSelector(*in, *out, s); err != nil {
return err
}
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := &in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(api.ResourceFieldSelector)
if err := Convert_v1_ResourceFieldSelector_To_api_ResourceFieldSelector(*in, *out, s); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
return nil
}
@ -1454,9 +1471,24 @@ func Convert_v1_DownwardAPIVolumeFile_To_api_DownwardAPIVolumeFile(in *DownwardA
func autoConvert_api_DownwardAPIVolumeFile_To_v1_DownwardAPIVolumeFile(in *api.DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, s conversion.Scope) error {
out.Path = in.Path
if err := Convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(&in.FieldRef, &out.FieldRef, s); err != nil {
if in.FieldRef != nil {
in, out := &in.FieldRef, &out.FieldRef
*out = new(ObjectFieldSelector)
if err := Convert_api_ObjectFieldSelector_To_v1_ObjectFieldSelector(*in, *out, s); err != nil {
return err
}
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := &in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(ResourceFieldSelector)
if err := Convert_api_ResourceFieldSelector_To_v1_ResourceFieldSelector(*in, *out, s); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
return nil
}
@ -1811,6 +1843,15 @@ func autoConvert_v1_EnvVarSource_To_api_EnvVarSource(in *EnvVarSource, out *api.
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := &in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(api.ResourceFieldSelector)
if err := Convert_v1_ResourceFieldSelector_To_api_ResourceFieldSelector(*in, *out, s); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
if in.ConfigMapKeyRef != nil {
in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef
*out = new(api.ConfigMapKeySelector)
@ -1846,6 +1887,15 @@ func autoConvert_api_EnvVarSource_To_v1_EnvVarSource(in *api.EnvVarSource, out *
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := &in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(ResourceFieldSelector)
if err := Convert_api_ResourceFieldSelector_To_v1_ResourceFieldSelector(*in, *out, s); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
if in.ConfigMapKeyRef != nil {
in, out := &in.ConfigMapKeyRef, &out.ConfigMapKeyRef
*out = new(ConfigMapKeySelector)
@ -5646,6 +5696,32 @@ func Convert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(i
return autoConvert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStatus(in, out, s)
}
func autoConvert_v1_ResourceFieldSelector_To_api_ResourceFieldSelector(in *ResourceFieldSelector, out *api.ResourceFieldSelector, s conversion.Scope) error {
out.ContainerName = in.ContainerName
out.Resource = in.Resource
if err := api.Convert_resource_Quantity_To_resource_Quantity(&in.Divisor, &out.Divisor, s); err != nil {
return err
}
return nil
}
func Convert_v1_ResourceFieldSelector_To_api_ResourceFieldSelector(in *ResourceFieldSelector, out *api.ResourceFieldSelector, s conversion.Scope) error {
return autoConvert_v1_ResourceFieldSelector_To_api_ResourceFieldSelector(in, out, s)
}
func autoConvert_api_ResourceFieldSelector_To_v1_ResourceFieldSelector(in *api.ResourceFieldSelector, out *ResourceFieldSelector, s conversion.Scope) error {
out.ContainerName = in.ContainerName
out.Resource = in.Resource
if err := api.Convert_resource_Quantity_To_resource_Quantity(&in.Divisor, &out.Divisor, s); err != nil {
return err
}
return nil
}
func Convert_api_ResourceFieldSelector_To_v1_ResourceFieldSelector(in *api.ResourceFieldSelector, out *ResourceFieldSelector, s conversion.Scope) error {
return autoConvert_api_ResourceFieldSelector_To_v1_ResourceFieldSelector(in, out, s)
}
func autoConvert_v1_ResourceQuota_To_api_ResourceQuota(in *ResourceQuota, out *api.ResourceQuota, s conversion.Scope) error {
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
return err

View File

@ -151,6 +151,7 @@ func init() {
DeepCopy_v1_ReplicationControllerList,
DeepCopy_v1_ReplicationControllerSpec,
DeepCopy_v1_ReplicationControllerStatus,
DeepCopy_v1_ResourceFieldSelector,
DeepCopy_v1_ResourceQuota,
DeepCopy_v1_ResourceQuotaList,
DeepCopy_v1_ResourceQuotaSpec,
@ -644,9 +645,24 @@ func DeepCopy_v1_DeleteOptions(in DeleteOptions, out *DeleteOptions, c *conversi
func DeepCopy_v1_DownwardAPIVolumeFile(in DownwardAPIVolumeFile, out *DownwardAPIVolumeFile, c *conversion.Cloner) error {
out.Path = in.Path
if err := DeepCopy_v1_ObjectFieldSelector(in.FieldRef, &out.FieldRef, c); err != nil {
if in.FieldRef != nil {
in, out := in.FieldRef, &out.FieldRef
*out = new(ObjectFieldSelector)
if err := DeepCopy_v1_ObjectFieldSelector(*in, *out, c); err != nil {
return err
}
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(ResourceFieldSelector)
if err := DeepCopy_v1_ResourceFieldSelector(*in, *out, c); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
return nil
}
@ -796,6 +812,15 @@ func DeepCopy_v1_EnvVarSource(in EnvVarSource, out *EnvVarSource, c *conversion.
} else {
out.FieldRef = nil
}
if in.ResourceFieldRef != nil {
in, out := in.ResourceFieldRef, &out.ResourceFieldRef
*out = new(ResourceFieldSelector)
if err := DeepCopy_v1_ResourceFieldSelector(*in, *out, c); err != nil {
return err
}
} else {
out.ResourceFieldRef = nil
}
if in.ConfigMapKeyRef != nil {
in, out := in.ConfigMapKeyRef, &out.ConfigMapKeyRef
*out = new(ConfigMapKeySelector)
@ -2526,6 +2551,15 @@ func DeepCopy_v1_ReplicationControllerStatus(in ReplicationControllerStatus, out
return nil
}
func DeepCopy_v1_ResourceFieldSelector(in ResourceFieldSelector, out *ResourceFieldSelector, c *conversion.Cloner) error {
out.ContainerName = in.ContainerName
out.Resource = in.Resource
if err := resource.DeepCopy_resource_Quantity(in.Divisor, &out.Divisor, c); err != nil {
return err
}
return nil
}
func DeepCopy_v1_ResourceQuota(in ResourceQuota, out *ResourceQuota, c *conversion.Cloner) error {
if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err

File diff suppressed because it is too large Load Diff

View File

@ -504,6 +504,10 @@ message DownwardAPIVolumeFile {
// Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
optional ObjectFieldSelector fieldRef = 2;
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
optional ResourceFieldSelector resourceFieldRef = 3;
}
// DownwardAPIVolumeSource represents a volume containing downward API info.
@ -641,11 +645,15 @@ message EnvVarSource {
// Selects a field of the pod; only name and namespace are supported.
optional ObjectFieldSelector fieldRef = 1;
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
optional ResourceFieldSelector resourceFieldRef = 2;
// Selects a key of a ConfigMap.
optional ConfigMapKeySelector configMapKeyRef = 2;
optional ConfigMapKeySelector configMapKeyRef = 3;
// Selects a key of a secret in the pod's namespace
optional SecretKeySelector secretKeyRef = 3;
optional SecretKeySelector secretKeyRef = 4;
}
// Event is a report of an event somewhere in the cluster.
@ -2345,6 +2353,18 @@ message ReplicationControllerStatus {
optional int64 observedGeneration = 3;
}
// ResourceFieldSelector represents container resources (cpu, memory) and their output format
message ResourceFieldSelector {
// Container name: required for volumes, optional for env vars
optional string containerName = 1;
// Required: resource to select
optional string resource = 2;
// Specifies the output format of the exposed resources, defaults to "1"
optional k8s.io.kubernetes.pkg.api.resource.Quantity divisor = 3;
}
// ResourceQuota sets aggregate quota restrictions enforced per namespace
message ResourceQuota {
// Standard object's metadata.

View File

@ -15048,15 +15048,16 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [3]bool
var yyq2 [4]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.FieldRef != nil
yyq2[1] = x.ConfigMapKeyRef != nil
yyq2[2] = x.SecretKeyRef != nil
yyq2[1] = x.ResourceFieldRef != nil
yyq2[2] = x.ConfigMapKeyRef != nil
yyq2[3] = x.SecretKeyRef != nil
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(3)
r.EncodeArrayStart(4)
} else {
yynn2 = 0
for _, b := range yyq2 {
@ -15093,6 +15094,29 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[1] {
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[1] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("resourceFieldRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if x.ConfigMapKeyRef == nil {
r.EncodeNil()
} else {
@ -15102,7 +15126,7 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
r.EncodeNil()
}
} else {
if yyq2[1] {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("configMapKeyRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
@ -15115,7 +15139,7 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if yyq2[3] {
if x.SecretKeyRef == nil {
r.EncodeNil()
} else {
@ -15125,7 +15149,7 @@ func (x *EnvVarSource) CodecEncodeSelf(e *codec1978.Encoder) {
r.EncodeNil()
}
} else {
if yyq2[2] {
if yyq2[3] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("secretKeyRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
@ -15208,6 +15232,17 @@ func (x *EnvVarSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
}
x.FieldRef.CodecDecodeSelf(d)
}
case "resourceFieldRef":
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
case "configMapKeyRef":
if r.TryDecodeAsNil() {
if x.ConfigMapKeyRef != nil {
@ -15241,16 +15276,16 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj7 int
var yyb7 bool
var yyhl7 bool = l >= 0
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
var yyj8 int
var yyb8 bool
var yyhl8 bool = l >= 0
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -15265,13 +15300,34 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
}
x.FieldRef.CodecDecodeSelf(d)
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -15286,13 +15342,13 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
}
x.ConfigMapKeyRef.CodecDecodeSelf(d)
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -15308,17 +15364,17 @@ func (x *EnvVarSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
x.SecretKeyRef.CodecDecodeSelf(d)
}
for {
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb7 = r.CheckBreak()
yyb8 = r.CheckBreak()
}
if yyb7 {
if yyb8 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj7-1, "")
z.DecStructFieldNotFound(yyj8-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
@ -15533,6 +15589,290 @@ func (x *ObjectFieldSelector) codecDecodeSelfFromArray(l int, d *codec1978.Decod
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *ResourceFieldSelector) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [3]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.ContainerName != ""
yyq2[2] = true
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(3)
} else {
yynn2 = 1
for _, b := range yyq2 {
if b {
yynn2++
}
}
r.EncodeMapStart(yynn2)
yynn2 = 0
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[0] {
yym4 := z.EncBinary()
_ = yym4
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.ContainerName))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[0] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("containerName"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym5 := z.EncBinary()
_ = yym5
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.ContainerName))
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Resource))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("resource"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Resource))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
yy10 := &x.Divisor
yym11 := z.EncBinary()
_ = yym11
if false {
} else if z.HasExtensions() && z.EncExt(yy10) {
} else if !yym11 && z.IsJSONHandle() {
z.EncJSONMarshal(yy10)
} else {
z.EncFallback(yy10)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("divisor"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yy12 := &x.Divisor
yym13 := z.EncBinary()
_ = yym13
if false {
} else if z.HasExtensions() && z.EncExt(yy12) {
} else if !yym13 && z.IsJSONHandle() {
z.EncJSONMarshal(yy12)
} else {
z.EncFallback(yy12)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
z.EncSendContainerState(codecSelfer_containerMapEnd1234)
}
}
}
}
func (x *ResourceFieldSelector) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym1 := z.DecBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeMap1234 {
yyl2 := r.ReadMapStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
} else if yyct2 == codecSelferValueTypeArray1234 {
yyl2 := r.ReadArrayStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
x.codecDecodeSelfFromArray(yyl2, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
}
}
}
func (x *ResourceFieldSelector) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys3Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys3Slc
var yyhl3 bool = l >= 0
for yyj3 := 0; ; yyj3++ {
if yyhl3 {
if yyj3 >= l {
break
}
} else {
if r.CheckBreak() {
break
}
}
z.DecSendContainerState(codecSelfer_containerMapKey1234)
yys3Slc = r.DecodeBytes(yys3Slc, true, true)
yys3 := string(yys3Slc)
z.DecSendContainerState(codecSelfer_containerMapValue1234)
switch yys3 {
case "containerName":
if r.TryDecodeAsNil() {
x.ContainerName = ""
} else {
x.ContainerName = string(r.DecodeString())
}
case "resource":
if r.TryDecodeAsNil() {
x.Resource = ""
} else {
x.Resource = string(r.DecodeString())
}
case "divisor":
if r.TryDecodeAsNil() {
x.Divisor = pkg3_resource.Quantity{}
} else {
yyv6 := &x.Divisor
yym7 := z.DecBinary()
_ = yym7
if false {
} else if z.HasExtensions() && z.DecExt(yyv6) {
} else if !yym7 && z.IsJSONHandle() {
z.DecJSONUnmarshal(yyv6)
} else {
z.DecFallback(yyv6, false)
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
}
func (x *ResourceFieldSelector) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj8 int
var yyb8 bool
var yyhl8 bool = l >= 0
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.ContainerName = ""
} else {
x.ContainerName = string(r.DecodeString())
}
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Resource = ""
} else {
x.Resource = string(r.DecodeString())
}
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Divisor = pkg3_resource.Quantity{}
} else {
yyv11 := &x.Divisor
yym12 := z.DecBinary()
_ = yym12
if false {
} else if z.HasExtensions() && z.DecExt(yyv11) {
} else if !yym12 && z.IsJSONHandle() {
z.DecJSONUnmarshal(yyv11)
} else {
z.DecFallback(yyv11, false)
}
}
for {
yyj8++
if yyhl8 {
yyb8 = yyj8 > l
} else {
yyb8 = r.CheckBreak()
}
if yyb8 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj8-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *ConfigMapKeySelector) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
@ -51106,14 +51446,16 @@ func (x *DownwardAPIVolumeFile) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [2]bool
var yyq2 [3]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[1] = x.FieldRef != nil
yyq2[2] = x.ResourceFieldRef != nil
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(2)
r.EncodeArrayStart(3)
} else {
yynn2 = 2
yynn2 = 1
for _, b := range yyq2 {
if b {
yynn2++
@ -51143,14 +51485,49 @@ func (x *DownwardAPIVolumeFile) CodecEncodeSelf(e *codec1978.Encoder) {
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yy7 := &x.FieldRef
yy7.CodecEncodeSelf(e)
if yyq2[1] {
if x.FieldRef == nil {
r.EncodeNil()
} else {
x.FieldRef.CodecEncodeSelf(e)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[1] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("fieldRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yy9 := &x.FieldRef
yy9.CodecEncodeSelf(e)
if x.FieldRef == nil {
r.EncodeNil()
} else {
x.FieldRef.CodecEncodeSelf(e)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("resourceFieldRef"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.ResourceFieldRef == nil {
r.EncodeNil()
} else {
x.ResourceFieldRef.CodecEncodeSelf(e)
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
@ -51221,10 +51598,25 @@ func (x *DownwardAPIVolumeFile) codecDecodeSelfFromMap(l int, d *codec1978.Decod
}
case "fieldRef":
if r.TryDecodeAsNil() {
x.FieldRef = ObjectFieldSelector{}
if x.FieldRef != nil {
x.FieldRef = nil
}
} else {
yyv5 := &x.FieldRef
yyv5.CodecDecodeSelf(d)
if x.FieldRef == nil {
x.FieldRef = new(ObjectFieldSelector)
}
x.FieldRef.CodecDecodeSelf(d)
}
case "resourceFieldRef":
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
default:
z.DecStructFieldNotFound(-1, yys3)
@ -51237,16 +51629,16 @@ func (x *DownwardAPIVolumeFile) codecDecodeSelfFromArray(l int, d *codec1978.Dec
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj6 int
var yyb6 bool
var yyhl6 bool = l >= 0
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
var yyj7 int
var yyb7 bool
var yyhl7 bool = l >= 0
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb6 = r.CheckBreak()
yyb7 = r.CheckBreak()
}
if yyb6 {
if yyb7 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@ -51256,35 +51648,60 @@ func (x *DownwardAPIVolumeFile) codecDecodeSelfFromArray(l int, d *codec1978.Dec
} else {
x.Path = string(r.DecodeString())
}
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb6 = r.CheckBreak()
yyb7 = r.CheckBreak()
}
if yyb6 {
if yyb7 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.FieldRef = ObjectFieldSelector{}
if x.FieldRef != nil {
x.FieldRef = nil
}
} else {
yyv8 := &x.FieldRef
yyv8.CodecDecodeSelf(d)
if x.FieldRef == nil {
x.FieldRef = new(ObjectFieldSelector)
}
x.FieldRef.CodecDecodeSelf(d)
}
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb7 = r.CheckBreak()
}
if yyb7 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
if x.ResourceFieldRef != nil {
x.ResourceFieldRef = nil
}
} else {
if x.ResourceFieldRef == nil {
x.ResourceFieldRef = new(ResourceFieldSelector)
}
x.ResourceFieldRef.CodecDecodeSelf(d)
}
for {
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
yyj7++
if yyhl7 {
yyb7 = yyj7 > l
} else {
yyb6 = r.CheckBreak()
yyb7 = r.CheckBreak()
}
if yyb6 {
if yyb7 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj6-1, "")
z.DecStructFieldNotFound(yyj7-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
@ -58597,7 +59014,7 @@ func (x codecSelfer1234) decSliceDownwardAPIVolumeFile(v *[]DownwardAPIVolumeFil
yyrg1 := len(yyv1) > 0
yyv21 := yyv1
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 48)
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 32)
if yyrt1 {
if yyrl1 <= cap(yyv1) {
yyv1 = yyv1[:yyrl1]

View File

@ -938,10 +938,13 @@ type EnvVar struct {
type EnvVarSource struct {
// Selects a field of the pod; only name and namespace are supported.
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"`
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" protobuf:"bytes,2,opt,name=resourceFieldRef"`
// Selects a key of a ConfigMap.
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty" protobuf:"bytes,2,opt,name=configMapKeyRef"`
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty" protobuf:"bytes,3,opt,name=configMapKeyRef"`
// Selects a key of a secret in the pod's namespace
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty" protobuf:"bytes,3,opt,name=secretKeyRef"`
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty" protobuf:"bytes,4,opt,name=secretKeyRef"`
}
// ObjectFieldSelector selects an APIVersioned field of an object.
@ -952,6 +955,16 @@ type ObjectFieldSelector struct {
FieldPath string `json:"fieldPath" protobuf:"bytes,2,opt,name=fieldPath"`
}
// ResourceFieldSelector represents container resources (cpu, memory) and their output format
type ResourceFieldSelector struct {
// Container name: required for volumes, optional for env vars
ContainerName string `json:"containerName,omitempty" protobuf:"bytes,1,opt,name=containerName"`
// Required: resource to select
Resource string `json:"resource" protobuf:"bytes,2,opt,name=resource"`
// Specifies the output format of the exposed resources, defaults to "1"
Divisor resource.Quantity `json:"divisor,omitempty" protobuf:"bytes,3,opt,name=divisor"`
}
// Selects a key from a ConfigMap.
type ConfigMapKeySelector struct {
// The ConfigMap to select from.
@ -3202,7 +3215,10 @@ type DownwardAPIVolumeFile struct {
// Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'
Path string `json:"path" protobuf:"bytes,1,opt,name=path"`
// Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.
FieldRef ObjectFieldSelector `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"`
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,2,opt,name=fieldRef"`
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" protobuf:"bytes,3,opt,name=resourceFieldRef"`
}
// SecurityContext holds security configuration that will be applied to a container.

View File

@ -310,6 +310,7 @@ var map_DownwardAPIVolumeFile = map[string]string{
"": "DownwardAPIVolumeFile represents information to create the file containing the pod field",
"path": "Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'",
"fieldRef": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.",
"resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.",
}
func (DownwardAPIVolumeFile) SwaggerDoc() map[string]string {
@ -401,6 +402,7 @@ func (EnvVar) SwaggerDoc() map[string]string {
var map_EnvVarSource = map[string]string{
"": "EnvVarSource represents a source for the value of an EnvVar.",
"fieldRef": "Selects a field of the pod; only name and namespace are supported.",
"resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.",
"configMapKeyRef": "Selects a key of a ConfigMap.",
"secretKeyRef": "Selects a key of a secret in the pod's namespace",
}
@ -1394,6 +1396,17 @@ func (ReplicationControllerStatus) SwaggerDoc() map[string]string {
return map_ReplicationControllerStatus
}
var map_ResourceFieldSelector = map[string]string{
"": "ResourceFieldSelector represents container resources (cpu, memory) and their output format",
"containerName": "Container name: required for volumes, optional for env vars",
"resource": "Required: resource to select",
"divisor": "Specifies the output format of the exposed resources, defaults to \"1\"",
}
func (ResourceFieldSelector) SwaggerDoc() map[string]string {
return map_ResourceFieldSelector
}
var map_ResourceQuota = map[string]string{
"": "ResourceQuota sets aggregate quota restrictions enforced per namespace",
"metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata",

View File

@ -702,7 +702,16 @@ func validateDownwardAPIVolumeSource(downwardAPIVolume *api.DownwardAPIVolumeSou
allErrs = append(allErrs, field.Required(fldPath.Child("path"), ""))
}
allErrs = append(allErrs, validateVolumeSourcePath(downwardAPIVolumeFile.Path, fldPath.Child("path"))...)
allErrs = append(allErrs, validateObjectFieldSelector(&downwardAPIVolumeFile.FieldRef, &validDownwardAPIFieldPathExpressions, fldPath.Child("fieldRef"))...)
if downwardAPIVolumeFile.FieldRef != nil {
allErrs = append(allErrs, validateObjectFieldSelector(downwardAPIVolumeFile.FieldRef, &validDownwardAPIFieldPathExpressions, fldPath.Child("fieldRef"))...)
if downwardAPIVolumeFile.ResourceFieldRef != nil {
allErrs = append(allErrs, field.Invalid(fldPath, "resource", "fieldRef and resourceFieldRef can not be specified simultaneously"))
}
} else if downwardAPIVolumeFile.ResourceFieldRef != nil {
allErrs = append(allErrs, validateContainerResourceFieldSelector(downwardAPIVolumeFile.ResourceFieldRef, &validContainerResourceFieldPathExpressions, fldPath.Child("resourceFieldRef"), true)...)
} else {
allErrs = append(allErrs, field.Required(fldPath, "one of fieldRef and resourceFieldRef is required"))
}
}
return allErrs
}
@ -1048,6 +1057,7 @@ func validateEnv(vars []api.EnvVar, fldPath *field.Path) field.ErrorList {
}
var validFieldPathExpressionsEnv = sets.NewString("metadata.name", "metadata.namespace", "status.podIP")
var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "requests.cpu", "requests.memory")
func validateEnvVarValueFrom(ev api.EnvVar, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
@ -1062,6 +1072,10 @@ func validateEnvVarValueFrom(ev api.EnvVar, fldPath *field.Path) field.ErrorList
numSources++
allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldRef, &validFieldPathExpressionsEnv, fldPath.Child("fieldRef"))...)
}
if ev.ValueFrom.ResourceFieldRef != nil {
numSources++
allErrs = append(allErrs, validateContainerResourceFieldSelector(ev.ValueFrom.ResourceFieldRef, &validContainerResourceFieldPathExpressions, fldPath.Child("resourceFieldRef"), false)...)
}
if ev.ValueFrom.ConfigMapKeyRef != nil {
numSources++
allErrs = append(allErrs, validateConfigMapKeySelector(ev.ValueFrom.ConfigMapKeyRef, fldPath.Child("configMapKeyRef"))...)
@ -1101,6 +1115,42 @@ func validateObjectFieldSelector(fs *api.ObjectFieldSelector, expressions *sets.
return allErrs
}
func validateContainerResourceFieldSelector(fs *api.ResourceFieldSelector, expressions *sets.String, fldPath *field.Path, volume bool) field.ErrorList {
allErrs := field.ErrorList{}
if volume && len(fs.ContainerName) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("containerName"), ""))
} else if len(fs.Resource) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("resource"), ""))
} else if !expressions.Has(fs.Resource) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("resource"), fs.Resource, expressions.List()))
}
allErrs = append(allErrs, validateContainerResourceDivisor(fs.Resource, fs.Divisor, fldPath)...)
return allErrs
}
var validContainerResourceDivisorForCPU = sets.NewString("1m", "1")
var validContainerResourceDivisorForMemory = sets.NewString("1m", "1", "1k", "1M", "1G", "1T", "1P", "1E", "1Ki", "1Mi", "1Gi", "1Ti", "1Pi", "1Ei")
func validateContainerResourceDivisor(rName string, divisor resource.Quantity, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
unsetDivisor := resource.Quantity{}
if unsetDivisor.Cmp(divisor) == 0 {
return allErrs
}
switch rName {
case "limits.cpu", "requests.cpu":
if !validContainerResourceDivisorForCPU.Has(divisor.String()) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("divisor"), rName, fmt.Sprintf("only divisor's values 1m and 1 are supported with the cpu resource")))
}
case "limits.memory", "requests.memory":
if !validContainerResourceDivisorForMemory.Has(divisor.String()) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("divisor"), rName, fmt.Sprintf("only divisor's values 1m, 1, 1k, 1M, 1G, 1T, 1P, 1E, 1Ki, 1Mi, 1Gi, 1Ti, 1Pi, 1Ei are supported with the memory resource")))
}
}
return allErrs
}
func validateConfigMapKeySelector(s *api.ConfigMapKeySelector, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

View File

@ -656,30 +656,42 @@ func TestValidateVolumes(t *testing.T) {
{Name: "cinder", VolumeSource: api.VolumeSource{Cinder: &api.CinderVolumeSource{VolumeID: "29ea5088-4f60-4757-962e-dba678767887", FSType: "ext4", ReadOnly: false}}},
{Name: "cephfs", VolumeSource: api.VolumeSource{CephFS: &api.CephFSVolumeSource{Monitors: []string{"foo"}}}},
{Name: "downwardapi", VolumeSource: api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{Items: []api.DownwardAPIVolumeFile{
{Path: "labels", FieldRef: api.ObjectFieldSelector{
{Path: "labels", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}},
{Path: "annotations", FieldRef: api.ObjectFieldSelector{
{Path: "annotations", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.annotations"}},
{Path: "namespace", FieldRef: api.ObjectFieldSelector{
{Path: "namespace", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.namespace"}},
{Path: "name", FieldRef: api.ObjectFieldSelector{
{Path: "name", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.name"}},
{Path: "path/withslash/andslash", FieldRef: api.ObjectFieldSelector{
{Path: "path/withslash/andslash", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}},
{Path: "path/./withdot", FieldRef: api.ObjectFieldSelector{
{Path: "path/./withdot", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}},
{Path: "path/with..dot", FieldRef: api.ObjectFieldSelector{
{Path: "path/with..dot", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}},
{Path: "second-level-dirent-can-have/..dot", FieldRef: api.ObjectFieldSelector{
{Path: "second-level-dirent-can-have/..dot", FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}},
{Path: "cpu_limit", ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "test-container",
Resource: "limits.cpu"}},
{Path: "cpu_request", ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "test-container",
Resource: "requests.cpu"}},
{Path: "memory_limit", ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "test-container",
Resource: "limits.memory"}},
{Path: "memory_request", ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "test-container",
Resource: "requests.memory"}},
}}}},
{Name: "fc", VolumeSource: api.VolumeSource{FC: &api.FCVolumeSource{TargetWWNs: []string{"some_wwn"}, Lun: &lun, FSType: "ext4", ReadOnly: false}}},
{Name: "flexvolume", VolumeSource: api.VolumeSource{FlexVolume: &api.FlexVolumeSource{Driver: "kubernetes.io/blue", FSType: "ext4"}}},
@ -705,30 +717,38 @@ func TestValidateVolumes(t *testing.T) {
containsDots := api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{Repository: "foo", Directory: "dots/../bar"}}
absPath := api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{Repository: "foo", Directory: "/abstarget"}}
emptyPathName := api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{Items: []api.DownwardAPIVolumeFile{{Path: "",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}}},
}}
absolutePathName := api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{Items: []api.DownwardAPIVolumeFile{{Path: "/absolutepath",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}}},
}}
dotDotInPath := api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{Items: []api.DownwardAPIVolumeFile{{Path: "../../passwd",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}}},
}}
dotDotPathName := api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{Items: []api.DownwardAPIVolumeFile{{Path: "..badFileName",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}}},
}}
dotDotFirstLevelDirent := api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{Items: []api.DownwardAPIVolumeFile{{Path: "..badDirName/goodFileName",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"}}},
}}
fieldRefandResourceFieldRef := api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{Items: []api.DownwardAPIVolumeFile{{Path: "test",
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels"},
ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "test-container",
Resource: "requests.memory"}}},
}}
zeroWWN := api.VolumeSource{FC: &api.FCVolumeSource{TargetWWNs: []string{}, Lun: &lun, FSType: "ext4", ReadOnly: false}}
emptyLun := api.VolumeSource{FC: &api.FCVolumeSource{TargetWWNs: []string{"wwn"}, Lun: nil, FSType: "ext4", ReadOnly: false}}
slashInName := api.VolumeSource{Flocker: &api.FlockerVolumeSource{DatasetName: "foo/bar"}}
@ -865,6 +885,11 @@ func TestValidateVolumes(t *testing.T) {
field.ErrorTypeRequired,
"azureFile.shareName", "",
},
"fieldRef and ResourceFieldRef together": {
[]api.Volume{{Name: "testvolume", VolumeSource: fieldRefandResourceFieldRef}},
field.ErrorTypeInvalid,
"downwardAPI", "fieldRef and resourceFieldRef can not be specified simultaneously",
},
}
for k, v := range errorCases {
_, errs := validateVolumes(v.V, field.NewPath("field"))

View File

@ -18,8 +18,12 @@ package fieldpath
import (
"fmt"
"math"
"strconv"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/resource"
)
// formatMap formats map[string]string to a string.
@ -58,3 +62,61 @@ func ExtractFieldPathAsString(obj interface{}, fieldPath string) (string, error)
return "", fmt.Errorf("Unsupported fieldPath: %v", fieldPath)
}
// ExtractResourceValueByContainerName extracts the value of a resource
// by providing container name
func ExtractResourceValueByContainerName(fs *api.ResourceFieldSelector, pod *api.Pod, containerName string) (string, error) {
container, err := findContainerInPod(pod, containerName)
if err != nil {
return "", err
}
return ExtractContainerResourceValue(fs, container)
}
// ExtractContainerResourceValue extracts the value of a resource
// in an already known container
func ExtractContainerResourceValue(fs *api.ResourceFieldSelector, container *api.Container) (string, error) {
divisor := resource.Quantity{}
if divisor.Cmp(fs.Divisor) == 0 {
divisor = resource.MustParse("1")
} else {
divisor = fs.Divisor
}
switch fs.Resource {
case "limits.cpu":
return convertResourceCPUToString(container.Resources.Limits.Cpu(), divisor)
case "limits.memory":
return convertResourceMemoryToString(container.Resources.Limits.Memory(), divisor)
case "requests.cpu":
return convertResourceCPUToString(container.Resources.Requests.Cpu(), divisor)
case "requests.memory":
return convertResourceMemoryToString(container.Resources.Requests.Memory(), divisor)
}
return "", fmt.Errorf("Unsupported container resource : %v", fs.Resource)
}
// findContainerInPod finds a container by its name in the provided pod
func findContainerInPod(pod *api.Pod, containerName string) (*api.Container, error) {
for _, container := range pod.Spec.Containers {
if container.Name == containerName {
return &container, nil
}
}
return nil, fmt.Errorf("container %s not found", containerName)
}
// convertResourceCPUTOString converts cpu value to the format of divisor and returns
// ceiling of the value.
func convertResourceCPUToString(cpu *resource.Quantity, divisor resource.Quantity) (string, error) {
c := int64(math.Ceil(float64(cpu.MilliValue()) / float64(divisor.MilliValue())))
return strconv.FormatInt(c, 10), nil
}
// convertResourceMemoryToString converts memory value to the format of divisor and returns
// ceiling of the value.
func convertResourceMemoryToString(memory *resource.Quantity, divisor resource.Quantity) (string, error) {
m := int64(math.Ceil(float64(memory.Value()) / float64(divisor.Value())))
return strconv.FormatInt(m, 10), nil
}

View File

@ -700,8 +700,13 @@ func printRBDVolumeSource(rbd *api.RBDVolumeSource, out io.Writer) {
func printDownwardAPIVolumeSource(d *api.DownwardAPIVolumeSource, out io.Writer) {
fmt.Fprintf(out, " Type:\tDownwardAPI (a volume populated by information about the pod)\n Items:\n")
for _, mapping := range d.Items {
if mapping.FieldRef != nil {
fmt.Fprintf(out, " %v -> %v\n", mapping.FieldRef.FieldPath, mapping.Path)
}
if mapping.ResourceFieldRef != nil {
fmt.Fprintf(out, " %v -> %v\n", mapping.ResourceFieldRef.Resource, mapping.Path)
}
}
}
type PersistentVolumeDescriber struct {
@ -895,6 +900,12 @@ func describeContainers(label string, containers []api.Container, containerStatu
valueFrom = resolverFn(e)
}
fmt.Fprintf(out, " %s:\t%s (%s:%s)\n", e.Name, valueFrom, e.ValueFrom.FieldRef.APIVersion, e.ValueFrom.FieldRef.FieldPath)
case e.ValueFrom.ResourceFieldRef != nil:
valueFrom, err := fieldpath.ExtractContainerResourceValue(e.ValueFrom.ResourceFieldRef, &container)
if err != nil {
valueFrom = ""
}
fmt.Fprintf(out, " %s:\t%s (%s)\n", e.Name, valueFrom, e.ValueFrom.ResourceFieldRef.Resource)
case e.ValueFrom.SecretKeyRef != nil:
fmt.Fprintf(out, " %s:\t<set to the key '%s' in secret '%s'>\n", e.Name, e.ValueFrom.SecretKeyRef.Key, e.ValueFrom.SecretKeyRef.Name)
case e.ValueFrom.ConfigMapKeyRef != nil:

View File

@ -1506,6 +1506,11 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *api.Pod, container *api.Contain
if err != nil {
return result, err
}
case envVar.ValueFrom.ResourceFieldRef != nil:
runtimeVal, err = containerResourceRuntimeValue(envVar.ValueFrom.ResourceFieldRef, pod, container)
if err != nil {
return result, err
}
case envVar.ValueFrom.ConfigMapKeyRef != nil:
name := envVar.ValueFrom.ConfigMapKeyRef.Name
key := envVar.ValueFrom.ConfigMapKeyRef.Key
@ -1563,6 +1568,16 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *api.ObjectFieldSelector, pod
return fieldpath.ExtractFieldPathAsString(pod, internalFieldPath)
}
// containerResourceRuntimeValue returns the value of the provided container resource
func containerResourceRuntimeValue(fs *api.ResourceFieldSelector, pod *api.Pod, container *api.Container) (string, error) {
containerName := fs.ContainerName
if len(containerName) == 0 {
return fieldpath.ExtractContainerResourceValue(fs, container)
} else {
return fieldpath.ExtractResourceValueByContainerName(fs, pod, containerName)
}
}
// GetClusterDNS returns a list of the DNS servers and a list of the DNS search
// domains of the cluster.
func (kl *Kubelet) GetClusterDNS(pod *api.Pod) ([]string, []string, error) {

View File

@ -69,14 +69,11 @@ func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool {
func (plugin *downwardAPIPlugin) NewMounter(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Mounter, error) {
v := &downwardAPIVolume{
volName: spec.Name(),
items: spec.Volume.DownwardAPI.Items,
pod: pod,
podUID: pod.UID,
plugin: plugin,
}
v.fieldReferenceFileNames = make(map[string]string)
for _, fileInfo := range spec.Volume.DownwardAPI.Items {
v.fieldReferenceFileNames[fileInfo.FieldRef.FieldPath] = path.Clean(fileInfo.Path)
}
return &downwardAPIVolumeMounter{
downwardAPIVolume: v,
opts: &opts,
@ -96,7 +93,7 @@ func (plugin *downwardAPIPlugin) NewUnmounter(volName string, podUID types.UID)
// downwardAPIVolume retrieves downward API data and placing them into the volume on the host.
type downwardAPIVolume struct {
volName string
fieldReferenceFileNames map[string]string
items []api.DownwardAPIVolumeFile
pod *api.Pod
podUID types.UID // TODO: remove this redundancy as soon NewUnmounter func will have *api.POD and not only types.UID
plugin *downwardAPIPlugin
@ -173,12 +170,22 @@ func (b *downwardAPIVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
func (d *downwardAPIVolume) collectData() (map[string][]byte, error) {
errlist := []error{}
data := make(map[string][]byte)
for fieldReference, fileName := range d.fieldReferenceFileNames {
if values, err := fieldpath.ExtractFieldPathAsString(d.pod, fieldReference); err != nil {
glog.Errorf("Unable to extract field %s: %s", fieldReference, err.Error())
for _, fileInfo := range d.items {
if fileInfo.FieldRef != nil {
if values, err := fieldpath.ExtractFieldPathAsString(d.pod, fileInfo.FieldRef.FieldPath); err != nil {
glog.Errorf("Unable to extract field %s: %s", fileInfo.FieldRef.FieldPath, err.Error())
errlist = append(errlist, err)
} else {
data[fileName] = []byte(sortLines(values))
data[path.Clean(fileInfo.Path)] = []byte(sortLines(values))
}
} else if fileInfo.ResourceFieldRef != nil {
containerName := fileInfo.ResourceFieldRef.ContainerName
if values, err := fieldpath.ExtractResourceValueByContainerName(fileInfo.ResourceFieldRef, d.pod, containerName); err != nil {
glog.Errorf("Unable to extract field %s: %s", fileInfo.ResourceFieldRef.Resource, err.Error())
errlist = append(errlist, err)
} else {
data[path.Clean(fileInfo.Path)] = []byte(sortLines(values))
}
}
}
return data, utilerrors.NewAggregate(errlist)

View File

@ -115,7 +115,7 @@ func TestLabels(t *testing.T) {
VolumeSource: api.VolumeSource{
DownwardAPI: &api.DownwardAPIVolumeSource{
Items: []api.DownwardAPIVolumeFile{
{Path: "labels", FieldRef: api.ObjectFieldSelector{
{Path: "labels", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.labels"}}}},
},
}
@ -179,7 +179,7 @@ func TestAnnotations(t *testing.T) {
VolumeSource: api.VolumeSource{
DownwardAPI: &api.DownwardAPIVolumeSource{
Items: []api.DownwardAPIVolumeFile{
{Path: "annotations", FieldRef: api.ObjectFieldSelector{
{Path: "annotations", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.annotations"}}}},
},
}
@ -242,7 +242,7 @@ func TestName(t *testing.T) {
VolumeSource: api.VolumeSource{
DownwardAPI: &api.DownwardAPIVolumeSource{
Items: []api.DownwardAPIVolumeFile{
{Path: "name_file_name", FieldRef: api.ObjectFieldSelector{
{Path: "name_file_name", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.name"}}}},
},
}
@ -305,7 +305,7 @@ func TestNamespace(t *testing.T) {
VolumeSource: api.VolumeSource{
DownwardAPI: &api.DownwardAPIVolumeSource{
Items: []api.DownwardAPIVolumeFile{
{Path: "namespace_file_name", FieldRef: api.ObjectFieldSelector{
{Path: "namespace_file_name", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.namespace"}}}},
},
}
@ -383,7 +383,7 @@ func TestWriteTwiceNoUpdate(t *testing.T) {
VolumeSource: api.VolumeSource{
DownwardAPI: &api.DownwardAPIVolumeSource{
Items: []api.DownwardAPIVolumeFile{
{Path: "labels", FieldRef: api.ObjectFieldSelector{
{Path: "labels", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.labels"}}}},
},
}
@ -469,7 +469,7 @@ func TestWriteTwiceWithUpdate(t *testing.T) {
VolumeSource: api.VolumeSource{
DownwardAPI: &api.DownwardAPIVolumeSource{
Items: []api.DownwardAPIVolumeFile{
{Path: "labels", FieldRef: api.ObjectFieldSelector{
{Path: "labels", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.labels"}}}},
},
}
@ -575,9 +575,9 @@ func TestWriteWithUnixPath(t *testing.T) {
VolumeSource: api.VolumeSource{
DownwardAPI: &api.DownwardAPIVolumeSource{
Items: []api.DownwardAPIVolumeFile{
{Path: "this/is/mine/labels", FieldRef: api.ObjectFieldSelector{
{Path: "this/is/mine/labels", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.labels"}},
{Path: "this/is/yours/annotations", FieldRef: api.ObjectFieldSelector{
{Path: "this/is/yours/annotations", FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.annotations"}},
}}},
}
@ -657,7 +657,7 @@ func TestWriteWithUnixPathBadPath(t *testing.T) {
Items: []api.DownwardAPIVolumeFile{
{
Path: "this//labels",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
FieldPath: "metadata.labels",
},
},

View File

@ -20,6 +20,7 @@ import (
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/test/e2e/framework"
@ -80,6 +81,53 @@ var _ = framework.KubeDescribe("Downward API", func() {
testDownwardAPI(f, podName, env, expectations)
})
It("should provide container's limits.cpu/memory and requests.cpu/memory as env vars", func() {
podName := "downward-api-" + string(util.NewUUID())
env := []api.EnvVar{
{
Name: "CPU_LIMIT",
ValueFrom: &api.EnvVarSource{
ResourceFieldRef: &api.ResourceFieldSelector{
Resource: "limits.cpu",
},
},
},
{
Name: "MEMORY_LIMIT",
ValueFrom: &api.EnvVarSource{
ResourceFieldRef: &api.ResourceFieldSelector{
Resource: "limits.memory",
},
},
},
{
Name: "CPU_REQUEST",
ValueFrom: &api.EnvVarSource{
ResourceFieldRef: &api.ResourceFieldSelector{
Resource: "requests.cpu",
},
},
},
{
Name: "MEMORY_REQUEST",
ValueFrom: &api.EnvVarSource{
ResourceFieldRef: &api.ResourceFieldSelector{
Resource: "requests.memory",
},
},
},
}
expectations := []string{
fmt.Sprintf("CPU_LIMIT=2"),
fmt.Sprintf("MEMORY_LIMIT=67108864"),
fmt.Sprintf("CPU_REQUEST=1"),
fmt.Sprintf("MEMORY_REQUEST=33554432"),
}
testDownwardAPI(f, podName, env, expectations)
})
})
func testDownwardAPI(f *framework.Framework, podName string, env []api.EnvVar, expectations []string) {
@ -94,6 +142,16 @@ func testDownwardAPI(f *framework.Framework, podName string, env []api.EnvVar, e
Name: "dapi-container",
Image: "gcr.io/google_containers/busybox:1.24",
Command: []string{"sh", "-c", "env"},
Resources: api.ResourceRequirements{
Requests: api.ResourceList{
api.ResourceCPU: resource.MustParse("250m"),
api.ResourceMemory: resource.MustParse("32Mi"),
},
Limits: api.ResourceList{
api.ResourceCPU: resource.MustParse("1250m"),
api.ResourceMemory: resource.MustParse("64Mi"),
},
},
Env: env,
},
},

View File

@ -21,6 +21,7 @@ import (
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/test/e2e/framework"
@ -131,6 +132,43 @@ var _ = framework.KubeDescribe("Downward API volume", func() {
podLogTimeout, framework.Poll).Should(ContainSubstring("builder=\"foo\"\n"))
})
It("should provide container's cpu limit", func() {
podName := "downwardapi-volume-" + string(util.NewUUID())
pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_limit")
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
fmt.Sprintf("2\n"),
}, f.Namespace.Name)
})
It("should provide container's memory limit", func() {
podName := "downwardapi-volume-" + string(util.NewUUID())
pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_limit")
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
fmt.Sprintf("67108864\n"),
}, f.Namespace.Name)
})
It("should provide container's cpu request", func() {
podName := "downwardapi-volume-" + string(util.NewUUID())
pod := downwardAPIVolumeForContainerResources(podName, "/etc/cpu_request")
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
fmt.Sprintf("1\n"),
}, f.Namespace.Name)
})
It("should provide container's memory request", func() {
podName := "downwardapi-volume-" + string(util.NewUUID())
pod := downwardAPIVolumeForContainerResources(podName, "/etc/memory_request")
framework.TestContainerOutput("downward API volume plugin", f.Client, pod, 0, []string{
fmt.Sprintf("33554432\n"),
}, f.Namespace.Name)
})
})
func downwardAPIVolumePodForSimpleTest(name string, filePath string) *api.Pod {
@ -154,6 +192,40 @@ func downwardAPIVolumePodForSimpleTest(name string, filePath string) *api.Pod {
return pod
}
func downwardAPIVolumeForContainerResources(name string, filePath string) *api.Pod {
pod := downwardAPIVolumeBasePod(name, nil, nil)
pod.Spec.Containers = downwardAPIVolumeBaseContainers("client-container", filePath)
return pod
}
func downwardAPIVolumeBaseContainers(name, filePath string) []api.Container {
return []api.Container{
{
Name: name,
Image: "gcr.io/google_containers/mounttest:0.6",
Command: []string{"/mt", "--file_content=" + filePath},
Resources: api.ResourceRequirements{
Requests: api.ResourceList{
api.ResourceCPU: resource.MustParse("250m"),
api.ResourceMemory: resource.MustParse("32Mi"),
},
Limits: api.ResourceList{
api.ResourceCPU: resource.MustParse("1250m"),
api.ResourceMemory: resource.MustParse("64Mi"),
},
},
VolumeMounts: []api.VolumeMount{
{
Name: "podinfo",
MountPath: "/etc",
ReadOnly: false,
},
},
},
}
}
func downwardAPIVolumePodForUpdateTest(name string, labels, annotations map[string]string, filePath string) *api.Pod {
pod := downwardAPIVolumeBasePod(name, labels, annotations)
@ -192,11 +264,39 @@ func downwardAPIVolumeBasePod(name string, labels, annotations map[string]string
Items: []api.DownwardAPIVolumeFile{
{
Path: "podname",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.name",
},
},
{
Path: "cpu_limit",
ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "client-container",
Resource: "limits.cpu",
},
},
{
Path: "cpu_request",
ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "client-container",
Resource: "requests.cpu",
},
},
{
Path: "memory_limit",
ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "client-container",
Resource: "limits.memory",
},
},
{
Path: "memory_request",
ResourceFieldRef: &api.ResourceFieldSelector{
ContainerName: "client-container",
Resource: "requests.memory",
},
},
},
},
},
@ -213,7 +313,7 @@ func applyLabelsAndAnnotationsToDownwardAPIPod(labels, annotations map[string]st
if len(labels) > 0 {
pod.Spec.Volumes[0].DownwardAPI.Items = append(pod.Spec.Volumes[0].DownwardAPI.Items, api.DownwardAPIVolumeFile{
Path: "labels",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.labels",
},
@ -223,7 +323,7 @@ func applyLabelsAndAnnotationsToDownwardAPIPod(labels, annotations map[string]st
if len(annotations) > 0 {
pod.Spec.Volumes[0].DownwardAPI.Items = append(pod.Spec.Volumes[0].DownwardAPI.Items, api.DownwardAPIVolumeFile{
Path: "annotations",
FieldRef: api.ObjectFieldSelector{
FieldRef: &api.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.annotations",
},