diff --git a/Dockerfile.release b/Dockerfile.release index 9fd064c26..2d9deb56b 100644 --- a/Dockerfile.release +++ b/Dockerfile.release @@ -24,6 +24,9 @@ pip install --no-cache-dir --no-compile --no-deps -e ../dodal # Everything above this line should be in the image cache unless pyproject.toml changes # ADD .git /app/hyperion/.git +# Restore the repository at the current commit instead of copying, to exclude uncommitted changes +# This is so that if you build a developer image from this dockerfile then _version.py will not +# append the dirty workdir hash, which causes complications during deployments that mount from a clean folder. RUN git restore . # Regenerate _version.py with the correct version - this should run quickly since we already have our dependencies diff --git a/docs/developer/hyperion/deploying-hyperion.rst b/docs/developer/hyperion/deploying-hyperion.rst index a1582bce1..e7750b111 100644 --- a/docs/developer/hyperion/deploying-hyperion.rst +++ b/docs/developer/hyperion/deploying-hyperion.rst @@ -11,6 +11,15 @@ you will first need to create a GH personal access token and then log in with po Pushing the docker image ------------------------ +Obtaining a GitHub access token +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You will need to obtain a GitHub personal access token (classic) - not the new fine-grained token. +It will need the specific permission scopes as detailed in the `ghcr documentation `_ + +Building the image +~~~~~~~~~~~~~~~~~~ + If building a test image, the image should be pushed to your personal GH account: :: @@ -19,10 +28,6 @@ If building a test image, the image should be pushed to your personal GH account where ``mysecretfile`` contains your personal access token -:: - - podman push ghcr.io// - Then run the ``build_docker_image.sh`` script. Troubleshooting @@ -68,23 +73,16 @@ Once the docker image is built, the image can be deployed to kubernetes using th Production deployment ~~~~~~~~~~~~~~~~~~~~~ -* From a development hyperion workspace, first deploy the source folders +Then create and deploy the helm release :: - python utility_scripts/deploy/deploy_hyperion.py --kubernetes + ./utility_scripts/deploy/deploy_hyperion_to_k8s.sh --beamline= --checkout-to-prod hyperion -* Then create and deploy the helm release - -:: - - module load helm - cd - ./utility_scripts/deploy/deploy_hyperion_to_k8s.sh --beamline= hyperion - -This will create a helm release "hyperion". The source folders will be mounted as -bind mounts to allow the pod to pick up changes in production. For production these are expected to be in the normal -place defined in ``values.yaml``. +This will run the ``deploy_hyperion.py`` script to deploy the latest hyperion to ``/dls_sw``. +You will be prompted to log into the beamline cluster, then it will create a helm release "hyperion". +The source folders will be mounted as bind mounts to allow the pod to pick up changes in production. +For production these are expected to be in the normal place defined in ``values.yaml``. Development deployment ~~~~~~~~~~~~~~~~~~~~~~ @@ -102,6 +100,10 @@ The dev deployment bind-mounts the current ``hyperion`` workspace and ``../dodal run against your own development code. **Clusters do not allow bind mounts from arbitrary directories so your workspace will have to be in a permitted directory such as your home directory.** +By default the script will log into the ``argus`` cluster, if you want to deploy to an alternate cluster, +log in with ``kubectl set-context --current --namespace=`` and then specify ``--no-login`` when running the +script + Please note, the deployment script is intended to be run from a checked-out matching version of the git repository. -``helm list`` should then show details of the installed release +``helm list`` should then show details of the installed release on a successful install diff --git a/docs/user/how-to/run-container.rst b/docs/user/how-to/run-container.rst index a3b0add14..f7dd72f16 100644 --- a/docs/user/how-to/run-container.rst +++ b/docs/user/how-to/run-container.rst @@ -10,6 +10,6 @@ Starting the container To pull the container from github container registry and run:: - $ docker run ghcr.io/DiamondLightSource/mx-bluesky:main --version + $ docker run ghcr.io/diamondlightsource/mx-bluesky:main --version To get a released version, use a numbered release instead of ``main``. diff --git a/helmchart/templates/deployment.yaml b/helmchart/templates/deployment.yaml index e0786a544..42958a2a6 100644 --- a/helmchart/templates/deployment.yaml +++ b/helmchart/templates/deployment.yaml @@ -62,7 +62,7 @@ spec: memory: "1Gi" ports: - name: hyperion-api - containerPort: 5005 + containerPort: {{ .Values.hyperion.containerPort }} protocol: TCP env: - name: HYPERION_LOG_DIR diff --git a/helmchart/templates/ingress.yaml b/helmchart/templates/ingress.yaml index 8ca7f2235..8abef49d0 100644 --- a/helmchart/templates/ingress.yaml +++ b/helmchart/templates/ingress.yaml @@ -18,6 +18,6 @@ spec: service: name: hyperion-svc # this must match the name of the service you want to target port: - number: 5005 + number: {{ .Values.hyperion.containerPort }} {{- end }} diff --git a/helmchart/templates/service.yaml b/helmchart/templates/service.yaml index 2f1b1140a..b7c601f35 100644 --- a/helmchart/templates/service.yaml +++ b/helmchart/templates/service.yaml @@ -10,8 +10,8 @@ spec: {{- end }} ports: - name: hyperion-api - port: 5005 + port: {{ .Values.hyperion.servicePort }} protocol: TCP - targetPort: 5005 + targetPort: {{ .Values.hyperion.containerPort }} selector: app: hyperion diff --git a/helmchart/values.yaml b/helmchart/values.yaml index 4047c4688..01eff1721 100644 --- a/helmchart/values.yaml +++ b/helmchart/values.yaml @@ -1,5 +1,7 @@ hyperion: - imageRepository: ghcr.io/DiamondLightSource + containerPort: 5005 + servicePort: 80 + imageRepository: ghcr.io/diamondlightsource # i03-hyperion user and group runAsUser: 36101 runAsGroup: 36101 diff --git a/utility_scripts/build_docker_image.sh b/utility_scripts/build_docker_image.sh index 73289ac0e..aba8d1c92 100755 --- a/utility_scripts/build_docker_image.sh +++ b/utility_scripts/build_docker_image.sh @@ -59,7 +59,7 @@ if [[ $BUILD == 1 ]]; then fi if [[ $PUSH == 1 ]]; then - NAMESPACE=`podman login --get-login ghcr.io` + NAMESPACE=$(podman login --get-login ghcr.io | tr '[:upper:]' '[:lower:]') if [[ $? != 0 ]]; then echo "Not logged in to ghcr.io" exit 1 diff --git a/utility_scripts/deploy/deploy_hyperion.py b/utility_scripts/deploy/deploy_hyperion.py index aba19626a..6f6c8e584 100644 --- a/utility_scripts/deploy/deploy_hyperion.py +++ b/utility_scripts/deploy/deploy_hyperion.py @@ -18,9 +18,16 @@ DEV_DEPLOY_LOCATION = "/scratch/30day_tmp/hyperion_release_test/bluesky" +class Options(NamedTuple): + release_dir: str + kubernetes: bool = False + print_release_dir: bool = False + quiet: bool = False + + class Deployment: # Set name, setup remote origin, get the latest version""" - def __init__(self, name: str, repo_args): + def __init__(self, name: str, repo_args, options: Options): self.name = name self.repo = Repo(repo_args) @@ -32,7 +39,10 @@ def __init__(self, name: str, repo_args): t.name for t in self.repo.tags if VERSION_PATTERN_COMPILED.match(t.name) ] self.versions.sort(key=Version, reverse=True) - print(f"Found {self.name}_versions:\n{os.linesep.join(self.versions)}") + + if not options.quiet: + print(f"Found {self.name}_versions:\n{os.linesep.join(self.versions)}") + self.latest_version_str = self.versions[0] def deploy(self): @@ -64,13 +74,8 @@ def set_deploy_location(self, release_area): ) -class Options(NamedTuple): - release_dir: str - kubernetes: bool = False - - # Get the release directory based off the beamline and the latest hyperion version -def _get_hyperion_release_dir_from_args() -> Options: +def _parse_options() -> Options: parser = argparse.ArgumentParser( prog="deploy_hyperion", description="Deploy hyperion to a beamline" ) @@ -85,7 +90,11 @@ def _get_hyperion_release_dir_from_args() -> Options: choices=recognised_beamlines, help=f"The beamline to deploy hyperion to. 'dev' installs to {DEV_DEPLOY_LOCATION}", ) - + parser.add_argument( + "--print-release-dir", + action=argparse.BooleanOptionalAction, + help="Print the path to the release folder and then exit", + ) args = parser.parse_args() if args.beamline == "dev": print("Running as dev") @@ -93,7 +102,12 @@ def _get_hyperion_release_dir_from_args() -> Options: else: release_dir = f"/dls_sw/{args.beamline}/software/bluesky" - return Options(release_dir=release_dir, kubernetes=args.kubernetes) + return Options( + release_dir=release_dir, + kubernetes=args.kubernetes, + print_release_dir=args.print_release_dir, + quiet=args.print_release_dir, + ) def _create_environment_from_control_machine( @@ -129,25 +143,30 @@ def main(options: Options): release_area = options.release_dir this_repo_top = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) - print(f"Repo top is {this_repo_top}") + if not options.quiet: + print(f"Repo top is {this_repo_top}") hyperion_repo = Deployment( - name="hyperion", - repo_args=os.path.join(this_repo_top, ".git"), + name="hyperion", repo_args=os.path.join(this_repo_top, ".git"), options=options ) if hyperion_repo.name != "hyperion": raise ValueError("This function should only be used with the hyperion repo") release_area_version = os.path.join( - release_area, f"hyperion_{hyperion_repo.latest_version_str}" + release_area, f"mx_bluesky_{hyperion_repo.latest_version_str}" ) + if options.print_release_dir: + print(release_area_version) + return + print(f"Putting releases into {release_area_version}") dodal_repo = Deployment( name="dodal", repo_args=os.path.join(this_repo_top, "../dodal/.git"), + options=options, ) dodal_repo.set_deploy_location(release_area_version) @@ -218,5 +237,5 @@ def create_symlink_by_tmp_and_rename(dirname, target, linkname): if __name__ == "__main__": # Gives path to /bluesky - options = _get_hyperion_release_dir_from_args() + options = _parse_options() main(options) diff --git a/utility_scripts/deploy/deploy_hyperion_to_k8s.sh b/utility_scripts/deploy/deploy_hyperion_to_k8s.sh index 8fda68040..52b63f790 100755 --- a/utility_scripts/deploy/deploy_hyperion_to_k8s.sh +++ b/utility_scripts/deploy/deploy_hyperion_to_k8s.sh @@ -1,5 +1,7 @@ #!/bin/bash # Installs helm package to kubernetes +LOGIN=true + for option in "$@"; do case $option in -b=*|--beamline=*) @@ -10,6 +12,10 @@ for option in "$@"; do DEV=true shift ;; + --checkout-to-prod) + CHECKOUT=true + shift + ;; --repository=*) REPOSITORY="${option#*=}" shift @@ -18,16 +24,30 @@ for option in "$@"; do APP_VERSION="${option#*=}" shift ;; + --no-login) + LOGIN=false + shift + ;; --help|--info|--h) CMD=`basename $0` echo "$CMD [options] " - echo "Deploys hyperion to kubernetes" - echo " --help This help" - echo " --dev Install to a development kubernetes cluster (assumes project checked out under /home)" - echo " -b, --beamline=BEAMLINE Overrides the BEAMLINE environment variable with the given beamline" - echo " --repository=REPOSITORY Override the repository to fetch the image from" - echo " --appVersion=version Version of the image to fetch from the repository otherwise it is deduced - from the setuptools_scm" + cat <