Merge pull request #46444 from jsafrane/node-mount-propagation

Automatic merge from submit-queue (batch tested with PRs 45724, 48051, 46444, 51056, 51605)

Mount propagation in kubelet

Together with #45724 it implements mount propagation as proposed in https://github.com/kubernetes/community/pull/659

There is:

- New alpha annotation that allows user to explicitly set propagation mode for each `VolumeMount` in pod containers (to be replaced with real `VolumeMount.Propagation` field during beta) + validation + tests. "Private" is the default one (= no change to existing pods).

  I know about proposal for real API fields for alpha feature in https://docs.google.com/document/d/1wuoSqHkeT51mQQ7dIFhUKrdi3-1wbKrNWeIL4cKb9zU/edit, but it seems it's not implemented yet. It would save me quite lot of code and ugly annotation.

- Updated CRI API to transport chosen propagation to Docker.

- New `kubelet --experimental-mount-propagation` option to enable the previous bullet without modifying types.go (worked around with changing `KubeletDeps`... not nice, but it's better than adding a parameter to `NewMainKubelet` and removing it in the next release...)

```release-note
kubelet has alpha support for mount propagation. It is disabled by default and it is there for testing only. This feature may be redesigned or even removed in a future release.
```

@derekwaynecarr @dchen1107 @kubernetes/sig-node-pr-reviews
This commit is contained in:
Kubernetes Submit Queue 2017-09-02 12:11:07 -07:00 committed by GitHub
commit 11a836078d
43 changed files with 1819 additions and 1042 deletions

View File

@ -62731,6 +62731,10 @@
"description": "Path within the container at which the volume should be mounted. Must not contain ':'.", "description": "Path within the container at which the volume should be mounted. Must not contain ':'.",
"type": "string" "type": "string"
}, },
"mountPropagation": {
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.",
"type": "string"
},
"name": { "name": {
"description": "This must match the Name of a Volume.", "description": "This must match the Name of a Volume.",
"type": "string" "type": "string"

View File

@ -5334,9 +5334,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -7472,9 +7472,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -2916,9 +2916,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -2971,9 +2971,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -2971,9 +2971,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -8026,9 +8026,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -2450,9 +2450,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.WatchEvent": { "v1.WatchEvent": {
"id": "v1.WatchEvent", "id": "v1.WatchEvent",
"required": [ "required": [

View File

@ -20577,9 +20577,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -835,9 +835,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3> <h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3>

View File

@ -782,9 +782,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3> <h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3>

View File

@ -700,9 +700,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3> <h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3>

View File

@ -741,9 +741,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3> <h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3>

View File

@ -700,9 +700,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3> <h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3>

View File

@ -993,9 +993,20 @@ Examples: <code>/foo</code> would allow <code>/foo</code>, <code>/foo/</code> an
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3> <h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3>

View File

@ -883,6 +883,10 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_volumemount">v1.VolumeMount</h3> <h3 id="_v1_volumemount">v1.VolumeMount</h3>
@ -935,6 +939,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>

View File

@ -929,6 +929,10 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_volumemount">v1.VolumeMount</h3> <h3 id="_v1_volumemount">v1.VolumeMount</h3>
@ -981,6 +985,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>

View File

@ -12110,6 +12110,10 @@
"description": "Path within the container at which the volume should be mounted. Must not contain ':'.", "description": "Path within the container at which the volume should be mounted. Must not contain ':'.",
"type": "string" "type": "string"
}, },
"mountPropagation": {
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.",
"type": "string"
},
"name": { "name": {
"description": "This must match the Name of a Volume.", "description": "This must match the Name of a Volume.",
"type": "string" "type": "string"

View File

@ -6385,9 +6385,17 @@
"subPath": { "subPath": {
"type": "string", "type": "string",
"description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)." "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root)."
},
"mountPropagation": {
"$ref": "v1.MountPropagationMode",
"description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release."
} }
} }
}, },
"v1.MountPropagationMode": {
"id": "v1.MountPropagationMode",
"properties": {}
},
"v1.Probe": { "v1.Probe": {
"id": "v1.Probe", "id": "v1.Probe",
"description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.",

View File

@ -945,9 +945,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.</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_mountpropagationmode">v1.MountPropagationMode</a></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="sect2">
<h3 id="_v1_mountpropagationmode">v1.MountPropagationMode</h3>
</div> </div>
<div class="sect2"> <div class="sect2">
<h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3> <h3 id="_v1_downwardapiprojection">v1.DownwardAPIProjection</h3>

View File

@ -1445,8 +1445,34 @@ type VolumeMount struct {
// Defaults to "" (volume's root). // Defaults to "" (volume's root).
// +optional // +optional
SubPath string SubPath string
// mountPropagation determines how mounts are propagated from the host
// to container and the other way around.
// When not set, MountPropagationHostToContainer is used.
// This field is alpha in 1.8 and can be reworked or removed in a future
// release.
// +optional
MountPropagation *MountPropagationMode
} }
// MountPropagationMode describes mount propagation.
type MountPropagationMode string
const (
// MountPropagationHostToContainer means that the volume in a container will
// receive new mounts from the host or other containers, but filesystems
// mounted inside the container won't be propagated to the host or other
// containers.
// Note that this mode is recursively applied to all mounts in the volume
// ("rslave" in Linux terminology).
MountPropagationHostToContainer MountPropagationMode = "HostToContainer"
// MountPropagationBidirectional means that the volume in a container will
// receive new mounts from the host or other containers, and its own mounts
// will be propagated from the container to the host or other containers.
// Note that this mode is recursively applied to all mounts in the volume
// ("rshared" in Linux terminology).
MountPropagationBidirectional MountPropagationMode = "Bidirectional"
)
// EnvVar represents an environment variable present in a Container. // EnvVar represents an environment variable present in a Container.
type EnvVar struct { type EnvVar struct {
// Required: This must be a C_IDENTIFIER. // Required: This must be a C_IDENTIFIER.

View File

@ -5133,6 +5133,7 @@ func autoConvert_v1_VolumeMount_To_api_VolumeMount(in *v1.VolumeMount, out *api.
out.ReadOnly = in.ReadOnly out.ReadOnly = in.ReadOnly
out.MountPath = in.MountPath out.MountPath = in.MountPath
out.SubPath = in.SubPath out.SubPath = in.SubPath
out.MountPropagation = (*api.MountPropagationMode)(unsafe.Pointer(in.MountPropagation))
return nil return nil
} }
@ -5146,6 +5147,7 @@ func autoConvert_api_VolumeMount_To_v1_VolumeMount(in *api.VolumeMount, out *v1.
out.ReadOnly = in.ReadOnly out.ReadOnly = in.ReadOnly
out.MountPath = in.MountPath out.MountPath = in.MountPath
out.SubPath = in.SubPath out.SubPath = in.SubPath
out.MountPropagation = (*v1.MountPropagationMode)(unsafe.Pointer(in.MountPropagation))
return nil return nil
} }

View File

@ -1027,6 +1027,38 @@ func validatePathNoBacksteps(targetPath string, fldPath *field.Path) field.Error
return allErrs return allErrs
} }
// validateMountPropagation verifies that MountPropagation field is valid and
// allowed for given container.
func validateMountPropagation(mountPropagation *api.MountPropagationMode, container *api.Container, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if mountPropagation == nil {
return allErrs
}
if !utilfeature.DefaultFeatureGate.Enabled(features.MountPropagation) {
allErrs = append(allErrs, field.Forbidden(fldPath, "mount propagation is disabled by feature-gate"))
return allErrs
}
supportedMountPropagations := sets.NewString(string(api.MountPropagationBidirectional), string(api.MountPropagationHostToContainer))
if !supportedMountPropagations.Has(string(*mountPropagation)) {
allErrs = append(allErrs, field.NotSupported(fldPath, *mountPropagation, supportedMountPropagations.List()))
}
if container == nil {
// The container is not available yet, e.g. during validation of
// PodPreset. Stop validation now, Pod validation will refuse final
// Pods with Bidirectional propagation in non-privileged containers.
return allErrs
}
privileged := container.SecurityContext != nil && container.SecurityContext.Privileged != nil && *container.SecurityContext.Privileged
if *mountPropagation == api.MountPropagationBidirectional && !privileged {
allErrs = append(allErrs, field.Forbidden(fldPath, "Bidirectional mount propagation is available only to privileged containers"))
}
return allErrs
}
// This validate will make sure targetPath: // This validate will make sure targetPath:
// 1. is not abs path // 1. is not abs path
// 2. does not contain any '..' elements // 2. does not contain any '..' elements
@ -1845,7 +1877,7 @@ func validateSecretKeySelector(s *api.SecretKeySelector, fldPath *field.Path) fi
return allErrs return allErrs
} }
func ValidateVolumeMounts(mounts []api.VolumeMount, volumes sets.String, fldPath *field.Path) field.ErrorList { func ValidateVolumeMounts(mounts []api.VolumeMount, volumes sets.String, container *api.Container, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
mountpoints := sets.NewString() mountpoints := sets.NewString()
@ -1869,6 +1901,10 @@ func ValidateVolumeMounts(mounts []api.VolumeMount, volumes sets.String, fldPath
if len(mnt.SubPath) > 0 { if len(mnt.SubPath) > 0 {
allErrs = append(allErrs, validateLocalDescendingPath(mnt.SubPath, fldPath.Child("subPath"))...) allErrs = append(allErrs, validateLocalDescendingPath(mnt.SubPath, fldPath.Child("subPath"))...)
} }
if mnt.MountPropagation != nil {
allErrs = append(allErrs, validateMountPropagation(mnt.MountPropagation, container, fldPath.Child("mountPropagation"))...)
}
} }
return allErrs return allErrs
} }
@ -2135,7 +2171,7 @@ func validateContainers(containers []api.Container, volumes sets.String, fldPath
allErrs = append(allErrs, validateContainerPorts(ctr.Ports, idxPath.Child("ports"))...) allErrs = append(allErrs, validateContainerPorts(ctr.Ports, idxPath.Child("ports"))...)
allErrs = append(allErrs, ValidateEnv(ctr.Env, idxPath.Child("env"))...) allErrs = append(allErrs, ValidateEnv(ctr.Env, idxPath.Child("env"))...)
allErrs = append(allErrs, ValidateEnvFrom(ctr.EnvFrom, idxPath.Child("envFrom"))...) allErrs = append(allErrs, ValidateEnvFrom(ctr.EnvFrom, idxPath.Child("envFrom"))...)
allErrs = append(allErrs, ValidateVolumeMounts(ctr.VolumeMounts, volumes, idxPath.Child("volumeMounts"))...) allErrs = append(allErrs, ValidateVolumeMounts(ctr.VolumeMounts, volumes, &ctr, idxPath.Child("volumeMounts"))...)
allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, idxPath.Child("imagePullPolicy"))...) allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, idxPath.Child("imagePullPolicy"))...)
allErrs = append(allErrs, ValidateResourceRequirements(&ctr.Resources, idxPath.Child("resources"))...) allErrs = append(allErrs, ValidateResourceRequirements(&ctr.Resources, idxPath.Child("resources"))...)
allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, idxPath.Child("securityContext"))...) allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, idxPath.Child("securityContext"))...)

View File

@ -3405,6 +3405,10 @@ func TestValidateEnvFrom(t *testing.T) {
func TestValidateVolumeMounts(t *testing.T) { func TestValidateVolumeMounts(t *testing.T) {
volumes := sets.NewString("abc", "123", "abc-123") volumes := sets.NewString("abc", "123", "abc-123")
container := api.Container{
SecurityContext: nil,
}
propagation := api.MountPropagationBidirectional
successCase := []api.VolumeMount{ successCase := []api.VolumeMount{
{Name: "abc", MountPath: "/foo"}, {Name: "abc", MountPath: "/foo"},
@ -3415,28 +3419,154 @@ func TestValidateVolumeMounts(t *testing.T) {
{Name: "abc-123", MountPath: "/bac", SubPath: ".baz"}, {Name: "abc-123", MountPath: "/bac", SubPath: ".baz"},
{Name: "abc-123", MountPath: "/bad", SubPath: "..baz"}, {Name: "abc-123", MountPath: "/bad", SubPath: "..baz"},
} }
if errs := ValidateVolumeMounts(successCase, volumes, field.NewPath("field")); len(errs) != 0 { if errs := ValidateVolumeMounts(successCase, volumes, &container, field.NewPath("field")); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
} }
errorCases := map[string][]api.VolumeMount{ errorCases := map[string][]api.VolumeMount{
"empty name": {{Name: "", MountPath: "/foo"}}, "empty name": {{Name: "", MountPath: "/foo"}},
"name not found": {{Name: "", MountPath: "/foo"}}, "name not found": {{Name: "", MountPath: "/foo"}},
"empty mountpath": {{Name: "abc", MountPath: ""}}, "empty mountpath": {{Name: "abc", MountPath: ""}},
"relative mountpath": {{Name: "abc", MountPath: "bar"}}, "relative mountpath": {{Name: "abc", MountPath: "bar"}},
"mountpath collision": {{Name: "foo", MountPath: "/path/a"}, {Name: "bar", MountPath: "/path/a"}}, "mountpath collision": {{Name: "foo", MountPath: "/path/a"}, {Name: "bar", MountPath: "/path/a"}},
"absolute subpath": {{Name: "abc", MountPath: "/bar", SubPath: "/baz"}}, "absolute subpath": {{Name: "abc", MountPath: "/bar", SubPath: "/baz"}},
"subpath in ..": {{Name: "abc", MountPath: "/bar", SubPath: "../baz"}}, "subpath in ..": {{Name: "abc", MountPath: "/bar", SubPath: "../baz"}},
"subpath contains ..": {{Name: "abc", MountPath: "/bar", SubPath: "baz/../bat"}}, "subpath contains ..": {{Name: "abc", MountPath: "/bar", SubPath: "baz/../bat"}},
"subpath ends in ..": {{Name: "abc", MountPath: "/bar", SubPath: "./.."}}, "subpath ends in ..": {{Name: "abc", MountPath: "/bar", SubPath: "./.."}},
"disabled MountPropagation feature gate": {{Name: "abc", MountPath: "/bar", MountPropagation: &propagation}},
} }
for k, v := range errorCases { for k, v := range errorCases {
if errs := ValidateVolumeMounts(v, volumes, field.NewPath("field")); len(errs) == 0 { if errs := ValidateVolumeMounts(v, volumes, &container, field.NewPath("field")); len(errs) == 0 {
t.Errorf("expected failure for %s", k) t.Errorf("expected failure for %s", k)
} }
} }
} }
func TestValidateMountPropagation(t *testing.T) {
bTrue := true
bFalse := false
privilegedContainer := &api.Container{
SecurityContext: &api.SecurityContext{
Privileged: &bTrue,
},
}
nonPrivilegedContainer := &api.Container{
SecurityContext: &api.SecurityContext{
Privileged: &bFalse,
},
}
defaultContainer := &api.Container{}
propagationBidirectional := api.MountPropagationBidirectional
propagationHostToContainer := api.MountPropagationHostToContainer
propagationInvalid := api.MountPropagationMode("invalid")
tests := []struct {
mount api.VolumeMount
container *api.Container
expectError bool
}{
{
// implicitly non-privileged container + no propagation
api.VolumeMount{Name: "foo", MountPath: "/foo"},
defaultContainer,
false,
},
{
// implicitly non-privileged container + HostToContainer
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationHostToContainer},
defaultContainer,
false,
},
{
// error: implicitly non-privileged container + Bidirectional
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationBidirectional},
defaultContainer,
true,
},
{
// explicitly non-privileged container + no propagation
api.VolumeMount{Name: "foo", MountPath: "/foo"},
nonPrivilegedContainer,
false,
},
{
// explicitly non-privileged container + HostToContainer
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationHostToContainer},
nonPrivilegedContainer,
false,
},
{
// explicitly non-privileged container + HostToContainer
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationBidirectional},
nonPrivilegedContainer,
true,
},
{
// privileged container + no propagation
api.VolumeMount{Name: "foo", MountPath: "/foo"},
privilegedContainer,
false,
},
{
// privileged container + HostToContainer
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationHostToContainer},
privilegedContainer,
false,
},
{
// privileged container + Bidirectional
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationBidirectional},
privilegedContainer,
false,
},
{
// error: privileged container + invalid mount propagation
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationInvalid},
privilegedContainer,
true,
},
{
// no container + Bidirectional
api.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationBidirectional},
nil,
false,
},
}
// Enable MountPropagation for this test
priorityEnabled := utilfeature.DefaultFeatureGate.Enabled("MountPropagation")
defer func() {
var err error
// restoring the old value
if priorityEnabled {
err = utilfeature.DefaultFeatureGate.Set("MountPropagation=true")
} else {
err = utilfeature.DefaultFeatureGate.Set("MountPropagation=false")
}
if err != nil {
t.Errorf("Failed to restore feature gate for MountPropagation: %v", err)
}
}()
err := utilfeature.DefaultFeatureGate.Set("MountPropagation=true")
if err != nil {
t.Errorf("Failed to enable feature gate for MountPropagation: %v", err)
return
}
for i, test := range tests {
volumes := sets.NewString("foo")
errs := ValidateVolumeMounts([]api.VolumeMount{test.mount}, volumes, test.container, field.NewPath("field"))
if test.expectError && len(errs) == 0 {
t.Errorf("test %d expected error, got none", i)
}
if !test.expectError && len(errs) != 0 {
t.Errorf("test %d expected success, got error: %v", i, errs)
}
}
}
func TestValidateProbe(t *testing.T) { func TestValidateProbe(t *testing.T) {
handler := api.Handler{Exec: &api.ExecAction{Command: []string{"echo"}}} handler := api.Handler{Exec: &api.ExecAction{Command: []string{"echo"}}}
// These fields must be positive. // These fields must be positive.

View File

@ -1409,7 +1409,9 @@ func (in *Container) DeepCopyInto(out *Container) {
if in.VolumeMounts != nil { if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts in, out := &in.VolumeMounts, &out.VolumeMounts
*out = make([]VolumeMount, len(*in)) *out = make([]VolumeMount, len(*in))
copy(*out, *in) for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
} }
if in.LivenessProbe != nil { if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe in, out := &in.LivenessProbe, &out.LivenessProbe
@ -5931,6 +5933,15 @@ func (in *Volume) DeepCopy() *Volume {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeMount) DeepCopyInto(out *VolumeMount) { func (in *VolumeMount) DeepCopyInto(out *VolumeMount) {
*out = *in *out = *in
if in.MountPropagation != nil {
in, out := &in.MountPropagation, &out.MountPropagation
if *in == nil {
*out = nil
} else {
*out = new(MountPropagationMode)
**out = **in
}
}
return return
} }

View File

@ -47,7 +47,7 @@ func ValidatePodPresetSpec(spec *settings.PodPresetSpec, fldPath *field.Path) fi
allErrs = append(allErrs, vErrs...) allErrs = append(allErrs, vErrs...)
allErrs = append(allErrs, apivalidation.ValidateEnv(spec.Env, fldPath.Child("env"))...) allErrs = append(allErrs, apivalidation.ValidateEnv(spec.Env, fldPath.Child("env"))...)
allErrs = append(allErrs, apivalidation.ValidateEnvFrom(spec.EnvFrom, fldPath.Child("envFrom"))...) allErrs = append(allErrs, apivalidation.ValidateEnvFrom(spec.EnvFrom, fldPath.Child("envFrom"))...)
allErrs = append(allErrs, apivalidation.ValidateVolumeMounts(spec.VolumeMounts, volumes, fldPath.Child("volumeMounts"))...) allErrs = append(allErrs, apivalidation.ValidateVolumeMounts(spec.VolumeMounts, volumes, nil, fldPath.Child("volumeMounts"))...)
return allErrs return allErrs
} }

View File

@ -142,7 +142,9 @@ func (in *PodPresetSpec) DeepCopyInto(out *PodPresetSpec) {
if in.VolumeMounts != nil { if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts in, out := &in.VolumeMounts, &out.VolumeMounts
*out = make([]api.VolumeMount, len(*in)) *out = make([]api.VolumeMount, len(*in))
copy(*out, *in) for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
} }
return return
} }

View File

@ -144,6 +144,12 @@ const (
// //
// Implement IPVS-based in-cluster service load balancing // Implement IPVS-based in-cluster service load balancing
SupportIPVSProxyMode utilfeature.Feature = "SupportIPVSProxyMode" SupportIPVSProxyMode utilfeature.Feature = "SupportIPVSProxyMode"
// owner: @jsafrane
// alpha: v1.8
//
// Enable mount propagation of volumes.
MountPropagation utilfeature.Feature = "MountPropagation"
) )
func init() { func init() {
@ -172,6 +178,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
PodPriority: {Default: false, PreRelease: utilfeature.Alpha}, PodPriority: {Default: false, PreRelease: utilfeature.Alpha},
EnableEquivalenceClassCache: {Default: false, PreRelease: utilfeature.Alpha}, EnableEquivalenceClassCache: {Default: false, PreRelease: utilfeature.Alpha},
TaintNodesByCondition: {Default: false, PreRelease: utilfeature.Alpha}, TaintNodesByCondition: {Default: false, PreRelease: utilfeature.Alpha},
MountPropagation: {Default: false, PreRelease: utilfeature.Alpha},
// inherited features from generic apiserver, relisted here to get a conflict if it is changed // inherited features from generic apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side: // unintentionally on either side:

View File

@ -43,6 +43,7 @@ go_library(
"//pkg/fieldpath:go_default_library", "//pkg/fieldpath:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/kubelet/apis/cri:go_default_library", "//pkg/kubelet/apis/cri:go_default_library",
"//pkg/kubelet/apis/cri/v1alpha1/runtime:go_default_library",
"//pkg/kubelet/apis/kubeletconfig:go_default_library", "//pkg/kubelet/apis/kubeletconfig:go_default_library",
"//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library", "//pkg/kubelet/apis/kubeletconfig/v1alpha1:go_default_library",
"//pkg/kubelet/cadvisor:go_default_library", "//pkg/kubelet/cadvisor:go_default_library",
@ -170,6 +171,7 @@ go_test(
"//pkg/api/install:go_default_library", "//pkg/api/install:go_default_library",
"//pkg/capabilities:go_default_library", "//pkg/capabilities:go_default_library",
"//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/apis:go_default_library",
"//pkg/kubelet/apis/cri/v1alpha1/runtime:go_default_library",
"//pkg/kubelet/apis/kubeletconfig:go_default_library", "//pkg/kubelet/apis/kubeletconfig:go_default_library",
"//pkg/kubelet/cadvisor/testing:go_default_library", "//pkg/kubelet/cadvisor/testing:go_default_library",
"//pkg/kubelet/cm:go_default_library", "//pkg/kubelet/cm:go_default_library",
@ -225,6 +227,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library", "//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
"//vendor/k8s.io/client-go/testing:go_default_library", "//vendor/k8s.io/client-go/testing:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/client-go/tools/record:go_default_library",

View File

@ -173,6 +173,34 @@ func (x Protocol) String() string {
} }
func (Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{0} } func (Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{0} }
type MountPropagation int32
const (
// No mount propagation ("private" in Linux terminology).
MountPropagation_PROPAGATION_PRIVATE MountPropagation = 0
// Mounts get propagated from the host to the container ("rslave" in Linux).
MountPropagation_PROPAGATION_HOST_TO_CONTAINER MountPropagation = 1
// Mounts get propagated from the host to the container and from the
// container to the host ("rshared" in Linux).
MountPropagation_PROPAGATION_BIDIRECTIONAL MountPropagation = 2
)
var MountPropagation_name = map[int32]string{
0: "PROPAGATION_PRIVATE",
1: "PROPAGATION_HOST_TO_CONTAINER",
2: "PROPAGATION_BIDIRECTIONAL",
}
var MountPropagation_value = map[string]int32{
"PROPAGATION_PRIVATE": 0,
"PROPAGATION_HOST_TO_CONTAINER": 1,
"PROPAGATION_BIDIRECTIONAL": 2,
}
func (x MountPropagation) String() string {
return proto.EnumName(MountPropagation_name, int32(x))
}
func (MountPropagation) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{1} }
type PodSandboxState int32 type PodSandboxState int32
const ( const (
@ -192,7 +220,7 @@ var PodSandboxState_value = map[string]int32{
func (x PodSandboxState) String() string { func (x PodSandboxState) String() string {
return proto.EnumName(PodSandboxState_name, int32(x)) return proto.EnumName(PodSandboxState_name, int32(x))
} }
func (PodSandboxState) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{1} } func (PodSandboxState) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} }
type ContainerState int32 type ContainerState int32
@ -219,7 +247,7 @@ var ContainerState_value = map[string]int32{
func (x ContainerState) String() string { func (x ContainerState) String() string {
return proto.EnumName(ContainerState_name, int32(x)) return proto.EnumName(ContainerState_name, int32(x))
} }
func (ContainerState) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} } func (ContainerState) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{3} }
type VersionRequest struct { type VersionRequest struct {
// Version of the kubelet runtime API. // Version of the kubelet runtime API.
@ -372,6 +400,8 @@ type Mount struct {
Readonly bool `protobuf:"varint,3,opt,name=readonly,proto3" json:"readonly,omitempty"` Readonly bool `protobuf:"varint,3,opt,name=readonly,proto3" json:"readonly,omitempty"`
// If set, the mount needs SELinux relabeling. // If set, the mount needs SELinux relabeling.
SelinuxRelabel bool `protobuf:"varint,4,opt,name=selinux_relabel,json=selinuxRelabel,proto3" json:"selinux_relabel,omitempty"` SelinuxRelabel bool `protobuf:"varint,4,opt,name=selinux_relabel,json=selinuxRelabel,proto3" json:"selinux_relabel,omitempty"`
// Requested propagation mode.
Propagation MountPropagation `protobuf:"varint,5,opt,name=propagation,proto3,enum=runtime.MountPropagation" json:"propagation,omitempty"`
} }
func (m *Mount) Reset() { *m = Mount{} } func (m *Mount) Reset() { *m = Mount{} }
@ -406,6 +436,13 @@ func (m *Mount) GetSelinuxRelabel() bool {
return false return false
} }
func (m *Mount) GetPropagation() MountPropagation {
if m != nil {
return m.Propagation
}
return MountPropagation_PROPAGATION_PRIVATE
}
// NamespaceOption provides options for Linux namespaces. // NamespaceOption provides options for Linux namespaces.
type NamespaceOption struct { type NamespaceOption struct {
// If set, use the host's network namespace. // If set, use the host's network namespace.
@ -3358,6 +3395,7 @@ func init() {
proto.RegisterType((*CpuUsage)(nil), "runtime.CpuUsage") proto.RegisterType((*CpuUsage)(nil), "runtime.CpuUsage")
proto.RegisterType((*MemoryUsage)(nil), "runtime.MemoryUsage") proto.RegisterType((*MemoryUsage)(nil), "runtime.MemoryUsage")
proto.RegisterEnum("runtime.Protocol", Protocol_name, Protocol_value) proto.RegisterEnum("runtime.Protocol", Protocol_name, Protocol_value)
proto.RegisterEnum("runtime.MountPropagation", MountPropagation_name, MountPropagation_value)
proto.RegisterEnum("runtime.PodSandboxState", PodSandboxState_name, PodSandboxState_value) proto.RegisterEnum("runtime.PodSandboxState", PodSandboxState_name, PodSandboxState_value)
proto.RegisterEnum("runtime.ContainerState", ContainerState_name, ContainerState_value) proto.RegisterEnum("runtime.ContainerState", ContainerState_name, ContainerState_value)
} }
@ -4607,6 +4645,11 @@ func (m *Mount) MarshalTo(dAtA []byte) (int, error) {
} }
i++ i++
} }
if m.Propagation != 0 {
dAtA[i] = 0x28
i++
i = encodeVarintApi(dAtA, i, uint64(m.Propagation))
}
return i, nil return i, nil
} }
@ -8364,6 +8407,9 @@ func (m *Mount) Size() (n int) {
if m.SelinuxRelabel { if m.SelinuxRelabel {
n += 2 n += 2
} }
if m.Propagation != 0 {
n += 1 + sovApi(uint64(m.Propagation))
}
return n return n
} }
@ -9951,6 +9997,7 @@ func (this *Mount) String() string {
`HostPath:` + fmt.Sprintf("%v", this.HostPath) + `,`, `HostPath:` + fmt.Sprintf("%v", this.HostPath) + `,`,
`Readonly:` + fmt.Sprintf("%v", this.Readonly) + `,`, `Readonly:` + fmt.Sprintf("%v", this.Readonly) + `,`,
`SelinuxRelabel:` + fmt.Sprintf("%v", this.SelinuxRelabel) + `,`, `SelinuxRelabel:` + fmt.Sprintf("%v", this.SelinuxRelabel) + `,`,
`Propagation:` + fmt.Sprintf("%v", this.Propagation) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@ -11838,6 +11885,25 @@ func (m *Mount) Unmarshal(dAtA []byte) error {
} }
} }
m.SelinuxRelabel = bool(v != 0) m.SelinuxRelabel = bool(v != 0)
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Propagation", wireType)
}
m.Propagation = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Propagation |= (MountPropagation(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:]) skippy, err := skipApi(dAtA[iNdEx:])
@ -24502,267 +24568,273 @@ var (
func init() { proto.RegisterFile("api.proto", fileDescriptorApi) } func init() { proto.RegisterFile("api.proto", fileDescriptorApi) }
var fileDescriptorApi = []byte{ var fileDescriptorApi = []byte{
// 4185 bytes of a gzipped FileDescriptorProto // 4276 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3b, 0x4d, 0x6f, 0x1c, 0x47, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3b, 0x4d, 0x6f, 0x1b, 0x49,
0x76, 0x9c, 0x19, 0x7e, 0xcc, 0xbc, 0xe1, 0x0c, 0x87, 0x25, 0x4a, 0x1c, 0x8d, 0x24, 0x8a, 0x6e, 0x76, 0x22, 0xa9, 0x0f, 0xf2, 0x51, 0xa4, 0xa8, 0x92, 0x2c, 0x51, 0xb4, 0x2d, 0xcb, 0xed, 0xf1,
0x59, 0xb6, 0xa4, 0x5d, 0xc9, 0x32, 0xbd, 0x96, 0x63, 0xf9, 0x4b, 0x63, 0x92, 0x32, 0x68, 0x49, 0x8c, 0xed, 0x5d, 0x7b, 0x3c, 0x9a, 0x1d, 0x4f, 0xc6, 0xf3, 0x65, 0x8e, 0x24, 0x3b, 0x1a, 0xdb,
0x14, 0xb7, 0x47, 0xf4, 0xee, 0x66, 0x03, 0x74, 0x9a, 0xd3, 0xc5, 0x61, 0xdb, 0x33, 0x5d, 0xed, 0x94, 0xb6, 0x29, 0xcd, 0xee, 0x66, 0x03, 0x74, 0x5a, 0xec, 0x12, 0xd5, 0x33, 0x64, 0x77, 0x4f,
0xee, 0x6a, 0x49, 0x0c, 0x72, 0x48, 0x2e, 0x41, 0x2e, 0x01, 0x9c, 0x63, 0x6e, 0x39, 0x04, 0x58, 0x77, 0xb5, 0x6d, 0x05, 0x39, 0x24, 0x97, 0x20, 0x97, 0x00, 0x9b, 0x63, 0x6e, 0x39, 0x04, 0x58,
0xe4, 0x92, 0x43, 0x0e, 0x41, 0x7e, 0x41, 0xb0, 0x97, 0x00, 0x01, 0x02, 0x04, 0xc9, 0x2d, 0xab, 0xe4, 0x92, 0x43, 0x0e, 0x41, 0x7e, 0x41, 0xb0, 0x97, 0x05, 0x02, 0x04, 0x08, 0x92, 0x5b, 0xd6,
0x1c, 0x72, 0x08, 0x90, 0xdf, 0xb0, 0xa8, 0xaf, 0xee, 0xea, 0xaf, 0x11, 0x29, 0x1b, 0xbb, 0x3a, 0x39, 0xe4, 0x10, 0x20, 0xbf, 0x61, 0x51, 0x5f, 0xdd, 0xd5, 0x5f, 0xb4, 0xe4, 0x19, 0xec, 0xfa,
0x4d, 0xd7, 0xab, 0x57, 0xaf, 0x5e, 0xd5, 0x7b, 0xf5, 0xbe, 0xaa, 0x06, 0x1a, 0xb6, 0xef, 0xde, 0xc4, 0xae, 0x57, 0xaf, 0x5e, 0xbd, 0x7a, 0xef, 0xd5, 0xab, 0xf7, 0x5e, 0x15, 0xa1, 0x66, 0x7a,
0xf2, 0x03, 0x42, 0x09, 0x5a, 0x08, 0x22, 0x8f, 0xba, 0x13, 0xdc, 0xbb, 0x39, 0x72, 0xe9, 0x51, 0xf6, 0x1d, 0xcf, 0x77, 0x89, 0x8b, 0xe6, 0xfc, 0xd0, 0x21, 0xf6, 0x18, 0x77, 0x6e, 0x0f, 0x6d,
0x74, 0x70, 0x6b, 0x48, 0x26, 0xef, 0x8c, 0xc8, 0x88, 0xbc, 0xc3, 0xfb, 0x0f, 0xa2, 0x43, 0xde, 0x72, 0x12, 0x1e, 0xdd, 0x19, 0xb8, 0xe3, 0x77, 0x87, 0xee, 0xd0, 0x7d, 0x97, 0xf5, 0x1f, 0x85,
0xe2, 0x0d, 0xfe, 0x25, 0xc6, 0x19, 0x37, 0xa0, 0xfd, 0x15, 0x0e, 0x42, 0x97, 0x78, 0x26, 0xfe, 0xc7, 0xac, 0xc5, 0x1a, 0xec, 0x8b, 0x8f, 0xd3, 0x6e, 0x41, 0xf3, 0x2b, 0xec, 0x07, 0xb6, 0xeb,
0x36, 0xc2, 0x21, 0x45, 0x5d, 0x58, 0x78, 0x2a, 0x20, 0xdd, 0xca, 0x7a, 0xe5, 0x5a, 0xc3, 0x54, 0xe8, 0xf8, 0xdb, 0x10, 0x07, 0x04, 0xb5, 0x61, 0xee, 0x19, 0x87, 0xb4, 0x4b, 0x1b, 0xa5, 0x1b,
0x4d, 0xe3, 0x57, 0x15, 0x58, 0x8a, 0x91, 0x43, 0x9f, 0x78, 0x21, 0x2e, 0xc7, 0x46, 0x6f, 0xc0, 0x35, 0x5d, 0x36, 0xb5, 0x5f, 0x96, 0x60, 0x21, 0x42, 0x0e, 0x3c, 0xd7, 0x09, 0x70, 0x31, 0x36,
0xa2, 0xe4, 0xc9, 0xf2, 0xec, 0x09, 0xee, 0x56, 0x79, 0x77, 0x53, 0xc2, 0x76, 0xed, 0x09, 0x46, 0xba, 0x0a, 0xf3, 0x82, 0x27, 0xc3, 0x31, 0xc7, 0xb8, 0x5d, 0x66, 0xdd, 0x75, 0x01, 0xeb, 0x99,
0x6f, 0xc3, 0x92, 0x42, 0x51, 0x44, 0x6a, 0x1c, 0xab, 0x2d, 0xc1, 0x72, 0x36, 0x74, 0x0b, 0xce, 0x63, 0x8c, 0xde, 0x81, 0x05, 0x89, 0x22, 0x89, 0x54, 0x18, 0x56, 0x53, 0x80, 0xc5, 0x6c, 0xe8,
0x28, 0x44, 0xdb, 0x77, 0x63, 0xe4, 0x59, 0x8e, 0xbc, 0x2c, 0xbb, 0xfa, 0xbe, 0x2b, 0xf1, 0x8d, 0x0e, 0x2c, 0x49, 0x44, 0xd3, 0xb3, 0x23, 0xe4, 0x69, 0x86, 0xbc, 0x28, 0xba, 0xba, 0x9e, 0x2d,
0x5f, 0x42, 0x63, 0x6b, 0x77, 0xb0, 0x49, 0xbc, 0x43, 0x77, 0xc4, 0x58, 0x0c, 0x71, 0xc0, 0xc6, 0xf0, 0xb5, 0x9f, 0x43, 0x6d, 0xbb, 0xd7, 0xdf, 0x72, 0x9d, 0x63, 0x7b, 0x48, 0x59, 0x0c, 0xb0,
0x74, 0x2b, 0xeb, 0x35, 0xc6, 0xa2, 0x6c, 0xa2, 0x1e, 0xd4, 0x43, 0x6c, 0x07, 0xc3, 0x23, 0x1c, 0x4f, 0xc7, 0xb4, 0x4b, 0x1b, 0x15, 0xca, 0xa2, 0x68, 0xa2, 0x0e, 0x54, 0x03, 0x6c, 0xfa, 0x83,
0x76, 0xab, 0xbc, 0x2b, 0x6e, 0xb3, 0x51, 0xc4, 0xa7, 0x2e, 0xf1, 0xc2, 0x6e, 0x4d, 0x8c, 0x92, 0x13, 0x1c, 0xb4, 0xcb, 0xac, 0x2b, 0x6a, 0xd3, 0x51, 0xae, 0x47, 0x6c, 0xd7, 0x09, 0xda, 0x15,
0x4d, 0xe3, 0x6f, 0x2a, 0xd0, 0xdc, 0x23, 0x01, 0x7d, 0x64, 0xfb, 0xbe, 0xeb, 0x8d, 0xd0, 0x4d, 0x3e, 0x4a, 0x34, 0xb5, 0xbf, 0x2d, 0x41, 0x7d, 0xdf, 0xf5, 0xc9, 0x53, 0xd3, 0xf3, 0x6c, 0x67,
0xa8, 0xf3, 0xbd, 0x1c, 0x92, 0x31, 0xdf, 0x83, 0xf6, 0xc6, 0xf2, 0x2d, 0xc9, 0xd2, 0xad, 0x3d, 0x88, 0x6e, 0x43, 0x95, 0xc9, 0x72, 0xe0, 0x8e, 0x98, 0x0c, 0x9a, 0x9b, 0x8b, 0x77, 0x04, 0x4b,
0xd9, 0x61, 0xc6, 0x28, 0xe8, 0x2a, 0xb4, 0x87, 0xc4, 0xa3, 0xb6, 0xeb, 0xe1, 0xc0, 0xf2, 0x49, 0x77, 0xf6, 0x45, 0x87, 0x1e, 0xa1, 0xa0, 0xeb, 0xd0, 0x1c, 0xb8, 0x0e, 0x31, 0x6d, 0x07, 0xfb,
0x40, 0xf9, 0xce, 0xcc, 0x99, 0xad, 0x18, 0xca, 0x88, 0xa3, 0x0b, 0xd0, 0x38, 0x22, 0x21, 0x15, 0x86, 0xe7, 0xfa, 0x84, 0x49, 0x66, 0x46, 0x6f, 0x44, 0x50, 0x4a, 0x1c, 0x5d, 0x84, 0xda, 0x89,
0x18, 0x35, 0x8e, 0x51, 0x67, 0x00, 0xde, 0xb9, 0x0a, 0x0b, 0xbc, 0xd3, 0xf5, 0xe5, 0x1e, 0xcc, 0x1b, 0x10, 0x8e, 0x51, 0x61, 0x18, 0x55, 0x0a, 0x60, 0x9d, 0xab, 0x30, 0xc7, 0x3a, 0x6d, 0x4f,
0xb3, 0xe6, 0x8e, 0x6f, 0x7c, 0x57, 0x81, 0xb9, 0x47, 0x24, 0xf2, 0x68, 0x66, 0x1a, 0x9b, 0x1e, 0xc8, 0x60, 0x96, 0x36, 0x77, 0x3d, 0xed, 0xd7, 0x25, 0x98, 0x79, 0xea, 0x86, 0x0e, 0x49, 0x4d,
0x49, 0xf9, 0x68, 0xd3, 0xd8, 0xf4, 0x28, 0x99, 0x86, 0x61, 0x08, 0x11, 0x89, 0x69, 0x58, 0x67, 0x63, 0x92, 0x13, 0xa1, 0x1f, 0x65, 0x1a, 0x93, 0x9c, 0xc4, 0xd3, 0x50, 0x0c, 0xae, 0x22, 0x3e,
0x0f, 0xea, 0x01, 0xb6, 0x1d, 0xe2, 0x8d, 0x8f, 0x39, 0x0b, 0x75, 0x33, 0x6e, 0x33, 0xd9, 0x85, 0x0d, 0xed, 0xec, 0x40, 0xd5, 0xc7, 0xa6, 0xe5, 0x3a, 0xa3, 0x53, 0xc6, 0x42, 0x55, 0x8f, 0xda,
0x78, 0xec, 0x7a, 0xd1, 0x73, 0x2b, 0xc0, 0x63, 0xfb, 0x00, 0x8f, 0x39, 0x2b, 0x75, 0xb3, 0x2d, 0x54, 0x77, 0x01, 0x1e, 0xd9, 0x4e, 0xf8, 0xc2, 0xf0, 0xf1, 0xc8, 0x3c, 0xc2, 0x23, 0xc6, 0x4a,
0xc1, 0xa6, 0x80, 0x1a, 0x5f, 0xc3, 0x12, 0x13, 0x76, 0xe8, 0xdb, 0x43, 0xfc, 0x98, 0x6f, 0x21, 0x55, 0x6f, 0x0a, 0xb0, 0xce, 0xa1, 0xe8, 0x63, 0xa8, 0x7b, 0xbe, 0xeb, 0x99, 0x43, 0x93, 0x8a,
0x53, 0x0d, 0x3e, 0xa9, 0x87, 0xe9, 0x33, 0x12, 0x7c, 0xc3, 0x39, 0xab, 0x9b, 0x4d, 0x06, 0xdb, 0xaf, 0x3d, 0xc3, 0x24, 0xb4, 0x16, 0x49, 0x88, 0x71, 0xbb, 0x1f, 0x23, 0xe8, 0x2a, 0xb6, 0xf6,
0x15, 0x20, 0x74, 0x1e, 0xea, 0x82, 0x2f, 0xd7, 0xe1, 0x6c, 0xd5, 0x4d, 0xbe, 0xe2, 0x3d, 0xd7, 0x35, 0x2c, 0x50, 0x4b, 0x09, 0x3c, 0x73, 0x80, 0xf7, 0x98, 0xfc, 0xa9, 0x5d, 0x31, 0x8e, 0x1d,
0x89, 0xbb, 0x5c, 0x7f, 0x28, 0xb9, 0x5a, 0x10, 0xab, 0x1f, 0x1a, 0x06, 0xc0, 0x8e, 0x47, 0xef, 0x4c, 0x9e, 0xbb, 0xfe, 0x37, 0x6c, 0x59, 0x55, 0xbd, 0x4e, 0x61, 0x3d, 0x0e, 0x42, 0x6b, 0x50,
0xfc, 0xe4, 0x2b, 0x7b, 0x1c, 0x61, 0xb4, 0x02, 0x73, 0x4f, 0xd9, 0x07, 0xa7, 0x5f, 0x33, 0x45, 0xe5, 0x8b, 0xb2, 0x2d, 0xb6, 0xa6, 0xaa, 0xce, 0xc4, 0xb5, 0x6f, 0x5b, 0x51, 0x97, 0xed, 0x0d,
0xc3, 0xf8, 0x8b, 0x1a, 0x5c, 0x78, 0xc8, 0x18, 0x1c, 0xd8, 0x9e, 0x73, 0x40, 0x9e, 0x0f, 0xf0, 0xc4, 0x92, 0xe6, 0xb8, 0xe8, 0x06, 0x9a, 0x06, 0xb0, 0xeb, 0x90, 0x7b, 0x3f, 0xfa, 0xca, 0x1c,
0x30, 0x0a, 0x5c, 0x7a, 0xbc, 0x49, 0x3c, 0x8a, 0x9f, 0x53, 0xb4, 0x0d, 0xcb, 0x9e, 0xe2, 0xd7, 0x85, 0x18, 0x2d, 0xc3, 0xcc, 0x33, 0xfa, 0xc1, 0xe8, 0x57, 0x74, 0xde, 0xd0, 0xfe, 0xb2, 0x02,
0x52, 0x2a, 0xc0, 0x28, 0x34, 0x37, 0xba, 0xb1, 0x5c, 0x33, 0x2b, 0x32, 0x3b, 0x5e, 0x1a, 0x10, 0x17, 0x9f, 0xd0, 0xd5, 0xf5, 0x4d, 0xc7, 0x3a, 0x72, 0x5f, 0xf4, 0xf1, 0x20, 0xf4, 0x6d, 0x72,
0xa2, 0xcf, 0x92, 0xfd, 0x51, 0x44, 0xaa, 0x9c, 0xc8, 0xb9, 0x98, 0xc8, 0x60, 0x9b, 0xf3, 0x21, 0xba, 0xe5, 0x3a, 0x04, 0xbf, 0x20, 0x68, 0x07, 0x16, 0x1d, 0xc9, 0xaf, 0x21, 0xed, 0x87, 0x52,
0x49, 0xa8, 0x7d, 0x53, 0x04, 0xde, 0x03, 0x76, 0x56, 0x2c, 0x3b, 0xb4, 0xa2, 0x10, 0x07, 0x7c, 0xa8, 0x6f, 0xb6, 0xa3, 0x25, 0xa7, 0x56, 0xa4, 0xb7, 0x9c, 0x24, 0x20, 0x40, 0x9f, 0xc7, 0xc2,
0xa5, 0xcd, 0x8d, 0x33, 0xf1, 0xe0, 0x64, 0x9d, 0x66, 0x23, 0x88, 0xbc, 0x7e, 0xb8, 0x1f, 0xe2, 0x95, 0x44, 0xca, 0x8c, 0xc8, 0x4a, 0x44, 0xa4, 0xbf, 0xc3, 0xf8, 0x10, 0x24, 0xa4, 0xd0, 0x25,
0x80, 0x9f, 0x28, 0x29, 0x21, 0x2b, 0x20, 0x84, 0x1e, 0x86, 0x4a, 0x2a, 0x0a, 0x6c, 0x72, 0x28, 0x81, 0xf7, 0x81, 0x6e, 0x34, 0xc3, 0x0c, 0x8c, 0x30, 0xc0, 0x3e, 0x5b, 0x69, 0x7d, 0x73, 0x29,
0x7a, 0x07, 0xce, 0x84, 0x91, 0xef, 0x8f, 0xf1, 0x04, 0x7b, 0xd4, 0x1e, 0x5b, 0xa3, 0x80, 0x44, 0x1a, 0x1c, 0xaf, 0x53, 0xaf, 0xf9, 0xa1, 0xd3, 0x0d, 0x0e, 0x03, 0xec, 0xb3, 0xed, 0x28, 0xd4,
0x7e, 0xd8, 0x9d, 0x5b, 0xaf, 0x5d, 0xab, 0x99, 0x48, 0xef, 0xfa, 0x82, 0xf7, 0xa0, 0x35, 0x00, 0x6b, 0xf8, 0xae, 0x4b, 0x8e, 0x03, 0xa9, 0x52, 0x09, 0xd6, 0x19, 0x14, 0xbd, 0x0b, 0x4b, 0x41,
0x3f, 0x70, 0x9f, 0xba, 0x63, 0x3c, 0xc2, 0x4e, 0x77, 0x9e, 0x13, 0xd5, 0x20, 0xe8, 0x36, 0xac, 0xe8, 0x79, 0x23, 0x3c, 0xc6, 0x0e, 0x31, 0x47, 0xc6, 0xd0, 0x77, 0x43, 0x2f, 0x68, 0xcf, 0x6c,
0x84, 0x78, 0x38, 0x24, 0x13, 0xdf, 0xf2, 0x03, 0x72, 0xe8, 0x8e, 0xb1, 0xd0, 0xa9, 0x05, 0xae, 0x54, 0x6e, 0x54, 0x74, 0xa4, 0x76, 0x3d, 0x62, 0x3d, 0x68, 0x1d, 0xc0, 0xf3, 0xed, 0x67, 0xf6,
0x53, 0x48, 0xf6, 0xed, 0x89, 0x2e, 0xa6, 0x5d, 0xc6, 0x77, 0x55, 0x38, 0xcb, 0x37, 0x60, 0x8f, 0x08, 0x0f, 0xb1, 0xd5, 0x9e, 0x65, 0x44, 0x15, 0x08, 0xba, 0x0b, 0xcb, 0x01, 0x1e, 0x0c, 0xdc,
0x38, 0x52, 0x16, 0xf2, 0xc4, 0x5e, 0x81, 0xd6, 0x90, 0x33, 0x64, 0xf9, 0x76, 0x80, 0x3d, 0x2a, 0xb1, 0x67, 0x78, 0xbe, 0x7b, 0x6c, 0x8f, 0x30, 0x37, 0xc8, 0x39, 0x66, 0x90, 0x48, 0xf4, 0xed,
0x55, 0x77, 0x51, 0x00, 0xf7, 0x38, 0x0c, 0x3d, 0x86, 0x4e, 0x28, 0x45, 0x67, 0x0d, 0x85, 0xec, 0xf3, 0x2e, 0x6a, 0x9a, 0xda, 0x2f, 0xca, 0x70, 0x81, 0x09, 0x60, 0xdf, 0xb5, 0x84, 0x2e, 0xc4,
0xe4, 0x0e, 0xbf, 0x19, 0x6f, 0xd2, 0x14, 0x39, 0x9b, 0x4b, 0x61, 0x4e, 0xf0, 0x0b, 0xe1, 0x71, 0x76, 0xbf, 0x06, 0x8d, 0x01, 0x63, 0xc8, 0xf0, 0x4c, 0x1f, 0x3b, 0x44, 0xd8, 0xfd, 0x3c, 0x07,
0x38, 0xa4, 0x63, 0x71, 0xe2, 0x9b, 0x1b, 0x3f, 0x4a, 0xd3, 0xc9, 0xb2, 0x79, 0x6b, 0x20, 0xb0, 0xee, 0x33, 0x18, 0xda, 0x83, 0x56, 0x20, 0x54, 0x67, 0x0c, 0xb8, 0xee, 0x84, 0x84, 0xdf, 0x8a,
0xb7, 0x3d, 0x1a, 0x1c, 0x9b, 0x6a, 0x6c, 0xef, 0x2e, 0x2c, 0xea, 0x1d, 0xa8, 0x03, 0xb5, 0x6f, 0x84, 0x34, 0x41, 0xcf, 0xfa, 0x42, 0x90, 0x51, 0xfc, 0x5c, 0x70, 0x1a, 0x0c, 0xc8, 0x88, 0xbb,
0xf0, 0xb1, 0x5c, 0x02, 0xfb, 0x4c, 0xf4, 0x52, 0x9c, 0x37, 0xd1, 0xb8, 0x5b, 0xfd, 0x83, 0x8a, 0x8b, 0xfa, 0xe6, 0x0f, 0x92, 0x74, 0xd2, 0x6c, 0xde, 0xe9, 0x73, 0xec, 0x1d, 0x87, 0xf8, 0xa7,
0x11, 0x00, 0x4a, 0x66, 0x79, 0x84, 0xa9, 0xed, 0xd8, 0xd4, 0x46, 0x08, 0x66, 0xb9, 0x05, 0x15, 0xba, 0x1c, 0xdb, 0xb9, 0x0f, 0xf3, 0x6a, 0x07, 0x6a, 0x41, 0xe5, 0x1b, 0x7c, 0x2a, 0x96, 0x40,
0x24, 0xf8, 0x37, 0xa3, 0x1a, 0xc9, 0xa3, 0xd1, 0x30, 0xd9, 0x27, 0xba, 0x08, 0x8d, 0x58, 0x09, 0x3f, 0x63, 0xbb, 0xe4, 0x9b, 0x95, 0x37, 0xee, 0x97, 0xff, 0xa0, 0xa4, 0xf9, 0x80, 0xe2, 0x59,
0xa5, 0x19, 0x4d, 0x00, 0xcc, 0x9c, 0xd9, 0x94, 0xe2, 0x89, 0x4f, 0xb9, 0x42, 0xb4, 0x4c, 0xd5, 0x9e, 0x62, 0x62, 0x5a, 0x26, 0x31, 0x11, 0x82, 0x69, 0xe6, 0x7e, 0x39, 0x09, 0xf6, 0x4d, 0xa9,
0x34, 0xfe, 0x79, 0x16, 0x3a, 0x39, 0x09, 0x7c, 0x00, 0xf5, 0x89, 0x9c, 0x5e, 0xea, 0xfe, 0x85, 0x86, 0x62, 0x6b, 0xd4, 0x74, 0xfa, 0x89, 0x2e, 0x41, 0x2d, 0x32, 0x42, 0xe1, 0x83, 0x63, 0x00,
0xc4, 0xa6, 0xe5, 0x38, 0x34, 0x63, 0x64, 0x66, 0x32, 0xd8, 0x61, 0xd4, 0x2c, 0x7e, 0xdc, 0x66, 0xf5, 0x85, 0x26, 0x21, 0x78, 0xec, 0x11, 0x66, 0x10, 0x0d, 0x5d, 0x36, 0xb5, 0x7f, 0x99, 0x86,
0x62, 0x1d, 0x93, 0x91, 0xe5, 0xb8, 0x01, 0x1e, 0x52, 0x12, 0x1c, 0x4b, 0x2e, 0x17, 0xc7, 0x64, 0x56, 0x46, 0x03, 0x1f, 0x42, 0x75, 0x2c, 0xa6, 0x17, 0xb6, 0x7f, 0x31, 0x76, 0x88, 0x19, 0x0e,
0xb4, 0xa5, 0x60, 0xe8, 0x5d, 0x00, 0xc7, 0x0b, 0x99, 0x44, 0x0f, 0xdd, 0x11, 0xe7, 0xb5, 0xb9, 0xf5, 0x08, 0x99, 0xfa, 0x1b, 0xba, 0x19, 0x95, 0xe3, 0x22, 0x6a, 0x53, 0xb5, 0x8e, 0xdc, 0xa1,
0x81, 0xe2, 0xb9, 0x63, 0xab, 0x6e, 0x36, 0x1c, 0x2f, 0x94, 0xcc, 0x7e, 0x08, 0x2d, 0x66, 0x25, 0x61, 0xd9, 0x3e, 0x1e, 0x10, 0xd7, 0x3f, 0x15, 0x5c, 0xce, 0x8f, 0xdc, 0xe1, 0xb6, 0x84, 0xa1,
0xad, 0x89, 0x30, 0xc8, 0x42, 0x8b, 0x9b, 0x1b, 0x2b, 0x1a, 0xc7, 0xb1, 0xb5, 0x36, 0x17, 0xfd, 0xf7, 0x00, 0x2c, 0x27, 0xa0, 0x1a, 0x3d, 0xb6, 0x87, 0x8c, 0xd7, 0xfa, 0x26, 0x8a, 0xe6, 0x8e,
0xa4, 0x11, 0xa2, 0x4f, 0x60, 0x9e, 0x5b, 0xa9, 0xb0, 0x3b, 0xcf, 0xc7, 0x5c, 0x2d, 0x58, 0xa5, 0x8e, 0x04, 0xbd, 0x66, 0x39, 0x81, 0x60, 0xf6, 0x23, 0x68, 0x50, 0x17, 0x6b, 0x8c, 0xb9, 0x37,
0x94, 0xf6, 0x43, 0x8e, 0x27, 0x84, 0x2d, 0x07, 0xa1, 0x87, 0xd0, 0xb4, 0x3d, 0x8f, 0x50, 0x5b, 0xe7, 0x56, 0x5c, 0xdf, 0x5c, 0x56, 0x38, 0x8e, 0x5c, 0xbd, 0x3e, 0xef, 0xc5, 0x8d, 0x00, 0x7d,
0x1c, 0xf0, 0x05, 0x4e, 0xe3, 0x46, 0x39, 0x8d, 0x7e, 0x82, 0x2c, 0x08, 0xe9, 0xc3, 0xd1, 0x4f, 0x0a, 0xb3, 0xcc, 0xc5, 0x05, 0xed, 0x59, 0x36, 0xe6, 0x7a, 0xce, 0x2a, 0x85, 0xb6, 0x9f, 0x30,
0x60, 0x8e, 0x5b, 0x80, 0x6e, 0x9d, 0xaf, 0x7a, 0x6d, 0xba, 0xfa, 0x99, 0x02, 0xb9, 0xf7, 0x21, 0x3c, 0xae, 0x6c, 0x31, 0x08, 0x3d, 0x81, 0xba, 0xe9, 0x38, 0x2e, 0x31, 0xf9, 0x06, 0x9f, 0x63,
0x34, 0x35, 0xd6, 0x4e, 0xa3, 0x6e, 0xbd, 0x4f, 0xa1, 0x93, 0xe5, 0xe8, 0x54, 0xea, 0xba, 0x03, 0x34, 0x6e, 0x15, 0xd3, 0xe8, 0xc6, 0xc8, 0x9c, 0x90, 0x3a, 0x1c, 0xfd, 0x08, 0x66, 0x98, 0x07,
0x2b, 0x66, 0xe4, 0x25, 0x8c, 0xa9, 0x10, 0xe2, 0x5d, 0x98, 0x97, 0xf2, 0x13, 0xba, 0x73, 0xbe, 0x68, 0x57, 0xd9, 0xaa, 0xd7, 0x27, 0x9b, 0x9f, 0xce, 0x91, 0x3b, 0x1f, 0x41, 0x5d, 0x61, 0xed,
0x74, 0x47, 0x4c, 0x89, 0x68, 0x7c, 0x02, 0x67, 0x33, 0xa4, 0x64, 0x80, 0xf1, 0x26, 0xb4, 0x7d, 0x3c, 0xe6, 0xd6, 0xf9, 0x0c, 0x5a, 0x69, 0x8e, 0xce, 0x65, 0xae, 0xbb, 0xb0, 0xac, 0x87, 0x4e,
0xe2, 0x58, 0xa1, 0x00, 0x5b, 0xae, 0xa3, 0x8c, 0x81, 0x1f, 0xe3, 0xee, 0x38, 0x6c, 0xf8, 0x80, 0xcc, 0x98, 0x8c, 0x3f, 0xde, 0x83, 0x59, 0xa1, 0x3f, 0x6e, 0x3b, 0x6b, 0x85, 0x12, 0xd1, 0x05,
0x12, 0x3f, 0xcf, 0xca, 0xc9, 0x86, 0x77, 0xe1, 0x5c, 0x76, 0xb8, 0x98, 0xde, 0xf8, 0x0c, 0x56, 0xa2, 0xf6, 0x29, 0x5c, 0x48, 0x91, 0x12, 0xd1, 0xc9, 0x5b, 0xd0, 0xf4, 0x5c, 0xcb, 0x08, 0x38,
0x4d, 0x3c, 0x21, 0x4f, 0xf1, 0xab, 0x92, 0xee, 0x41, 0x37, 0x4f, 0x20, 0x21, 0x9e, 0x40, 0x07, 0xd8, 0xb0, 0x2d, 0xe9, 0x0c, 0xbc, 0x08, 0x77, 0xd7, 0xa2, 0xc3, 0xfb, 0xc4, 0xf5, 0xb2, 0xac,
0xd4, 0xa6, 0x51, 0x78, 0x3a, 0xe2, 0xd7, 0x75, 0x02, 0xd2, 0x75, 0x0a, 0x3a, 0xa8, 0x0d, 0x55, 0x9c, 0x6d, 0x78, 0x1b, 0x56, 0xd2, 0xc3, 0xf9, 0xf4, 0xda, 0xe7, 0xb0, 0xaa, 0xe3, 0xb1, 0xfb,
0xd7, 0x97, 0x83, 0xaa, 0xae, 0x6f, 0x7c, 0x06, 0x8d, 0xd8, 0x69, 0xa1, 0x8d, 0x24, 0xb8, 0xa9, 0x0c, 0xbf, 0x2e, 0xe9, 0x0e, 0xb4, 0xb3, 0x04, 0x62, 0xe2, 0x31, 0xb4, 0x4f, 0x4c, 0x12, 0x06,
0xbe, 0xc4, 0xb3, 0xc5, 0x61, 0xcf, 0x83, 0x9c, 0xb5, 0x96, 0x33, 0x6d, 0x00, 0xc4, 0x76, 0x46, 0xe7, 0x23, 0x7e, 0x53, 0x25, 0x20, 0x8e, 0x4e, 0x4e, 0x07, 0x35, 0xa1, 0x6c, 0x7b, 0x62, 0x50,
0x79, 0x4a, 0x94, 0xa7, 0x67, 0x6a, 0x58, 0xc6, 0xdf, 0xa5, 0x8c, 0x8e, 0xc6, 0xb2, 0x13, 0xb3, 0xd9, 0xf6, 0xb4, 0xcf, 0xa1, 0x16, 0x1d, 0x5a, 0x68, 0x33, 0x8e, 0x8c, 0xca, 0xaf, 0x38, 0xd9,
0xec, 0xa4, 0x8c, 0x50, 0xf5, 0x34, 0x46, 0xe8, 0x16, 0xcc, 0x85, 0xd4, 0xa6, 0xc2, 0x0c, 0xb6, 0xa2, 0x98, 0xe9, 0x71, 0xc6, 0x5b, 0x8b, 0x99, 0x36, 0x01, 0x22, 0x3f, 0x23, 0x4f, 0x4a, 0x94,
0xb5, 0xc5, 0xa5, 0xa7, 0xc4, 0xa6, 0x40, 0x43, 0x97, 0x00, 0x86, 0x01, 0xb6, 0x29, 0x76, 0x2c, 0xa5, 0xa7, 0x2b, 0x58, 0xda, 0xdf, 0x27, 0x9c, 0x8e, 0xc2, 0xb2, 0x15, 0xb1, 0x6c, 0x25, 0x9c,
0x5b, 0xd8, 0xc7, 0x9a, 0xd9, 0x90, 0x90, 0x3e, 0x45, 0x77, 0x61, 0x41, 0x45, 0x2a, 0x73, 0x9c, 0x50, 0xf9, 0x3c, 0x4e, 0xe8, 0x0e, 0xcc, 0x04, 0xc4, 0x24, 0xdc, 0x0d, 0x36, 0x95, 0xc5, 0x25,
0x8d, 0xf5, 0x02, 0x82, 0xa9, 0xdd, 0x37, 0xd5, 0x80, 0xe4, 0x4c, 0xcf, 0x4f, 0x3f, 0xd3, 0x72, 0xa7, 0xc4, 0x3a, 0x47, 0x43, 0x97, 0x01, 0x06, 0x3e, 0x36, 0x09, 0xb6, 0x0c, 0x93, 0xfb, 0xc7,
0x9c, 0x40, 0xd6, 0xcc, 0xd2, 0x42, 0xa9, 0x59, 0x12, 0x23, 0x4e, 0x62, 0x96, 0xea, 0xa5, 0x66, 0x8a, 0x5e, 0x13, 0x90, 0x2e, 0x41, 0xf7, 0x61, 0x4e, 0x46, 0x2a, 0x33, 0x8c, 0x8d, 0x8d, 0x1c,
0x49, 0xd2, 0x98, 0x6a, 0x96, 0x7e, 0x9f, 0x06, 0xe6, 0x11, 0x74, 0xf3, 0x07, 0x44, 0x1a, 0x86, 0x82, 0x09, 0xe9, 0xeb, 0x72, 0x40, 0xbc, 0xa7, 0x67, 0x27, 0xef, 0x69, 0x31, 0x8e, 0x23, 0x2b,
0x77, 0x61, 0x3e, 0xe4, 0x90, 0x29, 0x46, 0x46, 0x0e, 0x91, 0x88, 0xc6, 0x7d, 0x58, 0xc9, 0x68, 0x6e, 0x69, 0xae, 0xd0, 0x2d, 0xf1, 0x11, 0x67, 0x71, 0x4b, 0xd5, 0x42, 0xb7, 0x24, 0x68, 0x4c,
0x80, 0x08, 0x14, 0x63, 0x7d, 0xa9, 0x9c, 0x48, 0x5f, 0x8c, 0xff, 0xaf, 0xe8, 0xda, 0x7b, 0xdf, 0x74, 0x4b, 0xbf, 0x4f, 0x07, 0xf3, 0x14, 0xda, 0xd9, 0x0d, 0x22, 0x1c, 0xc3, 0x7b, 0x30, 0x1b,
0x1d, 0x53, 0x1c, 0xe4, 0xb4, 0xf7, 0x3d, 0x45, 0x54, 0xa8, 0xee, 0xa5, 0x32, 0xa2, 0x22, 0x86, 0x30, 0xc8, 0x04, 0x27, 0x23, 0x86, 0x08, 0x44, 0xed, 0x21, 0x2c, 0xa7, 0x2c, 0x80, 0x07, 0x8a,
0x93, 0x9a, 0x38, 0x80, 0x36, 0x97, 0xa1, 0x15, 0xe2, 0x31, 0x77, 0x88, 0x32, 0x14, 0xf9, 0x71, 0x91, 0xbd, 0x94, 0xce, 0x64, 0x2f, 0xda, 0xff, 0x97, 0x54, 0xeb, 0x7d, 0x68, 0x8f, 0x08, 0xf6,
0xc1, 0x68, 0x31, 0xaf, 0x50, 0x80, 0x81, 0x44, 0x17, 0xe2, 0x6b, 0x8d, 0x75, 0x58, 0xef, 0x1e, 0x33, 0xd6, 0xfb, 0xbe, 0x24, 0xca, 0x4d, 0xf7, 0x72, 0x11, 0x51, 0x1e, 0xc3, 0x09, 0x4b, 0xec,
0xa0, 0x3c, 0xd2, 0xa9, 0xe4, 0xf0, 0x25, 0x3b, 0xfb, 0x2c, 0xf7, 0x28, 0xb0, 0xf4, 0x87, 0x9c, 0x43, 0x93, 0xe9, 0xd0, 0x08, 0xf0, 0x88, 0x1d, 0x88, 0x22, 0x14, 0xf9, 0x61, 0xce, 0x68, 0x3e,
0x8d, 0x29, 0x42, 0x10, 0x7c, 0x9a, 0x12, 0xd1, 0xf8, 0xdb, 0x1a, 0x40, 0xd2, 0xf9, 0xda, 0x1e, 0x2f, 0x37, 0x80, 0xbe, 0x40, 0xe7, 0xea, 0x6b, 0x8c, 0x54, 0x58, 0xe7, 0x01, 0xa0, 0x2c, 0xd2,
0xfa, 0x0f, 0xe2, 0x23, 0x28, 0xa2, 0x89, 0xcb, 0x05, 0xf4, 0x0a, 0x0f, 0xdf, 0xfd, 0xf4, 0xe1, 0xb9, 0xf4, 0xf0, 0x25, 0xdd, 0xfb, 0x34, 0x71, 0xc9, 0xf1, 0xf4, 0xc7, 0x8c, 0x8d, 0x09, 0x4a,
0x13, 0x71, 0xc5, 0x9b, 0x45, 0xa3, 0x5f, 0xdb, 0x63, 0xb7, 0x09, 0xe7, 0xb2, 0xe2, 0x96, 0x87, 0xe0, 0x7c, 0xea, 0x02, 0x51, 0xfb, 0xbb, 0x0a, 0x40, 0xdc, 0xf9, 0xc6, 0x6e, 0xfa, 0x0f, 0xa3,
0xee, 0x3a, 0xcc, 0xb9, 0x14, 0x4f, 0x44, 0x26, 0xad, 0xa7, 0x23, 0x1a, 0xae, 0xc0, 0x30, 0xde, 0x2d, 0xc8, 0xa3, 0x89, 0x2b, 0x39, 0xf4, 0x72, 0x37, 0xdf, 0xc3, 0xe4, 0xe6, 0xe3, 0x71, 0xc5,
0x80, 0xc6, 0xce, 0xc4, 0x1e, 0xe1, 0x81, 0x8f, 0x87, 0x6c, 0x2e, 0x97, 0x35, 0xe4, 0xfc, 0xa2, 0x5b, 0x79, 0xa3, 0xdf, 0xd8, 0x6d, 0xb7, 0x05, 0x2b, 0x69, 0x75, 0x8b, 0x4d, 0x77, 0x13, 0x66,
0x61, 0x6c, 0x40, 0xfd, 0x01, 0x3e, 0x16, 0x67, 0xf0, 0x84, 0xfc, 0x19, 0x7f, 0x55, 0x85, 0x55, 0x6c, 0x82, 0xc7, 0x3c, 0x0d, 0x57, 0xd3, 0x11, 0x05, 0x97, 0x63, 0x68, 0x57, 0xa1, 0xb6, 0x3b,
0x6e, 0x3b, 0x37, 0x55, 0x1e, 0x6b, 0xe2, 0x90, 0x44, 0xc1, 0x10, 0x87, 0x5c, 0xa4, 0x7e, 0x64, 0x36, 0x87, 0xb8, 0xef, 0xe1, 0x01, 0x9d, 0xcb, 0xa6, 0x0d, 0x31, 0x3f, 0x6f, 0x68, 0x9b, 0x50,
0xf9, 0x38, 0x70, 0x89, 0x23, 0xb3, 0xbe, 0xc6, 0xd0, 0x8f, 0xf6, 0x38, 0x80, 0xe5, 0xba, 0xac, 0x7d, 0x8c, 0x4f, 0xf9, 0x1e, 0x3c, 0x23, 0x7f, 0xda, 0x5f, 0x97, 0x61, 0x95, 0xf9, 0xce, 0x2d,
0xfb, 0xdb, 0x88, 0x48, 0xdd, 0xaa, 0x99, 0xf5, 0xa1, 0x1f, 0xfd, 0x94, 0xb5, 0xd5, 0xd8, 0xf0, 0x99, 0x04, 0xeb, 0x38, 0x70, 0x43, 0x7f, 0x80, 0x03, 0xa6, 0x52, 0x2f, 0x34, 0x3c, 0xec, 0xdb,
0xc8, 0x0e, 0x70, 0xc8, 0x75, 0x48, 0x8c, 0x1d, 0x70, 0x00, 0x7a, 0x17, 0xce, 0x4e, 0xf0, 0x84, 0xae, 0x25, 0xb2, 0xbe, 0xda, 0xc0, 0x0b, 0xf7, 0x19, 0x80, 0x26, 0xca, 0xb4, 0xfb, 0xdb, 0xd0,
0x04, 0xc7, 0xd6, 0xd8, 0x9d, 0xb8, 0xd4, 0x72, 0x3d, 0xeb, 0xe0, 0x98, 0xe2, 0x50, 0x2a, 0x0e, 0x15, 0xb6, 0x55, 0xd1, 0xab, 0x03, 0x2f, 0xfc, 0x31, 0x6d, 0xcb, 0xb1, 0xc1, 0x89, 0xe9, 0xe3,
0x12, 0x9d, 0x0f, 0x59, 0xdf, 0x8e, 0xf7, 0x39, 0xeb, 0x41, 0x06, 0xb4, 0x08, 0x99, 0x58, 0xe1, 0x80, 0xd9, 0x10, 0x1f, 0xdb, 0x67, 0x00, 0xf4, 0x1e, 0x5c, 0x18, 0xe3, 0xb1, 0xeb, 0x9f, 0x1a,
0x90, 0x04, 0xd8, 0xb2, 0x9d, 0xaf, 0xb9, 0xf3, 0xa8, 0x99, 0x4d, 0x42, 0x26, 0x03, 0x06, 0xeb, 0x23, 0x7b, 0x6c, 0x13, 0xc3, 0x76, 0x8c, 0xa3, 0x53, 0x82, 0x03, 0x61, 0x38, 0x88, 0x77, 0x3e,
0x3b, 0x5f, 0xa3, 0xcb, 0xd0, 0x1c, 0xfa, 0x51, 0x88, 0xa9, 0xc5, 0x7e, 0xb8, 0x93, 0x68, 0x98, 0xa1, 0x7d, 0xbb, 0xce, 0x17, 0xb4, 0x07, 0x69, 0xd0, 0x70, 0xdd, 0xb1, 0x11, 0x0c, 0x5c, 0x1f,
0x20, 0x40, 0x9b, 0x7e, 0x14, 0x6a, 0x08, 0x13, 0xb6, 0xed, 0x0b, 0x3a, 0xc2, 0x23, 0xb6, 0xcd, 0x1b, 0xa6, 0xf5, 0x35, 0x3b, 0x3c, 0x2a, 0x7a, 0xdd, 0x75, 0xc7, 0x7d, 0x0a, 0xeb, 0x5a, 0x5f,
0x36, 0xb4, 0x52, 0x79, 0x24, 0xcb, 0x16, 0x78, 0xc2, 0x28, 0xb3, 0x05, 0xf6, 0xcd, 0x60, 0x01, 0xa3, 0x2b, 0x50, 0x1f, 0x78, 0x61, 0x80, 0x89, 0x41, 0x7f, 0xd8, 0x21, 0x51, 0xd3, 0x81, 0x83,
0x19, 0xab, 0x9d, 0xe4, 0xdf, 0x0c, 0x46, 0x8f, 0x7d, 0x95, 0x2a, 0xf0, 0x6f, 0xb6, 0xe5, 0x63, 0xb6, 0xbc, 0x30, 0x50, 0x10, 0xc6, 0x54, 0xec, 0x73, 0x2a, 0xc2, 0x53, 0x2a, 0x66, 0x13, 0x1a,
0xfc, 0x54, 0xa6, 0xf2, 0x0d, 0x53, 0x34, 0x0c, 0x07, 0x60, 0xd3, 0xf6, 0xed, 0x03, 0x77, 0xec, 0x89, 0x3c, 0x92, 0x66, 0x0b, 0x2c, 0x61, 0x14, 0xd9, 0x02, 0xfd, 0xa6, 0x30, 0xdf, 0x1d, 0x49,
0xd2, 0x63, 0x74, 0x1d, 0x3a, 0xb6, 0xe3, 0x58, 0x43, 0x05, 0x71, 0xb1, 0xaa, 0xab, 0x2c, 0xd9, 0x49, 0xb2, 0x6f, 0x0a, 0x23, 0xa7, 0x9e, 0x4c, 0x15, 0xd8, 0x37, 0x15, 0xf9, 0x08, 0x3f, 0x13,
0x8e, 0xb3, 0xa9, 0x81, 0xd1, 0x8f, 0x60, 0xd9, 0x09, 0x88, 0x9f, 0xc6, 0x15, 0x85, 0x96, 0x0e, 0x75, 0x80, 0x9a, 0xce, 0x1b, 0x9a, 0x05, 0xb0, 0x65, 0x7a, 0xe6, 0x91, 0x3d, 0xb2, 0xc9, 0x29,
0xeb, 0xd0, 0x91, 0x8d, 0x7f, 0x9a, 0x85, 0x4b, 0x69, 0xc1, 0x66, 0x33, 0xf3, 0x0f, 0x60, 0x31, 0xba, 0x09, 0x2d, 0xd3, 0xb2, 0x8c, 0x81, 0x84, 0xd8, 0x58, 0x16, 0x65, 0x16, 0x4c, 0xcb, 0xda,
0x33, 0x6b, 0x3a, 0x25, 0x4e, 0x98, 0x34, 0x53, 0x88, 0x99, 0xdc, 0xb5, 0x9a, 0xcb, 0x5d, 0x0b, 0x52, 0xc0, 0xe8, 0x07, 0xb0, 0x68, 0xf9, 0xae, 0x97, 0xc4, 0xe5, 0x55, 0x9a, 0x16, 0xed, 0x50,
0x53, 0xfe, 0xda, 0x0f, 0x91, 0xf2, 0xcf, 0x7e, 0x9f, 0x94, 0x7f, 0xee, 0x44, 0x29, 0xff, 0x5b, 0x91, 0xb5, 0x7f, 0x9e, 0x86, 0xcb, 0x49, 0xc5, 0xa6, 0x33, 0xf3, 0x0f, 0x61, 0x3e, 0x35, 0x6b,
0xbc, 0x88, 0xa6, 0x06, 0xf1, 0xc4, 0x4b, 0xa8, 0x51, 0x2b, 0xc6, 0xf1, 0x54, 0xb1, 0x2d, 0x53, 0x32, 0x25, 0x8e, 0x99, 0xd4, 0x13, 0x88, 0xa9, 0xdc, 0xb5, 0x9c, 0xc9, 0x5d, 0x73, 0x53, 0xfe,
0x1a, 0x58, 0x38, 0x4d, 0x69, 0xa0, 0x5e, 0x5a, 0x1a, 0x60, 0x1a, 0xe1, 0xfb, 0x76, 0x30, 0x21, 0xca, 0xf7, 0x91, 0xf2, 0x4f, 0x7f, 0x97, 0x94, 0x7f, 0xe6, 0x4c, 0x29, 0xff, 0xdb, 0xac, 0x02,
0x81, 0xca, 0xfd, 0xbb, 0x0d, 0xce, 0xc2, 0x92, 0x82, 0xcb, 0xbc, 0xbf, 0xb4, 0x4a, 0x00, 0x65, 0x27, 0x07, 0xb1, 0xc4, 0x8b, 0x9b, 0x51, 0x23, 0xc2, 0x71, 0x64, 0xa5, 0x2e, 0x55, 0x1a, 0x98,
0x55, 0x02, 0xb4, 0x0e, 0x8b, 0x1e, 0xb1, 0x3c, 0xfc, 0xcc, 0x62, 0x02, 0x0b, 0xbb, 0x4d, 0x21, 0x3b, 0x4f, 0x69, 0xa0, 0x5a, 0x58, 0x1a, 0xa0, 0x16, 0xe1, 0x79, 0xa6, 0x3f, 0x76, 0x7d, 0x99,
0x3d, 0x8f, 0xec, 0xe2, 0x67, 0x7b, 0x0c, 0x62, 0xfc, 0x7d, 0x05, 0x56, 0xd2, 0x8a, 0x23, 0xf3, 0xfb, 0xb7, 0x6b, 0x8c, 0x85, 0x05, 0x09, 0x17, 0x79, 0x7f, 0x61, 0x95, 0x00, 0x8a, 0xaa, 0x04,
0xc2, 0x4f, 0xa1, 0x11, 0x28, 0xdb, 0x20, 0x95, 0x65, 0x3d, 0x1d, 0x7f, 0xe5, 0x6d, 0x88, 0x99, 0x68, 0x03, 0xe6, 0x1d, 0xd7, 0x70, 0xf0, 0x73, 0x83, 0x2a, 0x2c, 0x68, 0xd7, 0xb9, 0xf6, 0x1c,
0x0c, 0x41, 0x3f, 0x2d, 0xad, 0x30, 0xbc, 0x55, 0x42, 0xe6, 0x65, 0x35, 0x06, 0xa3, 0x0f, 0xcb, 0xb7, 0x87, 0x9f, 0xef, 0x53, 0x88, 0xf6, 0x0f, 0x25, 0x58, 0x4e, 0x1a, 0x8e, 0xc8, 0x0b, 0x3f,
0x31, 0xf2, 0xd4, 0xfc, 0x5e, 0xcb, 0xd7, 0xab, 0xe9, 0x7c, 0xdd, 0x83, 0xf9, 0x2d, 0xfc, 0xd4, 0x83, 0x9a, 0x2f, 0x7d, 0x83, 0x30, 0x96, 0x8d, 0x64, 0xfc, 0x95, 0xf5, 0x21, 0x7a, 0x3c, 0x04,
0x1d, 0xe2, 0x1f, 0xa4, 0xc4, 0xb7, 0x0e, 0x4d, 0x1f, 0x07, 0x13, 0x37, 0x0c, 0x63, 0xa5, 0x6f, 0xfd, 0xb8, 0xb0, 0xc2, 0xf0, 0x76, 0x01, 0x99, 0x57, 0xd5, 0x18, 0xb4, 0x2e, 0x2c, 0x46, 0xc8,
0x98, 0x3a, 0xc8, 0xf8, 0xaf, 0x39, 0x58, 0xca, 0xee, 0xec, 0x9d, 0x5c, 0x79, 0xa0, 0x97, 0x9c, 0x13, 0xf3, 0x7b, 0x25, 0x5f, 0x2f, 0x27, 0xf3, 0x75, 0x07, 0x66, 0xb7, 0xf1, 0x33, 0x7b, 0x80,
0xc2, 0xec, 0xfa, 0x34, 0x1f, 0x7d, 0x4d, 0xb9, 0x81, 0x6a, 0x26, 0x4b, 0x88, 0x3d, 0x85, 0x74, 0xbf, 0x97, 0xfa, 0xe0, 0x06, 0xd4, 0x3d, 0xec, 0x8f, 0xed, 0x20, 0x88, 0x8c, 0xbe, 0xa6, 0xab,
0x0d, 0x6c, 0xfd, 0x43, 0x32, 0x99, 0xd8, 0x9e, 0xa3, 0xca, 0xaf, 0xb2, 0xc9, 0x76, 0xcb, 0x0e, 0x20, 0xed, 0xbf, 0x66, 0x60, 0x21, 0x2d, 0xd9, 0x7b, 0x99, 0xf2, 0x40, 0x27, 0xde, 0x85, 0xe9,
0x46, 0xec, 0x68, 0x31, 0x30, 0xff, 0x66, 0x56, 0x92, 0x45, 0xdb, 0xae, 0xc7, 0xab, 0x0b, 0xfc, 0xf5, 0x29, 0x67, 0xf4, 0x0d, 0x79, 0x0c, 0x94, 0x53, 0x59, 0x42, 0x74, 0x52, 0x88, 0xa3, 0x81,
0xe0, 0x34, 0x4c, 0x90, 0xa0, 0x2d, 0x37, 0x40, 0x57, 0x61, 0x16, 0x7b, 0x4f, 0x95, 0x37, 0x4e, 0xae, 0x7f, 0xe0, 0x8e, 0xc7, 0xa6, 0x63, 0xc9, 0xda, 0xad, 0x68, 0x52, 0x69, 0x99, 0xfe, 0x90,
0xea, 0xb3, 0xca, 0xfd, 0x98, 0xbc, 0x1b, 0xbd, 0x05, 0xf3, 0x13, 0x12, 0x79, 0x54, 0xc5, 0xdd, 0x6e, 0x2d, 0x0a, 0x66, 0xdf, 0xd4, 0x4b, 0xd2, 0x68, 0xdb, 0x76, 0x58, 0x75, 0x81, 0x6d, 0x9c,
0xed, 0x18, 0x91, 0x17, 0x55, 0x4d, 0xd9, 0x8b, 0xae, 0xc3, 0x82, 0xc3, 0x65, 0xa0, 0x82, 0xeb, 0x9a, 0x0e, 0x02, 0xb4, 0x6d, 0xfb, 0xe8, 0x3a, 0x4c, 0x63, 0xe7, 0x99, 0x3c, 0x8d, 0xe3, 0xe2,
0xa5, 0xa4, 0x42, 0xc1, 0xe1, 0xa6, 0xea, 0x47, 0x1f, 0xc7, 0x71, 0x44, 0x23, 0x13, 0x09, 0x64, 0xae, 0x3c, 0x7e, 0x74, 0xd6, 0x8d, 0xde, 0x86, 0xd9, 0xb1, 0x1b, 0x3a, 0x44, 0xc6, 0xdd, 0xcd,
0x36, 0xb5, 0x30, 0x98, 0x78, 0x90, 0x0e, 0x26, 0x80, 0x93, 0xb8, 0x5e, 0x4a, 0x62, 0x7a, 0x7d, 0x64, 0x8d, 0x53, 0x17, 0xbd, 0xe8, 0x26, 0xcc, 0x59, 0x4c, 0x07, 0x32, 0xb8, 0x5e, 0x88, 0x2b,
0xe1, 0x3c, 0xd4, 0xc7, 0x64, 0x24, 0xf4, 0xa0, 0x29, 0x8a, 0xf5, 0x63, 0x32, 0xe2, 0x6a, 0xb0, 0x14, 0x0c, 0xae, 0xcb, 0x7e, 0xf4, 0x49, 0x14, 0x47, 0xd4, 0x52, 0x91, 0x40, 0x4a, 0xa8, 0xb9,
0xc2, 0x82, 0x27, 0xc7, 0xf5, 0xba, 0x8b, 0xfc, 0x78, 0x89, 0x06, 0xf3, 0x89, 0xfc, 0xc3, 0x22, 0xc1, 0xc4, 0xe3, 0x64, 0x30, 0x01, 0x8c, 0xc4, 0xcd, 0x42, 0x12, 0x93, 0xeb, 0x0b, 0x6b, 0x50,
0xde, 0x10, 0x77, 0x5b, 0xbc, 0xab, 0xc1, 0x21, 0x8f, 0xbd, 0x21, 0x77, 0xd9, 0x94, 0x1e, 0x77, 0x1d, 0xb9, 0x43, 0x6e, 0x07, 0x75, 0x5e, 0xe9, 0x1f, 0xb9, 0x43, 0x66, 0x06, 0xcb, 0x34, 0x78,
0xdb, 0x1c, 0xce, 0x3e, 0x59, 0xcc, 0x2b, 0xb2, 0x9d, 0xa5, 0x4c, 0xcc, 0x5b, 0x74, 0x3e, 0x5f, 0xb2, 0x6c, 0xa7, 0x3d, 0xcf, 0xb6, 0x17, 0x6f, 0xd0, 0x33, 0x91, 0x7d, 0x18, 0xae, 0x33, 0xc0,
0x83, 0x02, 0xc6, 0x3f, 0x56, 0xe0, 0xdc, 0x26, 0x0f, 0xf9, 0x34, 0x4b, 0x70, 0x8a, 0x04, 0x1c, 0xed, 0x06, 0xeb, 0xaa, 0x31, 0xc8, 0x9e, 0x33, 0x60, 0x47, 0x36, 0x21, 0xa7, 0xed, 0x26, 0x83,
0xdd, 0x8e, 0x2b, 0x1d, 0xd9, 0x3c, 0x3a, 0xbb, 0x58, 0x89, 0x87, 0xee, 0x41, 0x5b, 0xd1, 0x94, 0xd3, 0x4f, 0x1a, 0xf3, 0xf2, 0x6c, 0x67, 0x21, 0x15, 0xf3, 0xe6, 0xed, 0xcf, 0x37, 0xa0, 0x80,
0x23, 0x6b, 0x2f, 0xab, 0x91, 0xb4, 0x42, 0xbd, 0x69, 0x7c, 0x0c, 0xab, 0x39, 0x9e, 0x65, 0x78, 0xf1, 0x4f, 0x25, 0x58, 0xd9, 0x62, 0x21, 0x9f, 0xe2, 0x09, 0xce, 0x91, 0x80, 0xa3, 0xbb, 0x51,
0xf6, 0x06, 0x2c, 0x26, 0x16, 0x21, 0x66, 0xb9, 0x19, 0xc3, 0x76, 0x1c, 0xe3, 0x2e, 0x9c, 0x1d, 0xa5, 0x23, 0x9d, 0x47, 0xa7, 0x17, 0x2b, 0xf0, 0xd0, 0x03, 0x68, 0x4a, 0x9a, 0x62, 0x64, 0xe5,
0x50, 0x3b, 0xa0, 0xb9, 0x05, 0x9f, 0x60, 0x2c, 0x2f, 0x93, 0xa4, 0xc7, 0xca, 0x4a, 0xc6, 0x00, 0x55, 0x35, 0x92, 0x46, 0xa0, 0x36, 0xb5, 0x4f, 0x60, 0x35, 0xc3, 0xb3, 0x08, 0xcf, 0xae, 0xc2,
0x56, 0x06, 0x94, 0xf8, 0xaf, 0x40, 0x94, 0x9d, 0x74, 0xb6, 0x6c, 0x12, 0x51, 0x19, 0x93, 0xa9, 0x7c, 0xec, 0x11, 0x22, 0x96, 0xeb, 0x11, 0x6c, 0xd7, 0xd2, 0xee, 0xc3, 0x85, 0x3e, 0x31, 0x7d,
0xa6, 0xb1, 0x2a, 0x8a, 0x3a, 0xf9, 0xd9, 0x3e, 0x82, 0x73, 0xa2, 0xa6, 0xf2, 0x2a, 0x8b, 0x38, 0x92, 0x59, 0xf0, 0x19, 0xc6, 0xb2, 0x32, 0x49, 0x72, 0xac, 0xa8, 0x64, 0xf4, 0x61, 0xb9, 0x4f,
0xaf, 0x2a, 0x3a, 0x79, 0xba, 0x5b, 0x70, 0x26, 0x31, 0xe5, 0x49, 0x7a, 0x78, 0x33, 0x9d, 0x1e, 0x5c, 0xef, 0x35, 0x88, 0xd2, 0x9d, 0x4e, 0x97, 0xed, 0x86, 0x44, 0xc4, 0x64, 0xb2, 0xa9, 0xad,
0xae, 0xe6, 0x65, 0x9c, 0xca, 0x0e, 0xff, 0xba, 0xaa, 0x19, 0xcc, 0x92, 0xe4, 0x70, 0x23, 0x9d, 0xf2, 0xa2, 0x4e, 0x76, 0xb6, 0x8f, 0x61, 0x85, 0xd7, 0x54, 0x5e, 0x67, 0x11, 0x6b, 0xb2, 0xa2,
0x1c, 0x5e, 0x2c, 0x21, 0x99, 0xca, 0x0d, 0xf3, 0x1a, 0x59, 0x2b, 0xd0, 0x48, 0x33, 0x97, 0x41, 0x93, 0xa5, 0xbb, 0x0d, 0x4b, 0xb1, 0x2b, 0x8f, 0xd3, 0xc3, 0xdb, 0xc9, 0xf4, 0x70, 0x35, 0xab,
0xce, 0x66, 0x8a, 0xd9, 0x19, 0xde, 0x7e, 0x27, 0x09, 0xe4, 0x8e, 0x48, 0x20, 0xe3, 0xa9, 0xe3, 0xe3, 0x44, 0x76, 0xf8, 0x37, 0x65, 0xc5, 0x61, 0x16, 0x24, 0x87, 0x9b, 0xc9, 0xe4, 0xf0, 0x52,
0x3a, 0xd7, 0xed, 0x4c, 0x02, 0xd9, 0x2d, 0x63, 0x33, 0xce, 0x1f, 0xff, 0x72, 0x16, 0x1a, 0x71, 0x01, 0xc9, 0x44, 0x6e, 0x98, 0xb5, 0xc8, 0x4a, 0x8e, 0x45, 0xea, 0x99, 0x0c, 0x72, 0x3a, 0x55,
0x5f, 0x6e, 0x63, 0xf3, 0x9b, 0x54, 0x2d, 0xd8, 0x24, 0xdd, 0x7f, 0xd5, 0x5e, 0xc5, 0x7f, 0xcd, 0xcc, 0x4e, 0xf1, 0xf6, 0x3b, 0x49, 0x20, 0x77, 0x79, 0x02, 0x19, 0x4d, 0x1d, 0xd5, 0xb9, 0xee,
0xbe, 0xcc, 0x7f, 0x5d, 0x80, 0x06, 0xff, 0xb0, 0x02, 0x7c, 0x28, 0xfd, 0x51, 0x9d, 0x03, 0x4c, 0xa6, 0x12, 0xc8, 0x76, 0x11, 0x9b, 0x51, 0xfe, 0xf8, 0x57, 0xd3, 0x50, 0x8b, 0xfa, 0x32, 0x82,
0x7c, 0x98, 0x28, 0xd4, 0xfc, 0x49, 0x14, 0x2a, 0x93, 0xa9, 0x2e, 0x64, 0x33, 0xd5, 0x3b, 0xb1, 0xcd, 0x0a, 0xa9, 0x9c, 0x23, 0x24, 0xf5, 0xfc, 0xaa, 0xbc, 0xce, 0xf9, 0x35, 0xfd, 0xaa, 0xf3,
0x87, 0x11, 0xbe, 0x68, 0x2d, 0x4f, 0xae, 0xd0, 0xb7, 0x6c, 0xa7, 0x7d, 0x8b, 0x70, 0x4f, 0x57, 0xeb, 0x22, 0xd4, 0xd8, 0x87, 0xe1, 0xe3, 0x63, 0x71, 0x1e, 0x55, 0x19, 0x40, 0xc7, 0xc7, 0xb1,
0x0a, 0x06, 0xbf, 0xb6, 0x79, 0xea, 0x43, 0x91, 0xa7, 0xea, 0x5a, 0x25, 0x0d, 0xe1, 0x06, 0x40, 0x41, 0xcd, 0x9e, 0xc5, 0xa0, 0x52, 0x99, 0xea, 0x5c, 0x3a, 0x53, 0xbd, 0x17, 0x9d, 0x30, 0xfc,
0x7c, 0xe6, 0x55, 0xb2, 0x8a, 0xf2, 0x4b, 0x33, 0x35, 0x2c, 0x66, 0x55, 0x52, 0xfb, 0x9f, 0x14, 0x2c, 0x5a, 0xcf, 0x92, 0xcb, 0x3d, 0x5b, 0x76, 0x92, 0x67, 0x0b, 0x3f, 0x9e, 0xae, 0xe5, 0x0c,
0x63, 0x4f, 0x60, 0x55, 0xfe, 0x45, 0x8f, 0x92, 0x4a, 0xea, 0x99, 0x77, 0x72, 0xa5, 0x8d, 0x93, 0x7e, 0x63, 0xf3, 0xd4, 0x27, 0x3c, 0x4f, 0x55, 0xad, 0x4a, 0x38, 0xc2, 0x4d, 0x80, 0x68, 0xcf,
0x69, 0xdd, 0xcd, 0x74, 0x65, 0xe3, 0x74, 0xea, 0x92, 0x2b, 0x6c, 0x70, 0xa7, 0x6e, 0x07, 0xb2, 0xcb, 0x64, 0x15, 0x65, 0x97, 0xa6, 0x2b, 0x58, 0xd4, 0xab, 0x24, 0xe4, 0x1f, 0x17, 0x63, 0xcf,
0x5b, 0xe4, 0xa4, 0x0d, 0x09, 0xe9, 0x53, 0x16, 0x4a, 0x1d, 0xba, 0x9e, 0x1b, 0x1e, 0x89, 0xfe, 0xe0, 0x55, 0xfe, 0x55, 0x8d, 0x92, 0x0a, 0xea, 0x99, 0xf7, 0x32, 0xa5, 0x8d, 0xb3, 0x59, 0xdd,
0x79, 0xde, 0x0f, 0x0a, 0xd4, 0xe7, 0x17, 0xd3, 0xf8, 0xb9, 0x4b, 0xad, 0x21, 0x71, 0x30, 0x57, 0xed, 0x64, 0x65, 0xe3, 0x7c, 0xe6, 0x92, 0x29, 0x6c, 0xb0, 0x43, 0xdd, 0xf4, 0x45, 0x37, 0xcf,
0xc6, 0x39, 0xb3, 0xce, 0x00, 0x9b, 0xc4, 0xc1, 0xc9, 0x01, 0xa9, 0x9f, 0xea, 0x80, 0x34, 0x32, 0x49, 0x6b, 0x02, 0xd2, 0x25, 0x34, 0x94, 0x3a, 0xb6, 0x1d, 0x3b, 0x38, 0xe1, 0xfd, 0xb3, 0xac,
0x07, 0xe4, 0x1c, 0xcc, 0x07, 0xd8, 0x0e, 0x89, 0x27, 0x13, 0x03, 0xd9, 0x62, 0xbe, 0x62, 0x82, 0x1f, 0x24, 0xa8, 0xcb, 0x6e, 0xb5, 0xf1, 0x0b, 0x9b, 0x18, 0x03, 0xd7, 0xc2, 0xcc, 0x18, 0x67,
0xc3, 0x90, 0x4d, 0x20, 0x03, 0x18, 0xd9, 0xd4, 0xc2, 0xac, 0xc5, 0xb2, 0x30, 0x6b, 0x4a, 0xc1, 0xf4, 0x2a, 0x05, 0x6c, 0xb9, 0x16, 0x8e, 0x37, 0x48, 0xf5, 0x5c, 0x1b, 0xa4, 0x96, 0xda, 0x20,
0x34, 0x13, 0x66, 0xb5, 0xca, 0xc2, 0xac, 0x93, 0xd4, 0x4b, 0xb5, 0x20, 0xb2, 0x3d, 0x35, 0x88, 0x2b, 0x30, 0xeb, 0x63, 0x33, 0x70, 0x1d, 0x91, 0x18, 0x88, 0x16, 0x3d, 0x2b, 0xc6, 0x38, 0x08,
0xd4, 0xc3, 0xb1, 0xa5, 0x54, 0x38, 0xf6, 0xfb, 0x3c, 0x53, 0x0f, 0x60, 0x35, 0x77, 0x0a, 0xe4, 0xe8, 0x04, 0x22, 0x80, 0x11, 0x4d, 0x25, 0xcc, 0x9a, 0x2f, 0x0a, 0xb3, 0x26, 0x14, 0x4c, 0x53,
0xa1, 0xba, 0x9d, 0xa9, 0xb8, 0x76, 0xcb, 0x36, 0x28, 0x2e, 0xb8, 0xfe, 0x29, 0x5c, 0xde, 0xf7, 0x61, 0x56, 0xa3, 0x28, 0xcc, 0x3a, 0x4b, 0xbd, 0x54, 0x09, 0x22, 0x9b, 0x13, 0x83, 0x48, 0x35,
0x9d, 0x4c, 0xa8, 0x22, 0x13, 0xad, 0x93, 0x47, 0x08, 0x77, 0x54, 0x54, 0x59, 0x3d, 0x61, 0x0e, 0x1c, 0x5b, 0x48, 0x84, 0x63, 0xbf, 0xcf, 0x3d, 0xf5, 0x18, 0x56, 0x33, 0xbb, 0x40, 0x6c, 0xaa,
0x27, 0xd0, 0x0d, 0x03, 0xd6, 0xcb, 0x67, 0x97, 0x2e, 0xff, 0x8f, 0x61, 0x69, 0xfb, 0x39, 0x1e, 0xbb, 0xa9, 0x8a, 0x6b, 0xbb, 0x48, 0x40, 0x51, 0xc1, 0xf5, 0xcf, 0xe0, 0xca, 0xa1, 0x67, 0xa5,
0x0e, 0x8e, 0xbd, 0xe1, 0x29, 0x38, 0xea, 0x40, 0x6d, 0x38, 0x71, 0x64, 0x29, 0x83, 0x7d, 0xea, 0x42, 0x15, 0x91, 0x68, 0x9d, 0x3d, 0x42, 0xb8, 0x27, 0xa3, 0xca, 0xf2, 0x19, 0x73, 0x38, 0x8e,
0x51, 0x4c, 0x2d, 0x1d, 0xc5, 0x58, 0xd0, 0x49, 0x66, 0x90, 0x3b, 0x79, 0x8e, 0xed, 0xa4, 0xc3, 0xae, 0x69, 0xb0, 0x51, 0x3c, 0xbb, 0x38, 0xf2, 0xff, 0x04, 0x16, 0x76, 0x5e, 0xe0, 0x41, 0xff,
0x90, 0x19, 0xf1, 0x45, 0x53, 0xb6, 0x24, 0x1c, 0x07, 0x01, 0x5f, 0xaa, 0x80, 0xe3, 0x20, 0x48, 0xd4, 0x19, 0x9c, 0x83, 0xa3, 0x16, 0x54, 0x06, 0x63, 0x4b, 0x94, 0x32, 0xe8, 0xa7, 0x1a, 0xc5,
0x9f, 0xb9, 0x5a, 0xfa, 0xcc, 0x19, 0x5f, 0x43, 0x93, 0x4d, 0xf0, 0xbd, 0xd8, 0x97, 0xa1, 0x7c, 0x54, 0x92, 0x51, 0x8c, 0x01, 0xad, 0x78, 0x06, 0x21, 0xc9, 0x15, 0x2a, 0x49, 0x8b, 0x22, 0x53,
0x2d, 0x09, 0xe5, 0xe3, 0x8c, 0x60, 0x56, 0xcb, 0x08, 0x8c, 0x75, 0x58, 0x14, 0x73, 0xc9, 0x85, 0xe2, 0xf3, 0xba, 0x68, 0x09, 0x38, 0xf6, 0x7d, 0xb6, 0x54, 0x0e, 0xc7, 0xbe, 0x9f, 0xdc, 0x73,
0x74, 0xa0, 0x16, 0x05, 0x63, 0xa5, 0x59, 0x51, 0x30, 0x36, 0xfe, 0x10, 0x5a, 0x7d, 0x4a, 0xed, 0x95, 0xe4, 0x9e, 0xd3, 0xbe, 0x86, 0x3a, 0x9d, 0xe0, 0x3b, 0xb1, 0x2f, 0x42, 0xf9, 0x4a, 0x1c,
0xe1, 0xd1, 0x29, 0xf8, 0x89, 0xe7, 0xaa, 0xea, 0xd9, 0x47, 0x8e, 0x27, 0xc3, 0x80, 0xb6, 0xa2, 0xca, 0x47, 0x19, 0xc1, 0xb4, 0x92, 0x11, 0x68, 0x1b, 0x30, 0xcf, 0xe7, 0x12, 0x0b, 0x69, 0x41,
0x5d, 0x3a, 0xff, 0x2e, 0xa0, 0x3d, 0x12, 0xd0, 0xfb, 0x24, 0x78, 0x66, 0x07, 0xce, 0xe9, 0xa2, 0x25, 0xf4, 0x47, 0xd2, 0xb2, 0x42, 0x7f, 0xa4, 0xfd, 0x11, 0x34, 0xba, 0x84, 0x98, 0x83, 0x93,
0x79, 0x04, 0xb3, 0xf2, 0x41, 0x4e, 0xed, 0xda, 0x9c, 0xc9, 0xbf, 0x8d, 0xb7, 0xe1, 0x4c, 0x8a, 0x73, 0xf0, 0x13, 0xcd, 0x55, 0x56, 0xb3, 0x8f, 0x0c, 0x4f, 0x9a, 0x06, 0x4d, 0x49, 0xbb, 0x70,
0x5e, 0xe9, 0xc4, 0x1f, 0x40, 0x93, 0x1b, 0x39, 0x19, 0xf1, 0x5d, 0xd3, 0x2b, 0x9e, 0xd3, 0x2c, 0xfe, 0x1e, 0xa0, 0x7d, 0xd7, 0x27, 0x0f, 0x5d, 0xff, 0xb9, 0xe9, 0x5b, 0xe7, 0x8b, 0xe6, 0x11,
0xa1, 0xd1, 0x87, 0x65, 0xe6, 0xc5, 0x38, 0x3c, 0x3e, 0x16, 0x3f, 0xce, 0xc4, 0x45, 0x2b, 0xe9, 0x4c, 0x8b, 0xd7, 0x3c, 0x95, 0x1b, 0x33, 0x3a, 0xfb, 0xd6, 0xde, 0x81, 0xa5, 0x04, 0xbd, 0xc2,
0xf1, 0x99, 0x98, 0xe8, 0x1f, 0x2a, 0x30, 0xc7, 0xe1, 0x39, 0x9f, 0x73, 0x01, 0x1a, 0x01, 0xf6, 0x89, 0x3f, 0x84, 0x3a, 0x73, 0x72, 0x22, 0xe2, 0xbb, 0xa1, 0x56, 0x3c, 0x27, 0x79, 0x42, 0xad,
0x89, 0x45, 0xed, 0x51, 0xfc, 0xc6, 0x89, 0x01, 0x9e, 0xd8, 0xa3, 0x90, 0x3f, 0xd1, 0x62, 0x9d, 0x0b, 0x8b, 0xf4, 0x14, 0x63, 0xf0, 0x68, 0x5b, 0xfc, 0x30, 0x15, 0x17, 0x2d, 0x27, 0xc7, 0xa7,
0x8e, 0x3b, 0xc2, 0x21, 0x55, 0x0f, 0x9d, 0x9a, 0x0c, 0xb6, 0x25, 0x40, 0x6c, 0x4b, 0x42, 0xf7, 0x62, 0xa2, 0x7f, 0x2c, 0xc1, 0x0c, 0x83, 0x67, 0xce, 0x9c, 0x8b, 0x50, 0xf3, 0xb1, 0xe7, 0x1a,
0x4f, 0x44, 0xc0, 0x33, 0x6b, 0xf2, 0x6f, 0x74, 0x55, 0xbc, 0x3d, 0x98, 0x52, 0x9e, 0xe2, 0x0f, 0xc4, 0x1c, 0x46, 0x0f, 0xa4, 0x28, 0xe0, 0xc0, 0x1c, 0x06, 0xec, 0x7d, 0x17, 0xed, 0xb4, 0xec,
0x12, 0x7a, 0x50, 0xcf, 0x54, 0xa4, 0xe2, 0xb6, 0xf1, 0x31, 0x20, 0x7d, 0xcd, 0x72, 0x53, 0xdf, 0x21, 0x0e, 0x88, 0x7c, 0x25, 0x55, 0xa7, 0xb0, 0x6d, 0x0e, 0xa2, 0x22, 0x09, 0xec, 0x3f, 0xe5,
0x82, 0x79, 0xbe, 0x25, 0xca, 0x63, 0xb7, 0xd3, 0x8b, 0x36, 0x65, 0xaf, 0xf1, 0x29, 0x20, 0xb1, 0x01, 0xcf, 0xb4, 0xce, 0xbe, 0xd1, 0x75, 0xfe, 0xf6, 0x60, 0x42, 0x79, 0x8a, 0x3d, 0x48, 0xe8,
0x8b, 0x29, 0x2f, 0x7d, 0xf2, 0x1d, 0xff, 0x08, 0xce, 0xa4, 0xc6, 0xc7, 0x57, 0xcd, 0x29, 0x02, 0x40, 0x35, 0x55, 0x91, 0x8a, 0xda, 0xda, 0x27, 0x80, 0xd4, 0x35, 0x0b, 0xa1, 0xbe, 0x0d, 0xb3,
0xd9, 0xd9, 0xe5, 0xe0, 0x7f, 0xad, 0x00, 0xf4, 0x23, 0x7a, 0x24, 0x4b, 0x21, 0xfa, 0x2a, 0x2b, 0x4c, 0x24, 0xf2, 0xc4, 0x6e, 0x26, 0x17, 0xad, 0x8b, 0x5e, 0xed, 0x33, 0x40, 0x5c, 0x8a, 0x89,
0xe9, 0x55, 0xb2, 0x3e, 0xdf, 0x0e, 0xc3, 0x67, 0x24, 0x50, 0x61, 0x68, 0xdc, 0xe6, 0x65, 0x8c, 0x53, 0xfa, 0xec, 0x12, 0xff, 0x18, 0x96, 0x12, 0xe3, 0xa3, 0xab, 0xe6, 0x04, 0x81, 0xf4, 0xec,
0x88, 0x1e, 0xa9, 0xf2, 0x2b, 0xfb, 0x46, 0x57, 0xa1, 0x2d, 0x9e, 0xa6, 0x59, 0xb6, 0xe3, 0x04, 0x62, 0xf0, 0xaf, 0x4b, 0x00, 0xdd, 0x90, 0x9c, 0x88, 0x52, 0x88, 0xba, 0xca, 0x52, 0x72, 0x95,
0x38, 0x0c, 0x65, 0x1d, 0xb6, 0x25, 0xa0, 0x7d, 0x01, 0x64, 0x68, 0xae, 0x83, 0x3d, 0xea, 0xd2, 0xb4, 0xcf, 0x33, 0x83, 0xe0, 0xb9, 0xeb, 0xcb, 0x30, 0x34, 0x6a, 0xb3, 0x32, 0x46, 0x48, 0x4e,
0x63, 0x8b, 0x92, 0x6f, 0xb0, 0x27, 0x03, 0xcc, 0x96, 0x82, 0x3e, 0x61, 0x40, 0x86, 0x16, 0xe0, 0x64, 0xf9, 0x95, 0x7e, 0xa3, 0xeb, 0xd0, 0xe4, 0xef, 0xda, 0x0c, 0xd3, 0xb2, 0x7c, 0x1c, 0x04,
0x91, 0x1b, 0xd2, 0x40, 0xa1, 0xa9, 0xba, 0xa0, 0x84, 0x72, 0x34, 0xe3, 0x57, 0x15, 0xe8, 0xec, 0xa2, 0x0e, 0xdb, 0xe0, 0xd0, 0x2e, 0x07, 0x52, 0x34, 0xdb, 0xc2, 0x0e, 0xb1, 0xc9, 0xa9, 0x41,
0x45, 0xe3, 0xb1, 0x58, 0xe4, 0x69, 0xf7, 0x12, 0xbd, 0x2d, 0xd7, 0x51, 0xcd, 0x68, 0x43, 0xb2, 0xdc, 0x6f, 0xb0, 0x23, 0x02, 0xcc, 0x86, 0x84, 0x1e, 0x50, 0x20, 0x45, 0xf3, 0xf1, 0xd0, 0x0e,
0x45, 0x72, 0x71, 0xdf, 0x3f, 0xf1, 0xbd, 0x0d, 0xcb, 0x1a, 0xa3, 0x52, 0x68, 0xa9, 0x38, 0xa2, 0x88, 0x2f, 0xd1, 0x64, 0x5d, 0x50, 0x40, 0x19, 0x9a, 0xf6, 0xcb, 0x12, 0xb4, 0xf6, 0xc3, 0xd1,
0x92, 0x8e, 0x23, 0x98, 0xa2, 0x88, 0x5c, 0xef, 0xd5, 0x16, 0x67, 0x9c, 0x85, 0x33, 0xa9, 0xf1, 0x88, 0x2f, 0xf2, 0xbc, 0xb2, 0x44, 0xef, 0x88, 0x75, 0x94, 0x53, 0xd6, 0x10, 0x8b, 0x48, 0x2c,
0xd2, 0x69, 0xdc, 0x80, 0x96, 0xbc, 0xee, 0x95, 0x4a, 0x70, 0x1e, 0xea, 0xcc, 0xbc, 0x0c, 0x5d, 0xee, 0xbb, 0x27, 0xbe, 0x77, 0x61, 0x51, 0x61, 0x54, 0x28, 0x2d, 0x11, 0x47, 0x94, 0x92, 0x71,
0x47, 0xd5, 0xdd, 0x17, 0x7c, 0xe2, 0x6c, 0xba, 0x4e, 0x60, 0xec, 0x42, 0xcb, 0x14, 0xe4, 0x25, 0x04, 0x35, 0x14, 0x9e, 0xeb, 0xbd, 0xde, 0xe2, 0xb4, 0x0b, 0xb0, 0x94, 0x18, 0x2f, 0x0e, 0x8d,
0xee, 0x27, 0xd0, 0x96, 0x97, 0xc3, 0x56, 0xea, 0x91, 0x44, 0x52, 0x24, 0x4e, 0xd1, 0x36, 0x5b, 0x5b, 0xd0, 0x10, 0xd7, 0xbd, 0xc2, 0x08, 0xd6, 0xa0, 0x4a, 0xdd, 0xcb, 0xc0, 0xb6, 0x64, 0xdd,
0x9e, 0xde, 0x34, 0x7e, 0x09, 0x3d, 0xe1, 0xd4, 0x52, 0x54, 0xd5, 0xd2, 0x3e, 0x01, 0xf5, 0x74, 0x7d, 0xce, 0x73, 0xad, 0x2d, 0xdb, 0xf2, 0xb5, 0x1e, 0x34, 0x74, 0x4e, 0x5e, 0xe0, 0x7e, 0x0a,
0xb2, 0x8c, 0x78, 0x7a, 0x58, 0x2b, 0xd0, 0x9b, 0xc6, 0x25, 0xb8, 0x50, 0x48, 0x5c, 0xae, 0xdb, 0x4d, 0x71, 0x39, 0x6c, 0x24, 0x1e, 0x49, 0xc4, 0x45, 0xe2, 0x04, 0x6d, 0xbd, 0xe1, 0xa8, 0x4d,
0x87, 0x4e, 0xd2, 0xe1, 0xb8, 0xea, 0xba, 0x81, 0x5f, 0x23, 0x54, 0xb4, 0x6b, 0x84, 0x73, 0x71, 0xed, 0xe7, 0xd0, 0xe1, 0x87, 0x5a, 0x82, 0xaa, 0x5c, 0xda, 0xa7, 0x20, 0xdf, 0x5d, 0x16, 0x11,
0xa0, 0x20, 0x0c, 0xba, 0x6c, 0x69, 0x61, 0x5d, 0xad, 0x2c, 0xac, 0x9b, 0x4d, 0x85, 0x75, 0xc6, 0x4f, 0x0e, 0x6b, 0xf8, 0x6a, 0x53, 0xbb, 0x0c, 0x17, 0x73, 0x89, 0x8b, 0x75, 0x7b, 0xd0, 0x8a,
0x97, 0xf1, 0xee, 0xc9, 0x98, 0xfa, 0x43, 0x1e, 0xd8, 0x8b, 0xb9, 0x95, 0x99, 0x38, 0x5f, 0xb0, 0x3b, 0x2c, 0x5b, 0x5e, 0x37, 0xb0, 0x6b, 0x84, 0x92, 0x72, 0x8d, 0xb0, 0x12, 0x05, 0x0a, 0xdc,
0x38, 0x81, 0x61, 0x6a, 0xc8, 0xc6, 0x12, 0xb4, 0x52, 0x06, 0xc3, 0xb8, 0x07, 0xed, 0x8c, 0x05, 0xa1, 0x8b, 0x96, 0x12, 0xd6, 0x55, 0x8a, 0xc2, 0xba, 0xe9, 0x44, 0x58, 0xa7, 0x7d, 0x19, 0x49,
0xb8, 0x95, 0x89, 0x70, 0x72, 0xdb, 0x96, 0x89, 0x6f, 0x56, 0xa4, 0x21, 0xba, 0x1f, 0xee, 0x78, 0x4f, 0xc4, 0xd4, 0x1f, 0xb1, 0xc0, 0x9e, 0xcf, 0x2d, 0xdd, 0xc4, 0x5a, 0xce, 0xe2, 0x38, 0x86,
0x87, 0x44, 0xd1, 0xbd, 0x02, 0xcd, 0xfd, 0xb2, 0x67, 0x88, 0xb3, 0xea, 0x1e, 0xeb, 0x6d, 0x58, 0xae, 0x20, 0x6b, 0x0b, 0xd0, 0x48, 0x38, 0x0c, 0xed, 0x01, 0x34, 0x53, 0x1e, 0xe0, 0x4e, 0x2a,
0x1e, 0x50, 0x12, 0xd8, 0x23, 0xbc, 0xc3, 0x4f, 0xed, 0xa1, 0x2b, 0xee, 0x69, 0xa2, 0x28, 0xb6, 0xc2, 0xc9, 0x88, 0x2d, 0x15, 0xdf, 0x2c, 0x0b, 0x47, 0xf4, 0x30, 0xd8, 0x75, 0x8e, 0x5d, 0x49,
0xdf, 0xfc, 0xdb, 0xf8, 0x8f, 0x0a, 0x2c, 0xdd, 0x77, 0xc7, 0x38, 0x3c, 0x0e, 0x29, 0x9e, 0xec, 0xf7, 0x1a, 0xd4, 0x0f, 0x8b, 0x9e, 0x21, 0x4e, 0xcb, 0x7b, 0xac, 0x77, 0x60, 0xb1, 0x4f, 0x5c,
0xf3, 0x68, 0xf7, 0x22, 0x34, 0x18, 0x37, 0x21, 0xb5, 0x27, 0xbe, 0xba, 0xe7, 0x8a, 0x01, 0x6c, 0xdf, 0x1c, 0xe2, 0x5d, 0xb6, 0x6b, 0x8f, 0x6d, 0x7e, 0x4f, 0x13, 0x86, 0x91, 0xff, 0x66, 0xdf,
0x8f, 0x42, 0x41, 0x5a, 0xe5, 0xbf, 0x7a, 0xa6, 0x91, 0x9b, 0x95, 0x45, 0xff, 0x12, 0x84, 0xde, 0xda, 0x7f, 0x94, 0x60, 0xe1, 0xa1, 0x3d, 0xc2, 0xc1, 0x69, 0x40, 0xf0, 0xf8, 0x90, 0x45, 0xbb,
0x03, 0x88, 0x42, 0xec, 0xc8, 0xbb, 0xad, 0x5a, 0xc6, 0xf5, 0xec, 0xeb, 0x37, 0x10, 0x0c, 0x4f, 0x97, 0xa0, 0x46, 0xb9, 0x09, 0x88, 0x39, 0xf6, 0xe4, 0x3d, 0x57, 0x04, 0xa0, 0x32, 0x0a, 0x38,
0x5c, 0x74, 0xbd, 0x0f, 0x4d, 0xd7, 0x23, 0x0e, 0xe6, 0x37, 0x10, 0x8e, 0xcc, 0x8d, 0x8b, 0x47, 0x69, 0x99, 0xff, 0xaa, 0x99, 0x46, 0x66, 0x56, 0x1a, 0xfd, 0x0b, 0x10, 0x7a, 0x1f, 0x20, 0x0c,
0x81, 0x40, 0xdc, 0x0f, 0xb1, 0x63, 0xfc, 0x91, 0xb4, 0xc2, 0x6a, 0xf3, 0xa4, 0x0c, 0xb6, 0x61, 0xb0, 0x25, 0xee, 0xb6, 0x2a, 0xa9, 0xa3, 0xe7, 0x50, 0xbd, 0x81, 0xa0, 0x78, 0xfc, 0xa2, 0xeb,
0x59, 0x1c, 0xe8, 0xc3, 0x78, 0xd1, 0x4a, 0xd0, 0x49, 0xc0, 0x99, 0xd9, 0x10, 0xb3, 0xe3, 0x4a, 0x03, 0xa8, 0xdb, 0x8e, 0x6b, 0x61, 0x76, 0x03, 0x61, 0x89, 0xdc, 0x38, 0x7f, 0x14, 0x70, 0xc4,
0xaf, 0xa8, 0x46, 0x18, 0x77, 0xe1, 0x6c, 0x2a, 0x2a, 0x3d, 0x4d, 0x32, 0xf7, 0x45, 0x26, 0x13, 0xc3, 0x00, 0x5b, 0xda, 0x1f, 0x0b, 0x2f, 0x2c, 0x85, 0x27, 0x74, 0xb0, 0x03, 0x8b, 0x7c, 0x43,
0x4c, 0x14, 0x44, 0xa6, 0x62, 0x4a, 0x3f, 0x4a, 0x52, 0xb1, 0x50, 0xa4, 0x62, 0xa1, 0x61, 0xc2, 0x1f, 0x47, 0x8b, 0x96, 0x8a, 0x8e, 0x03, 0xce, 0x94, 0x40, 0xf4, 0x96, 0x2d, 0x4e, 0x45, 0x39,
0xf9, 0x54, 0x82, 0x9a, 0x62, 0xe4, 0xfd, 0x8c, 0x8b, 0xbf, 0x54, 0x42, 0x2c, 0xe3, 0xeb, 0xff, 0x42, 0xbb, 0x0f, 0x17, 0x12, 0x51, 0xe9, 0x79, 0x92, 0xb9, 0x47, 0xa9, 0x4c, 0x30, 0x36, 0x10,
0xb7, 0x02, 0x2b, 0x45, 0x08, 0xaf, 0x58, 0x0a, 0xf9, 0x59, 0xc9, 0x8b, 0x83, 0xdb, 0x53, 0xb9, 0x91, 0x8a, 0x49, 0xfb, 0x28, 0x48, 0xc5, 0x02, 0x9e, 0x8a, 0x05, 0x9a, 0x0e, 0x6b, 0x89, 0x04,
0xf9, 0x9d, 0x14, 0x8d, 0x1e, 0x40, 0xaf, 0x68, 0xf7, 0xf2, 0xa2, 0xa8, 0x9d, 0x40, 0x14, 0xff, 0x35, 0xc1, 0xc8, 0x07, 0xa9, 0x23, 0xfe, 0x72, 0x01, 0xb1, 0xd4, 0x59, 0xff, 0xbf, 0x25, 0x58,
0x57, 0xd5, 0x8a, 0x7b, 0x7d, 0x4a, 0x03, 0xf7, 0x20, 0x62, 0xca, 0xfb, 0x43, 0x25, 0xe9, 0xf7, 0xce, 0x43, 0x78, 0xcd, 0x52, 0xc8, 0x4f, 0x0a, 0x5e, 0x1c, 0xdc, 0x9d, 0xc8, 0xcd, 0xef, 0xa4,
0xe2, 0x04, 0x54, 0xec, 0xdf, 0xb5, 0xfc, 0xa8, 0x64, 0xd6, 0xc2, 0x24, 0xf4, 0x71, 0x3a, 0x09, 0x68, 0xf4, 0x18, 0x3a, 0x79, 0xd2, 0xcb, 0xaa, 0xa2, 0x72, 0x06, 0x55, 0xfc, 0x5f, 0x59, 0x29,
0x15, 0x65, 0xbb, 0x9b, 0x53, 0xc9, 0xbc, 0xb6, 0x95, 0x99, 0x17, 0x15, 0x68, 0xa7, 0xe5, 0x80, 0xee, 0x75, 0x09, 0xf1, 0xed, 0xa3, 0x90, 0x1a, 0xef, 0xf7, 0x95, 0xa4, 0x3f, 0x88, 0x12, 0x50,
0x3e, 0x06, 0xb0, 0x63, 0xce, 0xa5, 0xca, 0x5f, 0x9c, 0xb6, 0x3a, 0x53, 0xc3, 0x47, 0x57, 0xa0, 0x2e, 0xbf, 0x1b, 0xd9, 0x51, 0xf1, 0xac, 0xb9, 0x49, 0xe8, 0x5e, 0x32, 0x09, 0xe5, 0x65, 0xbb,
0x36, 0xf4, 0x23, 0x29, 0x91, 0xe4, 0xfe, 0x66, 0xd3, 0x8f, 0x84, 0x01, 0x60, 0xbd, 0x2c, 0x68, 0xdb, 0x13, 0xc9, 0xbc, 0xb1, 0x95, 0x99, 0x97, 0x25, 0x68, 0x26, 0xf5, 0x80, 0x3e, 0x01, 0x30,
0x16, 0xf7, 0xf0, 0x39, 0xcb, 0xf5, 0x88, 0x83, 0x05, 0xaa, 0xc4, 0x41, 0x9f, 0x41, 0xfb, 0x59, 0x23, 0xce, 0x85, 0xc9, 0x5f, 0x9a, 0xb4, 0x3a, 0x5d, 0xc1, 0x47, 0xd7, 0xa0, 0x32, 0xf0, 0x42,
0xe0, 0x52, 0xfb, 0x60, 0x8c, 0xad, 0xb1, 0x7d, 0x8c, 0x03, 0x69, 0xb9, 0xca, 0xad, 0x4c, 0x4b, 0xa1, 0x91, 0xf8, 0xfe, 0x66, 0xcb, 0x0b, 0xb9, 0x03, 0xa0, 0xbd, 0x34, 0x68, 0xe6, 0xf7, 0xf0,
0xe1, 0x3f, 0x64, 0xe8, 0x46, 0x04, 0x75, 0x35, 0xff, 0x4b, 0x2c, 0xf2, 0x03, 0x58, 0x8d, 0x18, 0x19, 0xcf, 0xf5, 0x94, 0x81, 0x39, 0xaa, 0xc0, 0x41, 0x9f, 0x43, 0xf3, 0xb9, 0x6f, 0x13, 0xf3,
0x9a, 0xc5, 0xdf, 0x02, 0x78, 0xb6, 0x47, 0xac, 0x10, 0x33, 0xd7, 0xa4, 0xde, 0xdf, 0x15, 0x5b, 0x68, 0x84, 0x8d, 0x91, 0x79, 0x8a, 0x7d, 0xe1, 0xb9, 0x8a, 0xbd, 0x4c, 0x43, 0xe2, 0x3f, 0xa1,
0xcb, 0x15, 0x3e, 0x68, 0x93, 0x04, 0x78, 0xd7, 0xf6, 0xc8, 0x40, 0x8c, 0x30, 0x26, 0xd0, 0xd4, 0xe8, 0x5a, 0x08, 0x55, 0x39, 0xff, 0x2b, 0x3c, 0xf2, 0x63, 0x58, 0x0d, 0x29, 0x9a, 0xc1, 0xde,
0x96, 0xf3, 0x92, 0x99, 0xef, 0xc1, 0xb2, 0xba, 0x19, 0x0b, 0x31, 0x95, 0x76, 0x7d, 0xda, 0x9c, 0x02, 0x38, 0xa6, 0xe3, 0x1a, 0x01, 0xa6, 0x47, 0x93, 0x7c, 0x7f, 0x97, 0xef, 0x2d, 0x97, 0xd9,
0x4b, 0x12, 0x7d, 0x80, 0x29, 0xb7, 0xee, 0x37, 0x2e, 0x42, 0x5d, 0xfd, 0x8b, 0x01, 0x2d, 0x40, 0xa0, 0x2d, 0xd7, 0xc7, 0x3d, 0xd3, 0x71, 0xfb, 0x7c, 0x84, 0x36, 0x86, 0xba, 0xb2, 0x9c, 0x57,
0xed, 0xc9, 0xe6, 0x5e, 0x67, 0x86, 0x7d, 0xec, 0x6f, 0xed, 0x75, 0x2a, 0x37, 0xee, 0xc2, 0x52, 0xcc, 0xfc, 0x00, 0x16, 0xe5, 0xcd, 0x58, 0x80, 0x89, 0xf0, 0xeb, 0x93, 0xe6, 0x5c, 0x10, 0xe8,
0xe6, 0x7d, 0x0d, 0x5a, 0x86, 0xd6, 0xa0, 0xbf, 0xbb, 0xf5, 0xf9, 0xe3, 0x9f, 0x5b, 0xe6, 0x76, 0x7d, 0x4c, 0x98, 0x77, 0xbf, 0x75, 0x09, 0xaa, 0xf2, 0x2f, 0x10, 0x68, 0x0e, 0x2a, 0x07, 0x5b,
0x7f, 0xeb, 0x17, 0x9d, 0x19, 0xb4, 0x02, 0x1d, 0x05, 0xda, 0x7d, 0xfc, 0x44, 0x40, 0x2b, 0x37, 0xfb, 0xad, 0x29, 0xfa, 0x71, 0xb8, 0xbd, 0xdf, 0x2a, 0xdd, 0x1a, 0x43, 0x2b, 0xfd, 0xfc, 0x1f,
0xbe, 0xc9, 0xe8, 0x08, 0x46, 0x67, 0x61, 0x79, 0xf3, 0xf1, 0xee, 0x93, 0xfe, 0xce, 0xee, 0xb6, 0xad, 0xc2, 0xd2, 0xbe, 0xbe, 0xb7, 0xdf, 0x7d, 0xd4, 0x3d, 0xd8, 0xdd, 0xeb, 0x19, 0xfb, 0xfa,
0x69, 0x6d, 0x9a, 0xdb, 0xfd, 0x27, 0xdb, 0x5b, 0x9d, 0x99, 0x34, 0xd8, 0xdc, 0xdf, 0xdd, 0xdd, 0xee, 0x57, 0xdd, 0x83, 0x9d, 0xd6, 0x14, 0xba, 0x0a, 0x97, 0xd5, 0x8e, 0x3f, 0xdc, 0xeb, 0x1f,
0xd9, 0xfd, 0xa2, 0x53, 0x61, 0x54, 0x13, 0xf0, 0xf6, 0xcf, 0x77, 0x18, 0x72, 0x35, 0x8d, 0xbc, 0x18, 0x07, 0x7b, 0xc6, 0xd6, 0x5e, 0xef, 0xa0, 0xbb, 0xdb, 0xdb, 0xd1, 0x5b, 0x25, 0x74, 0x19,
0xbf, 0xfb, 0x60, 0xf7, 0xf1, 0xcf, 0x76, 0x3b, 0xb5, 0x8d, 0x7f, 0x6f, 0x41, 0x5b, 0x39, 0x71, 0xd6, 0x54, 0x94, 0x2f, 0x76, 0xb7, 0x77, 0xf5, 0x9d, 0x2d, 0xfa, 0xdd, 0x7d, 0xd2, 0x2a, 0xdf,
0x1c, 0xf0, 0xfb, 0xd3, 0x4f, 0x61, 0x41, 0xfd, 0xc1, 0x24, 0xb1, 0x1e, 0xe9, 0x7f, 0xc3, 0xf4, 0xba, 0x0f, 0x0b, 0xa9, 0xe7, 0x3c, 0x68, 0x11, 0x1a, 0xfd, 0x6e, 0x6f, 0xfb, 0x8b, 0xbd, 0x9f,
0xba, 0xf9, 0x0e, 0x19, 0x0c, 0xcd, 0xa0, 0x3d, 0x1e, 0x9c, 0x68, 0x6f, 0x99, 0x2e, 0xe9, 0xe1, 0x1a, 0xfa, 0x4e, 0x77, 0xfb, 0x67, 0xad, 0x29, 0xb4, 0x0c, 0x2d, 0x09, 0xea, 0xed, 0x1d, 0x70,
0x42, 0xee, 0xb1, 0x54, 0x6f, 0xad, 0xac, 0x3b, 0xa6, 0x38, 0x60, 0x11, 0x89, 0xfe, 0x0e, 0x15, 0x68, 0xe9, 0xd6, 0x37, 0x29, 0x93, 0xc4, 0xe8, 0x02, 0x2c, 0x46, 0x73, 0x1b, 0x5b, 0xfa, 0x4e,
0xad, 0xe9, 0x7e, 0x3b, 0xff, 0xbe, 0xb5, 0x77, 0xb9, 0xb4, 0x3f, 0x26, 0xfa, 0x0b, 0xe8, 0x64, 0xf7, 0x60, 0x67, 0xbb, 0x35, 0x95, 0x04, 0xeb, 0x87, 0xbd, 0xde, 0x6e, 0xef, 0x51, 0xab, 0x44,
0x5f, 0xa0, 0xa2, 0xa4, 0x86, 0x52, 0xf2, 0xba, 0xb5, 0xf7, 0xc6, 0x14, 0x0c, 0x9d, 0x74, 0xee, 0xa9, 0xc6, 0xe0, 0x9d, 0x9f, 0xee, 0x52, 0xe4, 0x72, 0x12, 0xf9, 0xb0, 0xf7, 0xb8, 0xb7, 0xf7,
0x15, 0xe7, 0x7a, 0xf9, 0x3b, 0xbc, 0x1c, 0xe9, 0xb2, 0xc7, 0x7d, 0x62, 0x2b, 0xd2, 0x6f, 0x90, 0x93, 0x5e, 0xab, 0xb2, 0xf9, 0xef, 0x0d, 0x68, 0xca, 0x98, 0x01, 0xfb, 0xec, 0xba, 0xf6, 0x33,
0x90, 0xfe, 0x76, 0xb2, 0xe0, 0x2d, 0x9a, 0xb6, 0x15, 0xc5, 0x8f, 0x97, 0x8c, 0x19, 0xf4, 0x15, 0x98, 0x93, 0x7f, 0x86, 0x89, 0x9d, 0x55, 0xf2, 0x9f, 0x3b, 0x9d, 0x76, 0xb6, 0x43, 0xc4, 0x5e,
0x2c, 0x65, 0xae, 0xce, 0x50, 0x32, 0xaa, 0xf8, 0x22, 0xb0, 0xb7, 0x5e, 0x8e, 0x90, 0x96, 0x9b, 0x53, 0x68, 0x9f, 0xc5, 0x42, 0xca, 0xd3, 0xa9, 0xcb, 0x6a, 0x74, 0x92, 0x79, 0x9b, 0xd5, 0x59,
0x7e, 0x31, 0x96, 0x92, 0x5b, 0xc1, 0x6d, 0x5b, 0x4a, 0x6e, 0x85, 0x37, 0x6a, 0x5c, 0xbd, 0x52, 0x2f, 0xea, 0x8e, 0x28, 0xf6, 0x69, 0x00, 0xa4, 0x3e, 0x7b, 0x45, 0xeb, 0x6a, 0x98, 0x90, 0x7d,
0xd7, 0x5f, 0x9a, 0x7a, 0x15, 0xdd, 0xb5, 0xf5, 0xd6, 0xca, 0xba, 0xf5, 0xe5, 0x67, 0xae, 0xbe, 0x4e, 0xdb, 0xb9, 0x52, 0xd8, 0x1f, 0x11, 0xfd, 0x19, 0xb4, 0xd2, 0x0f, 0x5e, 0x51, 0x5c, 0xb2,
0xb4, 0xe5, 0x17, 0xdf, 0xa8, 0xf5, 0xd6, 0xcb, 0x11, 0xb2, 0xb2, 0x4a, 0xea, 0xf0, 0x19, 0x59, 0x29, 0x78, 0x4c, 0xdb, 0xb9, 0x3a, 0x01, 0x43, 0x25, 0x9d, 0x79, 0x34, 0xba, 0x51, 0xfc, 0xec,
0xe5, 0xae, 0x7d, 0x32, 0xb2, 0xca, 0x17, 0xf0, 0xa5, 0xac, 0x32, 0x05, 0xf5, 0xcb, 0xa5, 0x05, 0x2f, 0x43, 0xba, 0xe8, 0x2d, 0x21, 0x17, 0x45, 0xf2, 0xc9, 0x13, 0x52, 0x9f, 0x6a, 0xe6, 0x3c,
0xc7, 0xbc, 0xac, 0x8a, 0x6b, 0x98, 0xc6, 0x0c, 0xfa, 0x16, 0xba, 0x65, 0x55, 0x41, 0x94, 0x38, 0x7d, 0x53, 0x44, 0x91, 0xff, 0x56, 0x4a, 0x9b, 0x42, 0x5f, 0xc1, 0x42, 0xea, 0xa6, 0x0e, 0xc5,
0xed, 0x97, 0x94, 0x2d, 0x7b, 0xd7, 0x4f, 0x80, 0x19, 0x4f, 0xd9, 0x87, 0xba, 0x2a, 0x01, 0xa2, 0xa3, 0xf2, 0xef, 0x1d, 0x3b, 0x1b, 0xc5, 0x08, 0x49, 0xbd, 0xa9, 0xf7, 0x70, 0x09, 0xbd, 0xe5,
0xc4, 0xa0, 0x64, 0xea, 0x8e, 0xbd, 0xf3, 0x05, 0x3d, 0x31, 0x89, 0xf7, 0x61, 0x96, 0x41, 0xd1, 0x5c, 0xee, 0x25, 0xf4, 0x96, 0x7b, 0x81, 0xc7, 0xcc, 0x2b, 0x71, 0xdb, 0xa6, 0x98, 0x57, 0xde,
0x4a, 0x0a, 0x49, 0x0d, 0x3d, 0x9b, 0x81, 0xc6, 0xc3, 0x3e, 0x82, 0x79, 0x51, 0x31, 0x43, 0x49, 0xd5, 0x5e, 0x67, 0xbd, 0xa8, 0x5b, 0x5d, 0x7e, 0xea, 0xa6, 0x4d, 0x59, 0x7e, 0xfe, 0x05, 0x5e,
0x2a, 0x93, 0x2a, 0xcf, 0xf5, 0x56, 0x73, 0xf0, 0x78, 0xf0, 0x97, 0xe2, 0x7f, 0x6e, 0xb2, 0xf4, 0x67, 0xa3, 0x18, 0x21, 0xad, 0xab, 0xb8, 0xec, 0x9f, 0xd2, 0x55, 0xe6, 0x96, 0x29, 0xa5, 0xab,
0x85, 0x2e, 0xa4, 0xfe, 0x4f, 0x91, 0x2e, 0xb0, 0xf5, 0x2e, 0x16, 0x77, 0xea, 0x2a, 0x92, 0x89, 0xec, 0x7d, 0x81, 0xd0, 0x55, 0xaa, 0x7e, 0x7f, 0xa5, 0xb0, 0xbe, 0x99, 0xd5, 0x55, 0x7e, 0xc9,
0x07, 0xd6, 0xca, 0x02, 0xb6, 0x9c, 0x8a, 0x14, 0x07, 0x80, 0xc6, 0x0c, 0xb2, 0x44, 0x15, 0x29, 0x54, 0x9b, 0x42, 0xdf, 0x42, 0xbb, 0xa8, 0x08, 0x89, 0xe2, 0x18, 0xe1, 0x15, 0x55, 0xd2, 0xce,
0x43, 0xd8, 0x28, 0xd6, 0xad, 0x14, 0xf1, 0x2b, 0x53, 0x71, 0xe2, 0x09, 0x0e, 0xe0, 0x4c, 0x41, 0xcd, 0x33, 0x60, 0x46, 0x53, 0x76, 0xa1, 0x2a, 0x2b, 0x8e, 0x28, 0x76, 0x28, 0xa9, 0x32, 0x67,
0x3e, 0x8c, 0xae, 0x64, 0x84, 0x5f, 0x94, 0x8a, 0xf7, 0xde, 0x9c, 0x8e, 0xa4, 0x8b, 0x48, 0xaa, 0x67, 0x2d, 0xa7, 0x27, 0x22, 0xf1, 0x01, 0x4c, 0x53, 0x28, 0x5a, 0x4e, 0x20, 0xc9, 0xa1, 0x17,
0xf7, 0x39, 0xdd, 0x26, 0x68, 0x5a, 0xbd, 0x9a, 0x83, 0xab, 0xc1, 0x1b, 0x7f, 0x5e, 0x83, 0x45, 0x52, 0xd0, 0x68, 0xd8, 0xc7, 0x30, 0xcb, 0x0b, 0x74, 0x28, 0xce, 0x9c, 0x12, 0xd5, 0xc0, 0xce,
0x51, 0xb5, 0x90, 0x3e, 0xed, 0x0b, 0x80, 0xa4, 0xb0, 0x86, 0x7a, 0xa9, 0x65, 0xa6, 0x2a, 0x8c, 0x6a, 0x06, 0x1e, 0x0d, 0xfe, 0x92, 0xff, 0x27, 0x4f, 0x54, 0xda, 0xd0, 0xc5, 0xc4, 0xdf, 0x37,
0xbd, 0x0b, 0x85, 0x7d, 0xba, 0xf0, 0xb5, 0x1a, 0x99, 0x26, 0xfc, 0x7c, 0xe5, 0x4d, 0x13, 0x7e, 0x92, 0xf5, 0xbc, 0xce, 0xa5, 0xfc, 0x4e, 0xd5, 0x44, 0x52, 0xe1, 0xc7, 0x7a, 0x51, 0x7c, 0x98,
0x41, 0x59, 0xcd, 0x98, 0x41, 0x5b, 0xd0, 0x88, 0x0b, 0x37, 0x48, 0xab, 0xf7, 0x64, 0xaa, 0x4e, 0x31, 0x91, 0xfc, 0x78, 0x53, 0x9b, 0x42, 0x06, 0x2f, 0x5a, 0xa5, 0x08, 0x6b, 0xf9, 0xb6, 0x95,
0xbd, 0x5e, 0x51, 0x97, 0xce, 0x91, 0x56, 0x8c, 0xd1, 0x38, 0xca, 0x97, 0x78, 0x34, 0x8e, 0x8a, 0x20, 0x7e, 0x6d, 0x22, 0x4e, 0x34, 0xc1, 0x11, 0x2c, 0xe5, 0xa4, 0xdf, 0xe8, 0x5a, 0x4a, 0xf9,
0xea, 0x37, 0xc9, 0xea, 0x44, 0xee, 0x99, 0x5d, 0x5d, 0x2a, 0x9d, 0xcf, 0xae, 0x2e, 0x9d, 0xae, 0x79, 0x99, 0x7f, 0xe7, 0xad, 0xc9, 0x48, 0xaa, 0x8a, 0x84, 0x79, 0xaf, 0xa8, 0x3e, 0x41, 0xb1,
0x1a, 0x33, 0x9f, 0x5f, 0xfc, 0xf5, 0x6f, 0xd6, 0x2a, 0xff, 0xf9, 0x9b, 0xb5, 0x99, 0x3f, 0x7b, 0xea, 0xd5, 0x0c, 0x5c, 0x0e, 0xde, 0xfc, 0x8b, 0x0a, 0xcc, 0xf3, 0x22, 0x89, 0x38, 0xd3, 0x1e,
0xb1, 0x56, 0xf9, 0xf5, 0x8b, 0xb5, 0xca, 0xbf, 0xbd, 0x58, 0xab, 0xfc, 0xf7, 0x8b, 0xb5, 0xca, 0x01, 0xc4, 0x75, 0x3c, 0xd4, 0x49, 0x2c, 0x33, 0x51, 0xd0, 0xec, 0x5c, 0xcc, 0xed, 0x53, 0x95,
0x77, 0xff, 0xb3, 0x36, 0x73, 0x30, 0xcf, 0xff, 0xf8, 0xf9, 0xde, 0x6f, 0x03, 0x00, 0x00, 0xff, 0xaf, 0x94, 0xe4, 0x14, 0xe5, 0x67, 0x0b, 0x7d, 0x8a, 0xf2, 0x73, 0xaa, 0x78, 0xda, 0x14, 0xda,
0xff, 0x19, 0x8a, 0xba, 0xfd, 0xac, 0x3b, 0x00, 0x00, 0x86, 0x5a, 0x54, 0x27, 0x42, 0x4a, 0x79, 0x29, 0x55, 0xe4, 0xea, 0x74, 0xf2, 0xba, 0x54, 0x8e,
0x94, 0xda, 0x8f, 0xc2, 0x51, 0xb6, 0xa2, 0xa4, 0x70, 0x94, 0x57, 0x2e, 0x8a, 0x57, 0xc7, 0x53,
0xdd, 0xf4, 0xea, 0x12, 0xd5, 0x83, 0xf4, 0xea, 0x92, 0xd9, 0xb1, 0x36, 0xf5, 0xc5, 0xa5, 0x5f,
0xfd, 0x66, 0xbd, 0xf4, 0x9f, 0xbf, 0x59, 0x9f, 0xfa, 0xf3, 0x97, 0xeb, 0xa5, 0x5f, 0xbd, 0x5c,
0x2f, 0xfd, 0xdb, 0xcb, 0xf5, 0xd2, 0x7f, 0xbf, 0x5c, 0x2f, 0xfd, 0xe2, 0x7f, 0xd6, 0xa7, 0x8e,
0x66, 0xd9, 0x9f, 0x54, 0xdf, 0xff, 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xa9, 0xc0, 0x61,
0x58, 0x3c, 0x00, 0x00,
} }

View File

@ -150,6 +150,16 @@ message PortMapping {
string host_ip = 4; string host_ip = 4;
} }
enum MountPropagation {
// No mount propagation ("private" in Linux terminology).
PROPAGATION_PRIVATE = 0;
// Mounts get propagated from the host to the container ("rslave" in Linux).
PROPAGATION_HOST_TO_CONTAINER = 1;
// Mounts get propagated from the host to the container and from the
// container to the host ("rshared" in Linux).
PROPAGATION_BIDIRECTIONAL = 2;
}
// Mount specifies a host volume to mount into a container. // Mount specifies a host volume to mount into a container.
message Mount { message Mount {
// Path of the mount within the container. // Path of the mount within the container.
@ -160,6 +170,8 @@ message Mount {
bool readonly = 3; bool readonly = 3;
// If set, the mount needs SELinux relabeling. // If set, the mount needs SELinux relabeling.
bool selinux_relabel = 4; bool selinux_relabel = 4;
// Requested propagation mode.
MountPropagation propagation = 5;
} }
// NamespaceOption provides options for Linux namespaces. // NamespaceOption provides options for Linux namespaces.

View File

@ -389,6 +389,8 @@ type Mount struct {
ReadOnly bool ReadOnly bool
// Whether the mount needs SELinux relabeling // Whether the mount needs SELinux relabeling
SELinuxRelabel bool SELinuxRelabel bool
// Requested propagation mode
Propagation runtimeapi.MountPropagation
} }
type PortMapping struct { type PortMapping struct {

View File

@ -124,29 +124,40 @@ func extractLabels(input map[string]string) (map[string]string, map[string]strin
// generateMountBindings converts the mount list to a list of strings that // generateMountBindings converts the mount list to a list of strings that
// can be understood by docker. // can be understood by docker.
// Each element in the string is in the form of: // '<HostPath>:<ContainerPath>[:options]', where 'options'
// '<HostPath>:<ContainerPath>', or // is a comma-separated list of the following strings:
// '<HostPath>:<ContainerPath>:ro', if the path is read only, or // 'ro', if the path is read only
// '<HostPath>:<ContainerPath>:Z', if the volume requires SELinux // 'Z', if the volume requires SELinux relabeling
// relabeling and the pod provides an SELinux label // propagation mode such as 'rslave'
func generateMountBindings(mounts []*runtimeapi.Mount) []string { func generateMountBindings(mounts []*runtimeapi.Mount) []string {
result := make([]string, 0, len(mounts)) result := make([]string, 0, len(mounts))
for _, m := range mounts { for _, m := range mounts {
bind := fmt.Sprintf("%s:%s", m.HostPath, m.ContainerPath) bind := fmt.Sprintf("%s:%s", m.HostPath, m.ContainerPath)
readOnly := m.Readonly var attrs []string
if readOnly { if m.Readonly {
bind += ":ro" attrs = append(attrs, "ro")
} }
// Only request relabeling if the pod provides an SELinux context. If the pod // Only request relabeling if the pod provides an SELinux context. If the pod
// does not provide an SELinux context relabeling will label the volume with // does not provide an SELinux context relabeling will label the volume with
// the container's randomly allocated MCS label. This would restrict access // the container's randomly allocated MCS label. This would restrict access
// to the volume to the container which mounts it first. // to the volume to the container which mounts it first.
if m.SelinuxRelabel { if m.SelinuxRelabel {
if readOnly { attrs = append(attrs, "Z")
bind += ",Z" }
} else { switch m.Propagation {
bind += ":Z" case runtimeapi.MountPropagation_PROPAGATION_PRIVATE:
} // noop, private is default
case runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL:
attrs = append(attrs, "rshared")
case runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER:
attrs = append(attrs, "rslave")
default:
glog.Warningf("unknown propagation mode for hostPath %q", m.HostPath)
// Falls back to "private"
}
if len(attrs) > 0 {
bind = fmt.Sprintf("%s:%s", bind, strings.Join(attrs, ","))
} }
result = append(result, bind) result = append(result, bind)
} }

View File

@ -323,3 +323,70 @@ func TestMakePortsAndBindings(t *testing.T) {
assert.Equal(t, test.portmappings, actualPortMappings) assert.Equal(t, test.portmappings, actualPortMappings)
} }
} }
func TestGenerateMountBindings(t *testing.T) {
mounts := []*runtimeapi.Mount{
// everything default
{
HostPath: "/mnt/1",
ContainerPath: "/var/lib/mysql/1",
},
// readOnly
{
HostPath: "/mnt/2",
ContainerPath: "/var/lib/mysql/2",
Readonly: true,
},
// SELinux
{
HostPath: "/mnt/3",
ContainerPath: "/var/lib/mysql/3",
SelinuxRelabel: true,
},
// Propagation private
{
HostPath: "/mnt/4",
ContainerPath: "/var/lib/mysql/4",
Propagation: runtimeapi.MountPropagation_PROPAGATION_PRIVATE,
},
// Propagation rslave
{
HostPath: "/mnt/5",
ContainerPath: "/var/lib/mysql/5",
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
},
// Propagation rshared
{
HostPath: "/mnt/6",
ContainerPath: "/var/lib/mysql/6",
Propagation: runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL,
},
// Propagation unknown (falls back to private)
{
HostPath: "/mnt/7",
ContainerPath: "/var/lib/mysql/7",
Propagation: runtimeapi.MountPropagation(42),
},
// Everything
{
HostPath: "/mnt/8",
ContainerPath: "/var/lib/mysql/8",
Readonly: true,
SelinuxRelabel: true,
Propagation: runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL,
},
}
expectedResult := []string{
"/mnt/1:/var/lib/mysql/1",
"/mnt/2:/var/lib/mysql/2:ro",
"/mnt/3:/var/lib/mysql/3:Z",
"/mnt/4:/var/lib/mysql/4",
"/mnt/5:/var/lib/mysql/5:rslave",
"/mnt/6:/var/lib/mysql/6:rshared",
"/mnt/7:/var/lib/mysql/7",
"/mnt/8:/var/lib/mysql/8:ro,Z,rshared",
}
result := generateMountBindings(mounts)
assert.Equal(t, result, expectedResult)
}

View File

@ -41,6 +41,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
utilvalidation "k8s.io/apimachinery/pkg/util/validation" utilvalidation "k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/tools/remotecommand" "k8s.io/client-go/tools/remotecommand"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
v1helper "k8s.io/kubernetes/pkg/api/v1/helper" v1helper "k8s.io/kubernetes/pkg/api/v1/helper"
@ -48,7 +49,9 @@ import (
podutil "k8s.io/kubernetes/pkg/api/v1/pod" podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/api/v1/resource" "k8s.io/kubernetes/pkg/api/v1/resource"
"k8s.io/kubernetes/pkg/api/v1/validation" "k8s.io/kubernetes/pkg/api/v1/validation"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/fieldpath" "k8s.io/kubernetes/pkg/fieldpath"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
"k8s.io/kubernetes/pkg/kubelet/cm" "k8s.io/kubernetes/pkg/kubelet/cm"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/envvars" "k8s.io/kubernetes/pkg/kubelet/envvars"
@ -188,12 +191,19 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
} }
} }
propagation, err := translateMountPropagation(mount.MountPropagation)
if err != nil {
return nil, err
}
glog.V(5).Infof("Pod %q container %q mount %q has propagation %q", format.Pod(pod), container.Name, mount.Name, propagation)
mounts = append(mounts, kubecontainer.Mount{ mounts = append(mounts, kubecontainer.Mount{
Name: mount.Name, Name: mount.Name,
ContainerPath: containerPath, ContainerPath: containerPath,
HostPath: hostPath, HostPath: hostPath,
ReadOnly: mount.ReadOnly, ReadOnly: mount.ReadOnly,
SELinuxRelabel: relabelVolume, SELinuxRelabel: relabelVolume,
Propagation: propagation,
}) })
} }
if mountEtcHostsFile { if mountEtcHostsFile {
@ -207,6 +217,26 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
return mounts, nil return mounts, nil
} }
// translateMountPropagation transforms v1.MountPropagationMode to
// runtimeapi.MountPropagation.
func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.MountPropagation, error) {
if !utilfeature.DefaultFeatureGate.Enabled(features.MountPropagation) {
// mount propagation is disabled, use private as in the old versions
return runtimeapi.MountPropagation_PROPAGATION_PRIVATE, nil
}
switch {
case mountMode == nil:
// HostToContainer is the default
return runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER, nil
case *mountMode == v1.MountPropagationHostToContainer:
return runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER, nil
case *mountMode == v1.MountPropagationBidirectional:
return runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL, nil
default:
return 0, fmt.Errorf("invalid MountPropagation mode: %q", mountMode)
}
}
// makeHostsMount makes the mountpoint for the hosts file that the containers // makeHostsMount makes the mountpoint for the hosts file that the containers
// in a pod are injected with. // in a pod are injected with.
func makeHostsMount(podDir, podIP, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) (*kubecontainer.Mount, error) { func makeHostsMount(podDir, podIP, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) (*kubecontainer.Mount, error) {

View File

@ -35,6 +35,7 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@ -42,6 +43,7 @@ import (
// api.Registry.GroupOrDie(v1.GroupName).GroupVersion.String() is changed // api.Registry.GroupOrDie(v1.GroupName).GroupVersion.String() is changed
// to "v1"? // to "v1"?
_ "k8s.io/kubernetes/pkg/api/install" _ "k8s.io/kubernetes/pkg/api/install"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
"k8s.io/kubernetes/pkg/kubelet/server/portforward" "k8s.io/kubernetes/pkg/kubelet/server/portforward"
@ -49,6 +51,10 @@ import (
) )
func TestMakeMounts(t *testing.T) { func TestMakeMounts(t *testing.T) {
bTrue := true
propagationHostToContainer := v1.MountPropagationHostToContainer
propagationBidirectional := v1.MountPropagationBidirectional
testCases := map[string]struct { testCases := map[string]struct {
container v1.Container container v1.Container
podVolumes kubecontainer.VolumeMap podVolumes kubecontainer.VolumeMap
@ -56,18 +62,20 @@ func TestMakeMounts(t *testing.T) {
expectedErrMsg string expectedErrMsg string
expectedMounts []kubecontainer.Mount expectedMounts []kubecontainer.Mount
}{ }{
"valid mounts": { "valid mounts in unprivileged container": {
podVolumes: kubecontainer.VolumeMap{ podVolumes: kubecontainer.VolumeMap{
"disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/disk"}}, "disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/disk"}},
"disk4": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/host"}}, "disk4": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/host"}},
"disk5": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/var/lib/kubelet/podID/volumes/empty/disk5"}}, "disk5": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/var/lib/kubelet/podID/volumes/empty/disk5"}},
}, },
container: v1.Container{ container: v1.Container{
Name: "container1",
VolumeMounts: []v1.VolumeMount{ VolumeMounts: []v1.VolumeMount{
{ {
MountPath: "/etc/hosts", MountPath: "/etc/hosts",
Name: "disk", Name: "disk",
ReadOnly: false, ReadOnly: false,
MountPropagation: &propagationHostToContainer,
}, },
{ {
MountPath: "/mnt/path3", MountPath: "/mnt/path3",
@ -93,6 +101,7 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/mnt/disk", HostPath: "/mnt/disk",
ReadOnly: false, ReadOnly: false,
SELinuxRelabel: false, SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
}, },
{ {
Name: "disk", Name: "disk",
@ -100,6 +109,7 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/mnt/disk", HostPath: "/mnt/disk",
ReadOnly: true, ReadOnly: true,
SELinuxRelabel: false, SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
}, },
{ {
Name: "disk4", Name: "disk4",
@ -107,6 +117,7 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/mnt/host", HostPath: "/mnt/host",
ReadOnly: false, ReadOnly: false,
SELinuxRelabel: false, SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
}, },
{ {
Name: "disk5", Name: "disk5",
@ -114,6 +125,66 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/var/lib/kubelet/podID/volumes/empty/disk5", HostPath: "/var/lib/kubelet/podID/volumes/empty/disk5",
ReadOnly: false, ReadOnly: false,
SELinuxRelabel: false, SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
},
},
expectErr: false,
},
"valid mounts in privileged container": {
podVolumes: kubecontainer.VolumeMap{
"disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/disk"}},
"disk4": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/host"}},
"disk5": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/var/lib/kubelet/podID/volumes/empty/disk5"}},
},
container: v1.Container{
Name: "container1",
VolumeMounts: []v1.VolumeMount{
{
MountPath: "/etc/hosts",
Name: "disk",
ReadOnly: false,
MountPropagation: &propagationBidirectional,
},
{
MountPath: "/mnt/path3",
Name: "disk",
ReadOnly: true,
MountPropagation: &propagationHostToContainer,
},
{
MountPath: "/mnt/path4",
Name: "disk4",
ReadOnly: false,
},
},
SecurityContext: &v1.SecurityContext{
Privileged: &bTrue,
},
},
expectedMounts: []kubecontainer.Mount{
{
Name: "disk",
ContainerPath: "/etc/hosts",
HostPath: "/mnt/disk",
ReadOnly: false,
SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL,
},
{
Name: "disk",
ContainerPath: "/mnt/path3",
HostPath: "/mnt/disk",
ReadOnly: true,
SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
},
{
Name: "disk4",
ContainerPath: "/mnt/path4",
HostPath: "/mnt/host",
ReadOnly: false,
SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
}, },
}, },
expectErr: false, expectErr: false,
@ -161,6 +232,12 @@ func TestMakeMounts(t *testing.T) {
HostNetwork: true, HostNetwork: true,
}, },
} }
// test makeMounts with enabled mount propagation
err := utilfeature.DefaultFeatureGate.Set("MountPropagation=true")
if err != nil {
t.Errorf("Failed to enable feature gate for MountPropagation: %v", err)
return
}
mounts, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes) mounts, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes)
@ -178,6 +255,24 @@ func TestMakeMounts(t *testing.T) {
} }
assert.Equal(t, tc.expectedMounts, mounts, "mounts of container %+v", tc.container) assert.Equal(t, tc.expectedMounts, mounts, "mounts of container %+v", tc.container)
// test makeMounts with disabled mount propagation
err = utilfeature.DefaultFeatureGate.Set("MountPropagation=false")
if err != nil {
t.Errorf("Failed to enable feature gate for MountPropagation: %v", err)
return
}
mounts, err = makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes)
if !tc.expectErr {
expectedPrivateMounts := []kubecontainer.Mount{}
for _, mount := range tc.expectedMounts {
// all mounts are expected to be private when mount
// propagation is disabled
mount.Propagation = runtimeapi.MountPropagation_PROPAGATION_PRIVATE
expectedPrivateMounts = append(expectedPrivateMounts, mount)
}
assert.Equal(t, expectedPrivateMounts, mounts, "mounts of container %+v", tc.container)
}
}) })
} }
} }

View File

@ -294,6 +294,7 @@ func (m *kubeGenericRuntimeManager) makeMounts(opts *kubecontainer.RunContainerO
ContainerPath: v.ContainerPath, ContainerPath: v.ContainerPath,
Readonly: v.ReadOnly, Readonly: v.ReadOnly,
SelinuxRelabel: selinuxRelabel, SelinuxRelabel: selinuxRelabel,
Propagation: v.Propagation,
} }
volumeMounts = append(volumeMounts, mount) volumeMounts = append(volumeMounts, mount)

File diff suppressed because it is too large Load Diff

View File

@ -4071,6 +4071,14 @@ message VolumeMount {
// Defaults to "" (volume's root). // Defaults to "" (volume's root).
// +optional // +optional
optional string subPath = 4; optional string subPath = 4;
// mountPropagation determines how mounts are propagated from the host
// to container and the other way around.
// When not set, MountPropagationHostToContainer is used.
// This field is alpha in 1.8 and can be reworked or removed in a future
// release.
// +optional
optional string mountPropagation = 5;
} }
// Projection that may be projected along with other supported volume types // Projection that may be projected along with other supported volume types

View File

@ -1547,8 +1547,34 @@ type VolumeMount struct {
// Defaults to "" (volume's root). // Defaults to "" (volume's root).
// +optional // +optional
SubPath string `json:"subPath,omitempty" protobuf:"bytes,4,opt,name=subPath"` SubPath string `json:"subPath,omitempty" protobuf:"bytes,4,opt,name=subPath"`
// mountPropagation determines how mounts are propagated from the host
// to container and the other way around.
// When not set, MountPropagationHostToContainer is used.
// This field is alpha in 1.8 and can be reworked or removed in a future
// release.
// +optional
MountPropagation *MountPropagationMode `json:"mountPropagation,omitempty" protobuf:"bytes,5,opt,name=mountPropagation,casttype=MountPropagationMode"`
} }
// MountPropagationMode describes mount propagation.
type MountPropagationMode string
const (
// MountPropagationHostToContainer means that the volume in a container will
// receive new mounts from the host or other containers, but filesystems
// mounted inside the container won't be propagated to the host or other
// containers.
// Note that this mode is recursively applied to all mounts in the volume
// ("rslave" in Linux terminology).
MountPropagationHostToContainer MountPropagationMode = "HostToContainer"
// MountPropagationBidirectional means that the volume in a container will
// receive new mounts from the host or other containers, and its own mounts
// will be propagated from the container to the host or other containers.
// Note that this mode is recursively applied to all mounts in the volume
// ("rshared" in Linux terminology).
MountPropagationBidirectional MountPropagationMode = "Bidirectional"
)
// EnvVar represents an environment variable present in a Container. // EnvVar represents an environment variable present in a Container.
type EnvVar struct { type EnvVar struct {
// Name of the environment variable. Must be a C_IDENTIFIER. // Name of the environment variable. Must be a C_IDENTIFIER.

View File

@ -2019,11 +2019,12 @@ func (Volume) SwaggerDoc() map[string]string {
} }
var map_VolumeMount = map[string]string{ var map_VolumeMount = map[string]string{
"": "VolumeMount describes a mounting of a Volume within a container.", "": "VolumeMount describes a mounting of a Volume within a container.",
"name": "This must match the Name of a Volume.", "name": "This must match the Name of a Volume.",
"readOnly": "Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.", "readOnly": "Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.",
"mountPath": "Path within the container at which the volume should be mounted. Must not contain ':'.", "mountPath": "Path within the container at which the volume should be mounted. Must not contain ':'.",
"subPath": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root).", "subPath": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root).",
"mountPropagation": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.",
} }
func (VolumeMount) SwaggerDoc() map[string]string { func (VolumeMount) SwaggerDoc() map[string]string {

View File

@ -1409,7 +1409,9 @@ func (in *Container) DeepCopyInto(out *Container) {
if in.VolumeMounts != nil { if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts in, out := &in.VolumeMounts, &out.VolumeMounts
*out = make([]VolumeMount, len(*in)) *out = make([]VolumeMount, len(*in))
copy(*out, *in) for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
} }
if in.LivenessProbe != nil { if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe in, out := &in.LivenessProbe, &out.LivenessProbe
@ -5933,6 +5935,15 @@ func (in *Volume) DeepCopy() *Volume {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeMount) DeepCopyInto(out *VolumeMount) { func (in *VolumeMount) DeepCopyInto(out *VolumeMount) {
*out = *in *out = *in
if in.MountPropagation != nil {
in, out := &in.MountPropagation, &out.MountPropagation
if *in == nil {
*out = nil
} else {
*out = new(MountPropagationMode)
**out = **in
}
}
return return
} }

View File

@ -142,7 +142,9 @@ func (in *PodPresetSpec) DeepCopyInto(out *PodPresetSpec) {
if in.VolumeMounts != nil { if in.VolumeMounts != nil {
in, out := &in.VolumeMounts, &out.VolumeMounts in, out := &in.VolumeMounts, &out.VolumeMounts
*out = make([]v1.VolumeMount, len(*in)) *out = make([]v1.VolumeMount, len(*in))
copy(*out, *in) for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
} }
return return
} }