Skip to content

Conversation

gilesknap
Copy link
Contributor

  • mount in the standard ioc-instance PVCS including runtime
  • use runtime as a writeable home folder
  • add ability to set environment variables as per ioc-instance
  • set a default env vars HOME and TERM

Tested and fully working against this: https://github.com/epics-containers/p45-services/blob/legacy-p45-beamline/services/bl45p-ea-fastcs-01. Includes use of stdio-socket to expose to allow iPython console access.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds iPython console support for cluster environments by enhancing FastCS Helm charts with environment variable configuration and additional persistent volume mounts. The changes enable containers to have a writable home directory and proper environment setup for interactive console access.

  • Adds globalEnv and iocEnv configuration options for setting environment variables across all IOCs or individual IOCs
  • Mounts standard ioc-instance persistent volume claims (runtime, autosave) and configures a writable home directory
  • Sets default HOME and TERM environment variables for proper console functionality

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
Charts/fastcs/values.yaml Adds globalEnv and iocEnv array configurations for environment variables
Charts/fastcs/values.schema.json Defines JSON schema validation for the new environment variable arrays
Charts/fastcs/templates/statefulset.yaml Implements environment variables, working directory, and additional volume mounts in container specs
Charts/fastcs/extra.values.yaml Provides example configurations for the new environment variable arrays

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

codecov bot commented Sep 12, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.34%. Comparing base (9c2042a) to head (a1991c4).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #210   +/-   ##
=======================================
  Coverage   92.34%   92.34%           
=======================================
  Files          40       40           
  Lines        2077     2077           
=======================================
  Hits         1918     1918           
  Misses        159      159           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor Author

@gilesknap gilesknap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accepting CoPilot spelling fixes

value: /epics/runtime
- name: TERM
value: xterm-256color
{{- with $.Values.globalEnv }}
Copy link
Contributor

@GDYendell GDYendell Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the idea here that you can have a global env and add a service env without overwriting the global one? Would this be an appropriate case to use global - i.e. put $.Values.global.env here? Then we can add global.env in the root services yaml to insert things here and don't need an extra value in this schema.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that is the idea as you suggest.

We could move globalEnv into global but I don't have much appetite for it as its a breaking change for any services repos that have used it already and its not compelling enough to justify those breaks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So ibek already has globalEnv?

Copy link
Contributor Author

@gilesknap gilesknap Sep 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No ioc-instance helm chart does. It is intended to go in the shared values file so that all services (whose helm charts reference gloablEnv) will get these environment variables.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I think this is fine if it would be a big breaking change. It does seem ".Values.global.env" is a common pattern in the helm community, so it would be nice to align with that. But at the same time it might not be worth the upheaval.

{{- toYaml . | nindent 12 }}
{{- end }}
- name: runtime-volume
mountPath: /epics/runtime
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense to have /epics/runtime in fastcs. It has a very specific use in ibek IOCs that doesn't apply to fastcs IOCs (generating what are normally static files for conventional IOCs to use at boot time).

Can we just use /tmp as HOME?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using runtime means that your CLI history is saved between reboots. tmp would be lost.

We could call it something different, but its just where all IOCs put the things they make that are not autosave files or data.

If you don't like the name of the PVC then we have to go create a new PVC - which is not horrible. But right now we have the epics-pvcs pod to go inspect all the folders and make adjustments to them if needed.

None of my reasons are super compelling so if you prefer /tmp then lets go with that. I don't feel like it is a nicer name for a home folder than /runtime though!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Persistent history would be kind of nice, so don't mind too much making a directory other than /tmp. It is just the epics bit that I don't like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we can mount it into the container anywhere and call it what we want.

BUT. The PVC is called ixx-runtime and is mounted into all ibek IOCS (using the ioc-instance helm chart) at /epics/runtime. So options are:

  • make a completely new PVC just for fastCS IOCs and manage it separately so we can call it a better name and mount it where you want.
  • mount the existing epics-pvcs/my-ioc-name into /home/ipython_user
  • or just be consistent with ioc-instance and mount it into /epics/runtime so that developers jumping between ioc-instance and fastcs helm charts don't have to think about it.

I went for the last option. In my head the idea that /epics/runtime is a scratch area for EPICS IOCs is not awful, but I get that fastCS things might not be EPICS always.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is perhaps some friction over the fact that I made this helm chart to work with epics-containers and service repositories. Whereas fastcs itself is more generic than that.

Pragmatically, the chart will be used in service repositories and exist along side ioc-instance helm chart for ibek IOCs.
There are some PVCs that are global to each services domain and I've re-used them here. If we don't want to do that then we create a bit of extra work maintaining additional PVCs. I like the consistency but I'm coming from a epics-containers centric viewpoint.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that is fair. To be honest I am leaning towards /tmp just to fix the warning and allow up arrow once to tweak and re-run something, which realistically I think is all anyone will do 90% of the time anyway. I don't really like that it would pollute /epics/runtime, as a useful place to inspect what ibek IOCs generated, with something completely unrelated and its not worth making a new PVC for.

{{- with $.Values.globalEnv }}
{{- toYaml . | nindent 12}}
{{- end }}
{{- with $.Values.iocEnv }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer just env here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, I'm trying to be consistent with all IOCs here for familiarity.

The bad choices made early in epics-containers are only worth fixing if the benefit outweighs the breaking changes.
Is it worth it? maybe, I'm reluctant to make changes which will break existing services repos now that we have so many of them. I could grep them all to see if they are using iocEnv and maybe none are.

Do we care about fastCS being consistent with ibek IOCs? dunno.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just that it isn't necessarily an IOC. Does ibek already have iocEnv?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes ioc-instance (ibek IOCs) has iocEnv. We could change this one because it is never intended to be used in the shared values file, only in the individual values files.

I think it makes sense to call this env but also need to concede that use of the path /epics/ should also change in that case.

Copy link
Contributor Author

@gilesknap gilesknap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GDYendell I responded to your comments, let me know what you think.

Copy link
Contributor Author

@gilesknap gilesknap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having read your comments and thought this through I think we should:

  • drop the autosave mount
  • for the home dir mount epics-pvcs/runtime/my-ioc-name into /home/ipython
  • change the iocEnv value to env

I think that is accepting most of your points with the caveat that the PVC name still has epics in it. Changing the pvc names would be a big breaking change, adding a new PVC would be extra maintenance - @GDYendell let me know how you feel about this!

Comment on lines +133 to +138
{{- with $.Values.env }}
{{- toYaml . | nindent 12}}
{{- end }}
{{- with $.Values.global.env }}
{{- toYaml . | nindent 12}}
{{- end }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the precedence here if a variable appears in both? env should override global.env

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point, I think in fact the schema will fail for having the same key twice in a dictionary.

This means some exciting dictionary mergining in GoLang templates! blurg!

{{- $location := default .Values.global.location .Values.location | required "ERROR - You must supply location or global.location" -}}
{{- $ioc_group := default .Values.global.ioc_group .Values.ioc_group | required "ERROR - You must supply ioc_group or global.ioc_group" -}}
{{- $location := default .Values.global.location .Values.location | default "" -}}
{{- $ioc_group := default .Values.global.ioc_group .Values.ioc_group | default "" -}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could set is_ioc to true here if ioc_group is not empty, so that it doesn't have to be a value? And so that we can't have ioc_group=something with is_ioc=false, which would probably do bad things.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds sensible to me.

@gilesknap gilesknap marked this pull request as draft September 19, 2025 08:21
@gilesknap
Copy link
Contributor Author

Hi @GDYendell I have made a bunch of changes to genericize the helm chart but I'm not happy with them.
AND I have realized that there is lots of work to do with services - as a fastcs deployment should choose the set of ports it exposes bases upon its transports.

The main reason I'm not happy is that the chart now looks a bit like ioc-instance but with loads of odd caveats in it.

I've been chatting to Tom this morning and I think we need to make some fundamental breaking changes to the epics-containers framework to make it easier to add in a chart like this.

I'm going to write up what I think is needed and discuss it with you and Tom on Monday.

In the meantime I've switched this PR to draft as I think the chart will have lots of changes once the epics-containers changes are done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants