# Dynamically Provisioning Additional Storage in JupyterHub with User-specific Configuration

**URL:** <https://discourse.jupyter.org/t/dynamically-provisioning-additional-storage-in-jupyterhub-with-user-specific-configuration/25412>\
**Category:** Zero to JupyterHub on Kubernetes\
**Created:** [April 29, 2024, 4:10am UTC](https://discourse.jupyter.org/t/dynamically-provisioning-additional-storage-in-jupyterhub-with-user-specific-configuration/25412 "2024-04-29T04:10:11Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![csvlrs](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/csvlrs/32/13225_2.png) [@csvlrs](https://discourse.jupyter.org/u/csvlrs)\
**Post date:** [April 29, 2024, 4:10am UTC](https://discourse.jupyter.org/t/dynamically-provisioning-additional-storage-in-jupyterhub-with-user-specific-configuration/25412/1 "2024-04-29T04:10:11Z")

</div>

I have a `user_info.json` file containing user information, structured as follows:

```json
[
  { "name": "martin", "additional_storage": false, "server": []},
  { "name": "joe", "additional_storage": { "storage_account_name": "<storage_account_name>", "container_name": "<container_image>" }, "server": [{"default": true, "display_name": "server1"}, {"display_name": "server2"}]}
]

```

This file is mounted in the user’s pod at `/etc/jupyterhub`.

Upon user login, I aim to provision additional storage (PV) dynamically. This involves creating PV, PVC, and mounting them to the user pod.

I’ve successfully implemented dynamic provisioning for `profile/server` by integrating the following logic into the hub’s `values.yaml`:

```yaml
extraConfig:
  options_form: |
    import json
    async def dynamic_options_form(self):
        username = self.user.name
        with open("/etc/jupyterhub/users_info.json") as f:
            users = json.load(f)
        for user in users:
            if username == user['name']:
                self.profile_list += user.get("server") if user.get("server") else self.profile_list
                break
        return self._options_form_default()
    c.KubeSpawner.options_form = dynamic_options_form

```

However, I’m encountering difficulties replicating the same dynamic provisioning for PV.

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [May 5, 2024, 1:41pm UTC](https://discourse.jupyter.org/t/dynamically-provisioning-additional-storage-in-jupyterhub-with-user-specific-configuration/25412/2 "2024-05-05T13:41:18Z")

</div>

KubeSpawner only supports one dynamically created PVC

> <https://github.com/jupyterhub/kubespawner/blob/269f51a694928ba6ea96b25bffa1544737104041/kubespawner/spawner.py#L2702-L2713>

You could subclass KubeSpawner, and create the additional PVCs.
