<p dir="auto"><strong>Is this a request for help?</strong> (If yes, you should use our troubleshooting guide and community support channels, see <a href="http://kubernetes.io/docs/troubleshooting/" rel="nofollow">http://kubernetes.io/docs/troubleshooting/</a>.):</p>
<p dir="auto">No, this is a bug report</p>
<p dir="auto"><strong>What keywords did you search in Kubernetes issues before filing this one?</strong> (If you have found any duplicates, you should instead reply there.):</p>
<p dir="auto">Searched for: "error validating data: couldn't find type: v1beta1.StorageClass"</p>
<hr>
<p dir="auto"><strong>Is this a BUG REPORT or FEATURE REQUEST?</strong> (choose one):</p>

<p dir="auto"><strong>Kubernetes version</strong> (use <code class="notranslate">kubectl version</code>):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Client Version: version.Info{Major:&quot;1&quot;, Minor:&quot;3&quot;, GitVersion:&quot;v1.3.0+2831379&quot;, GitCommit:&quot;283137936a498aed572ee22af6774b6fb6e9fd94&quot;, GitTreeState:&quot;not a git tree&quot;, BuildDate:&quot;2016-07-05T15:40:13Z&quot;, GoVersion:&quot;go1.6.2&quot;, Compiler:&quot;gc&quot;, Platform:&quot;darwin/amd64&quot;}
Server Version: version.Info{Major:&quot;1&quot;, Minor:&quot;3&quot;, GitVersion:&quot;v1.3.5+coreos.0&quot;, GitCommit:&quot;d7a04b1c6044647f5919fadf3cecb9ee70c10fc5&quot;, GitTreeState:&quot;clean&quot;, BuildDate:&quot;2016-08-15T21:01:42Z&quot;, GoVersion:&quot;go1.6.2&quot;, Compiler:&quot;gc&quot;, Platform:&quot;linux/amd64&quot;}"><pre class="notranslate"><code class="notranslate">Client Version: version.Info{Major:"1", Minor:"3", GitVersion:"v1.3.0+2831379", GitCommit:"283137936a498aed572ee22af6774b6fb6e9fd94", GitTreeState:"not a git tree", BuildDate:"2016-07-05T15:40:13Z", GoVersion:"go1.6.2", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"3", GitVersion:"v1.3.5+coreos.0", GitCommit:"d7a04b1c6044647f5919fadf3cecb9ee70c10fc5", GitTreeState:"clean", BuildDate:"2016-08-15T21:01:42Z", GoVersion:"go1.6.2", Compiler:"gc", Platform:"linux/amd64"}
</code></pre></div>
<p dir="auto"><strong>Environment</strong>:</p>
<ul dir="auto">
<li><strong>Cloud provider or hardware configuration</strong>: AWS</li>
<li><strong>OS</strong> (e.g. from /etc/os-release): Mac OSX 10.11.5</li>
<li><strong>Kernel</strong> (e.g. <code class="notranslate">uname -a</code>): Darwin Adams-MacBook-Pro.local 15.5.0 Darwin Kernel Version 15.5.0: Tue Apr 19 18:36:36 PDT 2016; root:xnu-3248.50.21~8/RELEASE_X86_64 x86_64</li>
<li><strong>Install tools</strong>:</li>
<li><strong>Others</strong>:</li>
</ul>
<p dir="auto"><strong>What happened</strong>: I want to create a StorageClass. I ran the following code:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="kubectl create -f - &lt;&lt;EOF
kind: StorageClass
apiVersion: extensions/v1beta1
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  zone: us-east-1d
  iopsPerGB: &quot;10&quot;
EOF"><pre class="notranslate"><code class="notranslate">kubectl create -f - &lt;&lt;EOF
kind: StorageClass
apiVersion: extensions/v1beta1
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  zone: us-east-1d
  iopsPerGB: "10"
EOF
</code></pre></div>
<p dir="auto">And got the following error:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="error validating &quot;STDIN&quot;: error validating data: couldn't find type: v1beta1.StorageClass; if you choose to ignore these errors, turn validation off with --validate=false"><pre class="notranslate"><code class="notranslate">error validating "STDIN": error validating data: couldn't find type: v1beta1.StorageClass; if you choose to ignore these errors, turn validation off with --validate=false
</code></pre></div>
<p dir="auto"><strong>What you expected to happen</strong>:<br>
A StorageClass is created succesfully</p>
<p dir="auto"><strong>How to reproduce it</strong> (as minimally and precisely as possible):<br>
Run this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="kubectl create -f - &lt;&lt;EOF
kind: StorageClass
apiVersion: extensions/v1beta1
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  zone: us-east-1d
  iopsPerGB: &quot;10&quot;
EOF"><pre class="notranslate"><code class="notranslate">kubectl create -f - &lt;&lt;EOF
kind: StorageClass
apiVersion: extensions/v1beta1
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  zone: us-east-1d
  iopsPerGB: "10"
EOF
</code></pre></div>
<p dir="auto"><strong>Anything else do we need to know</strong>:</p>
<p dir="auto">Note: I'm happy to write a more formal proposal out, I just wanted to quickly float the idea and see if it makes any sense to have.</p>
<h3 dir="auto">Introduction</h3>
<p dir="auto">A hostPath volume source is probably the simplest one to define, needing only a single path. However, that simplicity comes with many assumptions and caveats.</p>
<p dir="auto">Right now, the largest caveat with a hostPath volume under Docker is that the given target will be created as an empty directory owned by root if it does not already exist. This is rarely what the user actually wants because hostPath volumes are typically used to express a dependency on an existing external file or directory.</p>
<p dir="auto">To copy from a <a href="https://github.com/appc/spec/issues/648#issuecomment-241143645" data-hovercard-type="issue" data-hovercard-url="/appc/spec/issues/648/hovercard">different comment</a>: hostPath volumes have the following uses:</p>
<h4 dir="auto">Hostpath use-cases</h4>
<ol dir="auto">
<li>Communicating with an external system that produced data, is producing data, or is listening on a unix socket, such as a user who produced a configuration directory for the application, or X and the X11 socket.</li>
<li>Communicating with external systems that will consume data created by the application; e.g. a container that produces logs at /var/log/fooApp and wishes to bindmount it to the host at /var/log/fooApp as well because the operator knows an external logging process will scan through that directory and collect them.</li>
<li>Communicating between instances of yourself: e.g. a container that bindmounts in /var/cache/appName/thumbnails for each run and populates it with any thumbnails not present, but prefers to re-use existing ones between invocations simply to avoid unneeded processing.</li>
</ol>
<h3 dir="auto">Proposed API change</h3>
<p dir="auto">I propose that the <code class="notranslate">v1.HostPathVolumeSource</code> be changed to include the following field:</p>

<ol dir="auto">
<li><code class="notranslate">type</code> - optional string of <code class="notranslate">auto|exists|file|device|socket|directory</code> - If not set, defaults to <code class="notranslate">auto</code>, whereby any existing path will be accepted, and non-existent paths be created as new directories If set to a given value, something of the given type must be present at that path. If there is nothing present, or it is not of the specified type, the pod will fail to run.</li>
</ol>
<p dir="auto"><em>Note</em>: For the default case, the presence or absence of the given path is resolved at container-runtime for any container that references the given path. For the other cases, it is resolved when the pod is placed prior to any containers being run.</p>
<h3 dir="auto">Reason for change</h3>
<p dir="auto">In the first use-case above, creating the nonexistent thing is not a desirable action and can end up breaking things (aside, docker once had a bug where it created the <code class="notranslate">docker.sock</code> after starting old containers, so any restart=always containers bindmounting the <code class="notranslate">docker.sock</code> would create a directory there and crashloop the daemon).</p>
<p dir="auto">In the second and third use-cases, you do want the directory created. I think the first use-case is, however, the most common one.</p>
<p dir="auto">Because Kubernetes runs across many machines and should value correctness, I propose that the <code class="notranslate">hostPath</code> volume should allow a user to specify additional expectations about what already exists, or does not, at that path such that it can fail quickly if those assumptions are not met, rather than mutate the host filesystem.</p>
<p dir="auto">This ensures that a host that is in an odd state (e.g. with some socket not existing that should) does not end up in a worse state, and also allows a pod to more clearly express the dependency it has such that an operator who accidentally runs it on a system it is not suited for can see quickly and clearly what went wrong.</p>
<h4 dir="auto">Other considerations</h4>
<p dir="auto">the <code class="notranslate">subPath</code> feature is also relevant because it is a way in which one can reference directories which might-or-might not exist within a volume as well. One possible way to resolve both hostPath and subPath at the same time would be making my above proposed api-changes attributes of the reference within the container, not the volume source outside of it. I think that having the attribute of the volume on the host attached to the source is neater and makes more logical sense however, so I'd prefer keeping it there. Other solutions are to simply assume subPaths should always be created, or to duplicate these options for subPath as well. Opinions welcome!</p>
<p dir="auto">The examples folder contains many examples of pods where this feature would be useful. For example:</p>
<ol dir="auto">
<li>sysdig-cloud example -- If <code class="notranslate">/boot</code> does not exist or <code class="notranslate">/var/run/docker.sock</code> is at an alternate location, this should fail to run and the operator should edit the pod, not clobber the host</li>
<li>storage/vitess example -- If <code class="notranslate">/etc/ssl/certs</code> is not present (e.g. on <code class="notranslate">/etc/pki/</code> distros) it should not be created, it should be an error</li>
<li>newrelic example -- Same as sysdig, a <code class="notranslate">docker.sock</code> reference</li>
<li>... many others in the wild I'm sure</li>
</ol>
<p dir="auto">Opinions on whether this increase in expressiveness is worth the increased API surface area. I think it is, but second opinions would be much appreciated.</p>
<p dir="auto">cc @kubernetes/sig-storage <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/thockin/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/thockin">@thockin</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/jonboulle/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/jonboulle">@jonboulle</a></p>