<p>I have scripts that are mounted to a shared persistent volume. Part of the main Deployment chart is to run some bash scripts in the <code>initContainers</code> that will clone the scripts repository and copy/mount it to the shared persistent volume. My issue is sometimes there will be no changes in the main app or no update to the values.yaml file, so no helm upgrade will actually happen. I think this is fine but what I want to happen is have a task that will still clone the scripts repository and copy/mount it to the persistent volume. </p>

<p>I am reading about k8s Job (post-install hook) but I am not sure if this will accomplish what I need. </p>

alltej
<p>Since you are not changed anything in HELM side like values or spec/templates, the HELM will not perform any change.
In this case your code is a external source and looking by HELM perspective it is correct.</p>

<p>I can propose some alternatives to achieve what you want:</p>

<ol>
<li><strong>Use HELM with FORCE flag</strong>
Use <code>helm upgrade --force</code> to upgrade your deployment. 
By Helm <a href="https://helm.sh/docs/helm/helm_upgrade/" rel="nofollow noreferrer">docs</a>:

<blockquote>
  <p><strong>--force</strong> - force resource updates through a replacement strategy</p>
</blockquote></li>
</ol>

<p>In this case Helm will recreate all resources of your chart, consequently the pods, and then re-run <code>initContainers</code> executing your script again.</p>

<ol start="2">
<li><strong>Use a Kubernetes CronJob</strong>
In this case you will spawn a pod that will mount your volume and run a script/command you want.</li>
</ol>

<p>Example of a <a href="https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/" rel="nofollow noreferrer">Kubernetes CronJob</a>:</p>

<pre><code>apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: nice-count
spec:
  schedule: "*/2 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: nice-job
            image: alpine
            command: ['sh', '-c', 'echo "HelloWorld" &gt; /usr/share/nginx/html/index.html']
            volumeMounts:
              - mountPath: "/usr/share/nginx/html"
                name: task-pv-storage
          volumes:
            - name: task-pv-storage
              persistentVolumeClaim:
                claimName: task-pv-claim
          restartPolicy: Never
</code></pre>

<p>In this example, a CronJob will run <strong>each 2 hours</strong>, mounting the volume <code>task-pv-storage</code> on <code>/usr/share/nginx/html</code> and executing the command <code>echo "HelloWorld" &gt; /usr/share/nginx/html/index.html</code>.</p>

<p>You should trigger the CronJob mannually creating a Job with the command:</p>

<pre><code>kubectl create job --from=cronjob/&lt;CRON_JOB_NAME&gt; &lt;JOB_NAME&gt;
</code></pre>

<p>In the example above, the command looks like this:</p>

<p><code>kubectl create job --from=cronjob/nice-count nice-count-job</code></p>

<ol start="3">
<li><strong>Execute a Job manually or using CI/CD</strong>
You can execute the job directly or if you have a CI/CD solution you can create a job to run once instead use a CronJob, in this case you should use this template:</li>
</ol>

<pre><code>apiVersion: batch/v1
kind: Job
metadata:
  name: nice-count-job
spec:
  template:
    spec:
      containers:
      - image: alpine
        name: my-job
        volumeMounts:
        - mountPath: /usr/share/nginx/html
          name: task-pv-storage
        command:
        - sh
        - -c
        - echo "hello" &gt; /usr/share/nginx/html/index.html
      restartPolicy: Never
      volumes:
      - name: task-pv-storage
        persistentVolumeClaim:
          claimName: task-pv-claim
</code></pre>

<p>I've tested this examples and works in both cases.</p>

<p>Please let me know if that helped!</p>
