Zero-to-jupyterhub-k8s: How to add some files in user home?

Created on 25 Apr 2018  路  12Comments  路  Source: jupyterhub/zero-to-jupyterhub-k8s

Hi

I'd like to add a welcome message to the user, and I would like it to be at his home (something like ~/.welcome-msg). It is printed when the use use the terminal and probably in a near welcome splashscreen plugin if I manage to find time to do it.

Today I have to burn the message inside the docker image, which is not very convenient. How I can send somes files from my config.yaml and have it added into the user's home directory (either as .dotfiles or even in a dot-folder with a mount volume somehow, that would be great!)

Most helpful comment

Here is my solution so far:

singleuser:
  ...
  lifecycleHooks:
    postStart:
      exec:
        command:
          - "bash"
          - "-c"
          - >
            cp -rfTv /user_env /home/jovyan ;
            rm -f ~/.welcome-msg;
            echo "******************************************************************************************************" >> ~/.welcome-msg;
            echo "Welcome to the Jupyterlab Terminal."                                                                    >> ~/.welcome-msg;
            echo ""                                                                                                       >> ~/.welcome-msg;
            echo "Please note the following important information:"                                                       >> ~/.welcome-msg;
            ...
            echo "To disable it, please execute the following command:"                                                   >> ~/.welcome-msg;
            echo "   $ touch ~/.welcome-msg.disabled"                                                                     >> ~/.welcome-msg;
            echo "******************************************************************************************************" >> ~/.welcome-msg;

And in my singleuser image, I have a bashrc (in /user_env/.bashrc) burned in the docker image with this chunk:

...
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    if [[ -f ~/.welcome-msg && ! -f ~/.welcome-msg.disabled ]]; then
        cat ~/.welcome-msg
    fi
    ;;
*)
    export PATH="$HOME/bin:$PATH"
    ;;
esac
...

All 12 comments

@gsemet I have a similar need and is quite happy about my solution. I want to provide updated content to all my users. My solution is to provide the following chart values under singleuser.storage in my config.yaml. It utilizes a kubernetes git repo volume.

A gitRepo volume is an example of what can be done as a volume plugin. It mounts an empty directory and clones a git repository into it for your pod to use.

      extraVolumes:
        - name: getting-started
          gitRepo:
            repository: https://github.com/consideRatio/jupyter-se-getting-started.git
      extraVolumeMounts:
        - name: getting-started
          mountPath: /home/jovyan/jupyter-se-getting-started
          subPath: jupyter-se-getting-started

__NOTE__: The mountPath shouldn't exist already, it will be overridden every time and /home/jovyan is also the mount point for the singleuser storage volume! This is why I append the folder /jupyter-se-getting-started to the home directory path and use that as mountPath. The content within this mountPath will be a folder called the same as the git respository, so by using subPath to enter it directly instead of ending up with one pointless folder within a folder. This way you end up adding all files in a git repository to one single directory under /home/jovyan without any issues.

You can inspect my deployment further at consideratio/z2jh-extended.

I think the lifecycle-hooks might be a good avenue for this. It's often used to populate the home directory with git clones, etc.

yes, I use it. But how to "copy" a file from config? I don't want to curl or git clone this file, since I do not want to open the configuration repository publicly and really which is lives in the same repository as the configuration.
Ideally a configmap mounted in the docker could be acceptable, but I do not find a way to do it easily

I think I can use extraVolumeMounts with configMap actually :)

@gsemet did you get this figured out in a way that we could easily document for people? :-)

that's not so easy, sadly. I do not have an easy way to describe a custom configmap within the z2jh value file.

Here is my solution so far:

singleuser:
  ...
  lifecycleHooks:
    postStart:
      exec:
        command:
          - "bash"
          - "-c"
          - >
            cp -rfTv /user_env /home/jovyan ;
            rm -f ~/.welcome-msg;
            echo "******************************************************************************************************" >> ~/.welcome-msg;
            echo "Welcome to the Jupyterlab Terminal."                                                                    >> ~/.welcome-msg;
            echo ""                                                                                                       >> ~/.welcome-msg;
            echo "Please note the following important information:"                                                       >> ~/.welcome-msg;
            ...
            echo "To disable it, please execute the following command:"                                                   >> ~/.welcome-msg;
            echo "   $ touch ~/.welcome-msg.disabled"                                                                     >> ~/.welcome-msg;
            echo "******************************************************************************************************" >> ~/.welcome-msg;

And in my singleuser image, I have a bashrc (in /user_env/.bashrc) burned in the docker image with this chunk:

...
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    if [[ -f ~/.welcome-msg && ! -f ~/.welcome-msg.disabled ]]; then
        cat ~/.welcome-msg
    fi
    ;;
*)
    export PATH="$HOME/bin:$PATH"
    ;;
esac
...

ha - that's clever :-)

yeah maybe a bit hacky to include in the tutorials, but I like it!

perhaps we should close this issue then? it sounds like your issue is resolved and I'm not sure what's the path forward. WDYT?

i don't know if the "community" documentation will appear sometimes on z2jh, but I would be glad to documente this hack on a wiki or somewhere like this :)

if you wanna put together a short post or something like this, feel free to make a PR with a link here:

https://zero-to-jupyterhub.readthedocs.io/en/latest/#resources-from-the-community

we put that together to have a place for less "official" but still quite useful information from the community!

Hi,
Even I have same situation, but I want to write a file with Instance metadata and some dynamic data that I get from POST request's body.

Any idea how to achieve it?

Thanks in Advance!!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

consideRatio picture consideRatio  路  4Comments

jgerardsimcock picture jgerardsimcock  路  4Comments

sgibson91 picture sgibson91  路  3Comments

jonathanballs picture jonathanballs  路  3Comments

aurashn picture aurashn  路  4Comments