From 0e23ed433c012c171f4090219cc5f2332d340143 Mon Sep 17 00:00:00 2001 From: eskild <42120229+iameskild@users.noreply.github.com> Date: Mon, 13 Nov 2023 08:15:19 -0800 Subject: [PATCH] Remove kbatch, prefect and clearml (#2101) Co-authored-by: Chuck McAndrew <6248903+dcmcand@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug-report.yml | 1 - .pre-commit-config.yaml | 2 - scripts/helm-validate.py | 2 +- src/_nebari/provider/cicd/github.py | 6 - .../stages/kubernetes_ingress/__init__.py | 15 - .../stages/kubernetes_services/__init__.py | 62 -- .../kubernetes_services/template/clearml.tf | 31 - .../template/jupyterhub.tf | 2 - .../kubernetes_services/template/kbatch.tf | 23 - .../services/clearml/chart/Chart.yaml | 14 - .../kubernetes/services/clearml/chart/LICENSE | 557 ------------------ .../services/clearml/chart/README.md | 146 ----- .../clearml/chart/charts/mongodb-10.3.7.tgz | Bin 52105 -> 0 bytes .../clearml/chart/charts/redis-10.9.0.tgz | Bin 60374 -> 0 bytes .../clearml/chart/templates/NOTES.txt | 22 - .../clearml/chart/templates/_helpers.tpl | 97 --- .../chart/templates/deployment-agent.yaml | 105 ---- .../templates/deployment-agentservices.yaml | 100 ---- .../chart/templates/deployment-apiserver.yaml | 122 ---- .../chart/templates/deployment-elastic.yaml | 264 --------- .../templates/deployment-fileserver.yaml | 69 --- .../chart/templates/deployment-webserver.yaml | 64 -- .../clearml/chart/templates/ingress.yaml | 48 -- .../chart/templates/pvc-agentservices.yaml | 13 - .../chart/templates/pvc-apiserver.yaml | 15 - .../chart/templates/pvc-fileserver.yaml | 13 - .../clearml/chart/templates/secret-agent.yaml | 11 - .../clearml/chart/templates/secrets.yaml | 11 - .../chart/templates/service-apiserver.yaml | 15 - .../chart/templates/service-fileserver.yaml | 15 - .../chart/templates/service-webserver.yaml | 15 - .../services/clearml/chart/values.yaml | 264 --------- .../kubernetes/services/clearml/ingress.tf | 101 ---- .../kubernetes/services/clearml/main.tf | 58 -- .../kubernetes/services/clearml/variables.tf | 34 -- .../kubernetes/services/kbatch/main.tf | 76 --- .../kubernetes/services/kbatch/values.yaml | 1 - .../kubernetes/services/kbatch/variables.tf | 57 -- .../kubernetes/services/kbatch/versions.tf | 18 - .../services/prefect/chart/.helmignore | 23 - .../services/prefect/chart/Chart.yaml | 23 - .../prefect/chart/templates/_helpers.tpl | 63 -- .../prefect/chart/templates/prefect.yaml | 111 ---- .../prefect/chart/templates/secret.yaml | 29 - .../services/prefect/chart/values.yaml | 5 - .../kubernetes/services/prefect/main.tf | 33 -- .../kubernetes/services/prefect/values.yaml | 17 - .../kubernetes/services/prefect/variables.tf | 29 - .../kubernetes_services/template/prefect.tf | 34 -- 49 files changed, 1 insertion(+), 2835 deletions(-) delete mode 100644 src/_nebari/stages/kubernetes_services/template/clearml.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/kbatch.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/Chart.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/LICENSE delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/README.md delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/charts/mongodb-10.3.7.tgz delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/charts/redis-10.9.0.tgz delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/NOTES.txt delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/_helpers.tpl delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-agent.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-agentservices.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-apiserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-elastic.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-fileserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-webserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/ingress.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-agentservices.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-apiserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-fileserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secret-agent.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secrets.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-apiserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-fileserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-webserver.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/values.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/ingress.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/main.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/variables.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/main.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/values.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/variables.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/versions.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/.helmignore delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/Chart.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/_helpers.tpl delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/prefect.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/secret.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/values.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/main.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/values.yaml delete mode 100644 src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/variables.tf delete mode 100644 src/_nebari/stages/kubernetes_services/template/prefect.tf diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 66e9002627..a89ff5e880 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -104,7 +104,6 @@ body: description: Is this issue related to any of the Nebari integrations? multiple: true options: - - "Prefect" - "Keycloak" - "conda-store" - "Dask" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 192d17db92..97a47a9b47 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,8 +30,6 @@ repos: exclude: "^docs-sphinx/cli.html" - id: check-json - id: check-yaml - # jinja2 templates for helm charts - exclude: "src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/(clearml/chart/templates/.*|prefect/chart/templates/.*)" args: [--allow-multiple-documents] - id: check-toml # Lint: Checks that non-binary executables have a proper shebang. diff --git a/scripts/helm-validate.py b/scripts/helm-validate.py index b655bea2c7..c0a065bed5 100644 --- a/scripts/helm-validate.py +++ b/scripts/helm-validate.py @@ -215,7 +215,7 @@ def add_workflow_job_summary(chart_index: dict): if __name__ == "__main__": # charts = generate_index_of_helm_charts() STAGES_DIR = "nebari/template/stages" - SKIP_CHARTS = ["prefect", "clearml", "helm-extensions"] + SKIP_CHARTS = ["helm-extensions"] charts = HelmChartIndexer( stages_dir=STAGES_DIR, skip_charts=SKIP_CHARTS diff --git a/src/_nebari/provider/cicd/github.py b/src/_nebari/provider/cicd/github.py index ac6fe15451..7b58464c43 100644 --- a/src/_nebari/provider/cicd/github.py +++ b/src/_nebari/provider/cicd/github.py @@ -108,12 +108,6 @@ def gha_env_vars(config: schema.Main): if os.environ.get("NEBARI_GH_BRANCH"): env_vars["NEBARI_GH_BRANCH"] = "${{ secrets.NEBARI_GH_BRANCH }}" - # This assumes that the user is using the omitting sensitive values configuration for the token. - if config.prefect.enabled: - env_vars[ - "NEBARI_SECRET_prefect_token" - ] = "${{ secrets.NEBARI_SECRET_PREFECT_TOKEN }}" - if config.provider == schema.ProviderEnum.aws: env_vars["AWS_ACCESS_KEY_ID"] = "${{ secrets.AWS_ACCESS_KEY_ID }}" env_vars["AWS_SECRET_ACCESS_KEY"] = "${{ secrets.AWS_SECRET_ACCESS_KEY }}" diff --git a/src/_nebari/stages/kubernetes_ingress/__init__.py b/src/_nebari/stages/kubernetes_ingress/__init__.py index 5a966b1459..cabe61f0cd 100644 --- a/src/_nebari/stages/kubernetes_ingress/__init__.py +++ b/src/_nebari/stages/kubernetes_ingress/__init__.py @@ -24,17 +24,6 @@ TIMEOUT = 10 # seconds -def add_clearml_dns(zone_name, record_name, record_type, ip_or_hostname): - dns_records = [ - f"app.clearml.{record_name}", - f"api.clearml.{record_name}", - f"files.clearml.{record_name}", - ] - - for dns_record in dns_records: - update_record(zone_name, dns_record, record_type, ip_or_hostname) - - def provision_ingress_dns( stage_outputs: Dict[str, Dict[str, Any]], config: schema.Main, @@ -60,13 +49,9 @@ def provision_ingress_dns( schema.ProviderEnum.azure, }: update_record(zone_name, record_name, "A", ip_or_hostname) - if config.clearml.enabled: - add_clearml_dns(zone_name, record_name, "A", ip_or_hostname) elif config.provider == schema.ProviderEnum.aws: update_record(zone_name, record_name, "CNAME", ip_or_hostname) - if config.clearml.enabled: - add_clearml_dns(zone_name, record_name, "CNAME", ip_or_hostname) else: logger.info( f"Couldn't update the DNS record for cloud provider: {config.provider}" diff --git a/src/_nebari/stages/kubernetes_services/__init__.py b/src/_nebari/stages/kubernetes_services/__init__.py index 2b8bb6fd80..8fe838d326 100644 --- a/src/_nebari/stages/kubernetes_services/__init__.py +++ b/src/_nebari/stages/kubernetes_services/__init__.py @@ -37,13 +37,6 @@ def to_yaml(cls, representer, node): return representer.represent_str(node.value) -class Prefect(schema.Base): - enabled: bool = False - image: typing.Optional[str] - overrides: typing.Dict = {} - token: typing.Optional[str] - - class DefaultImages(schema.Base): jupyterhub: str = f"quay.io/nebari/nebari-jupyterhub:{set_docker_image_tag()}" jupyterlab: str = f"quay.io/nebari/nebari-jupyterlab:{set_docker_image_tag()}" @@ -195,20 +188,10 @@ class ArgoWorkflows(schema.Base): nebari_workflow_controller: NebariWorkflowController = NebariWorkflowController() -class KBatch(schema.Base): - enabled: bool = True - - class Monitoring(schema.Base): enabled: bool = True -class ClearML(schema.Base): - enabled: bool = False - enable_forward_auth: bool = False - overrides: typing.Dict = {} - - class JupyterHub(schema.Base): overrides: typing.Dict = {} @@ -228,7 +211,6 @@ class JupyterLab(schema.Base): class InputSchema(schema.Base): - prefect: Prefect = Prefect() default_images: DefaultImages = DefaultImages() storage: Storage = Storage() theme: Theme = Theme() @@ -249,11 +231,6 @@ class InputSchema(schema.Base): "numpy=1.23.5", "numba=0.56.4", "pandas=1.5.3", - { - "pip": [ - "kbatch==0.4.2", - ], - }, ], ), "environment-dashboard.yaml": CondaEnvironment( @@ -301,9 +278,7 @@ class InputSchema(schema.Base): } conda_store: CondaStore = CondaStore() argo_workflows: ArgoWorkflows = ArgoWorkflows() - kbatch: KBatch = KBatch() monitoring: Monitoring = Monitoring() - clearml: ClearML = ClearML() jupyterhub: JupyterHub = JupyterHub() jupyterlab: JupyterLab = JupyterLab() @@ -382,23 +357,6 @@ class ArgoWorkflowsInputVars(schema.Base): ) -class KBatchInputVars(schema.Base): - kbatch_enabled: bool = Field(alias="kbatch-enabled") - - -class PrefectInputVars(schema.Base): - prefect_enabled: bool = Field(alias="prefect-enabled") - prefect_token: str = Field(None, alias="prefect-token") - prefect_image: str = Field(None, alias="prefect-image") - prefect_overrides: Dict = Field(alias="prefect-overrides") - - -class ClearMLInputVars(schema.Base): - clearml_enabled: bool = Field(alias="clearml-enabled") - clearml_enable_forwardauth: bool = Field(alias="clearml-enable-forwardauth") - clearml_overrides: List[str] = Field(alias="clearml-overrides") - - class KubernetesServicesStage(NebariTerraformStage): name = "07-kubernetes-services" priority = 70 @@ -520,23 +478,6 @@ def input_vars(self, stage_outputs: Dict[str, Dict[str, Any]]): keycloak_read_only_user_credentials=keycloak_read_only_user_credentials, ) - kbatch_vars = KBatchInputVars( - kbatch_enabled=self.config.kbatch.enabled, - ) - - prefect_vars = PrefectInputVars( - prefect_enabled=self.config.prefect.enabled, - prefect_token=self.config.prefect.token, - prefect_image=self.config.prefect.image, - prefect_overrides=self.config.prefect.overrides, - ) - - clearml_vars = ClearMLInputVars( - clearml_enabled=self.config.clearml.enabled, - clearml_enable_forwardauth=self.config.clearml.enable_forward_auth, - clearml_overrides=[json.dumps(self.config.clearml.overrides)], - ) - return { **kubernetes_services_vars.dict(by_alias=True), **conda_store_vars.dict(by_alias=True), @@ -544,9 +485,6 @@ def input_vars(self, stage_outputs: Dict[str, Dict[str, Any]]): **dask_gateway_vars.dict(by_alias=True), **monitoring_vars.dict(by_alias=True), **argo_workflows_vars.dict(by_alias=True), - **kbatch_vars.dict(by_alias=True), - **prefect_vars.dict(by_alias=True), - **clearml_vars.dict(by_alias=True), } def check( diff --git a/src/_nebari/stages/kubernetes_services/template/clearml.tf b/src/_nebari/stages/kubernetes_services/template/clearml.tf deleted file mode 100644 index 6c619fc656..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/clearml.tf +++ /dev/null @@ -1,31 +0,0 @@ -# ======================= VARIABLES ====================== -variable "clearml-enabled" { - description = "Clearml enabled or disabled" - type = bool -} - -variable "clearml-enable-forwardauth" { - description = "Clearml enabled or disabled forward authentication" - type = bool -} - - -variable "clearml-overrides" { - description = "Clearml helm chart overrides" - type = list(string) -} - - -# ====================== RESOURCES ======================= -module "clearml" { - count = var.clearml-enabled ? 1 : 0 - - source = "./modules/kubernetes/services/clearml" - - namespace = var.environment - external-url = var.endpoint - - overrides = var.clearml-overrides - - enable-forward-auth = var.clearml-enable-forwardauth -} diff --git a/src/_nebari/stages/kubernetes_services/template/jupyterhub.tf b/src/_nebari/stages/kubernetes_services/template/jupyterhub.tf index 009d857436..9fa68cbf53 100644 --- a/src/_nebari/stages/kubernetes_services/template/jupyterhub.tf +++ b/src/_nebari/stages/kubernetes_services/template/jupyterhub.tf @@ -112,8 +112,6 @@ module "jupyterhub" { "dask-gateway" ], (var.monitoring-enabled ? ["monitoring"] : []), - (var.prefect-enabled ? ["prefect"] : []), - (var.kbatch-enabled ? ["kbatch"] : []) ) general-node-group = var.node_groups.general diff --git a/src/_nebari/stages/kubernetes_services/template/kbatch.tf b/src/_nebari/stages/kubernetes_services/template/kbatch.tf deleted file mode 100644 index d400fbdd5e..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/kbatch.tf +++ /dev/null @@ -1,23 +0,0 @@ -# ======================= VARIABLES ====================== -variable "kbatch-enabled" { - description = "kbatch enabled or disabled" - type = bool -} - - -# ====================== RESOURCES ======================= -module "kbatch" { - count = var.kbatch-enabled ? 1 : 0 - - source = "./modules/kubernetes/services/kbatch" - - namespace = var.environment - external-url = var.endpoint - - jupyterhub_api_token = module.jupyterhub.services.kbatch.api_token - node-group = var.node_groups.user - - dask-gateway-address = module.dask-gateway.config.gateway.address - dask-gateway-proxy-address = module.dask-gateway.config.gateway.proxy_address - dask-worker-image = var.dask-worker-image -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/Chart.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/Chart.yaml deleted file mode 100644 index 98418b2c21..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/Chart.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v2 -appVersion: "1.0.2" -description: Clearml server Helm chart for Kubernetes -name: clearml-server-cloud-ready -version: "2.0.2+1" -dependencies: - - name: redis - version: "~10.9.0" - repository: "https://charts.bitnami.com/bitnami" - condition: redis.enabled - - name: mongodb - version: "~10.3.2" - repository: "https://charts.bitnami.com/bitnami" - condition: mongodb.enabled diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/LICENSE b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/LICENSE deleted file mode 100644 index 688d2d8043..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/LICENSE +++ /dev/null @@ -1,557 +0,0 @@ - Server Side Public License - VERSION 1, OCTOBER 16, 2018 - - Copyright © 2021 allegro.ai, Inc. - - Everyone is permitted to copy and distribute verbatim copies of this - license document, but changing it is not allowed. - - TERMS AND CONDITIONS - - 0. Definitions. - - “This License” refers to Server Side Public License. - - “Copyright” also means copyright-like laws that apply to other kinds of - works, such as semiconductor masks. - - “The Program” refers to any copyrightable work licensed under this - License. Each licensee is addressed as “you”. “Licensees” and - “recipients” may be individuals or organizations. - - To “modify” a work means to copy from or adapt all or part of the work in - a fashion requiring copyright permission, other than the making of an - exact copy. The resulting work is called a “modified version” of the - earlier work or a work “based on” the earlier work. - - A “covered work” means either the unmodified Program or a work based on - the Program. - - To “propagate” a work means to do anything with it that, without - permission, would make you directly or secondarily liable for - infringement under applicable copyright law, except executing it on a - computer or modifying a private copy. Propagation includes copying, - distribution (with or without modification), making available to the - public, and in some countries other activities as well. - - To “convey” a work means any kind of propagation that enables other - parties to make or receive copies. Mere interaction with a user through a - computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays “Appropriate Legal Notices” to the - extent that it includes a convenient and prominently visible feature that - (1) displays an appropriate copyright notice, and (2) tells the user that - there is no warranty for the work (except to the extent that warranties - are provided), that licensees may convey the work under this License, and - how to view a copy of this License. If the interface presents a list of - user commands or options, such as a menu, a prominent item in the list - meets this criterion. - - 1. Source Code. - - The “source code” for a work means the preferred form of the work for - making modifications to it. “Object code” means any non-source form of a - work. - - A “Standard Interface” means an interface that either is an official - standard defined by a recognized standards body, or, in the case of - interfaces specified for a particular programming language, one that is - widely used among developers working in that language. The “System - Libraries” of an executable work include anything, other than the work as - a whole, that (a) is included in the normal form of packaging a Major - Component, but which is not part of that Major Component, and (b) serves - only to enable use of the work with that Major Component, or to implement - a Standard Interface for which an implementation is available to the - public in source code form. A “Major Component”, in this context, means a - major essential component (kernel, window system, and so on) of the - specific operating system (if any) on which the executable work runs, or - a compiler used to produce the work, or an object code interpreter used - to run it. - - The “Corresponding Source” for a work in object code form means all the - source code needed to generate, install, and (for an executable work) run - the object code and to modify the work, including scripts to control - those activities. However, it does not include the work's System - Libraries, or general-purpose tools or generally available free programs - which are used unmodified in performing those activities but which are - not part of the work. For example, Corresponding Source includes - interface definition files associated with source files for the work, and - the source code for shared libraries and dynamically linked subprograms - that the work is specifically designed to require, such as by intimate - data communication or control flow between those subprograms and other - parts of the work. - - The Corresponding Source need not include anything that users can - regenerate automatically from other parts of the Corresponding Source. - - The Corresponding Source for a work in source code form is that same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of - copyright on the Program, and are irrevocable provided the stated - conditions are met. This License explicitly affirms your unlimited - permission to run the unmodified Program, subject to section 13. The - output from running a covered work is covered by this License only if the - output, given its content, constitutes a covered work. This License - acknowledges your rights of fair use or other equivalent, as provided by - copyright law. Subject to section 13, you may make, run and propagate - covered works that you do not convey, without conditions so long as your - license otherwise remains in force. You may convey covered works to - others for the sole purpose of having them make modifications exclusively - for you, or provide you with facilities for running those works, provided - that you comply with the terms of this License in conveying all - material for which you do not control copyright. Those thus making or - running the covered works for you must do so exclusively on your - behalf, under your direction and control, on terms that prohibit them - from making any copies of your copyrighted material outside their - relationship with you. - - Conveying under any other circumstances is permitted solely under the - conditions stated below. Sublicensing is not allowed; section 10 makes it - unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological - measure under any applicable law fulfilling obligations under article 11 - of the WIPO copyright treaty adopted on 20 December 1996, or similar laws - prohibiting or restricting circumvention of such measures. - - When you convey a covered work, you waive any legal power to forbid - circumvention of technological measures to the extent such circumvention is - effected by exercising rights under this License with respect to the - covered work, and you disclaim any intention to limit operation or - modification of the work as a means of enforcing, against the work's users, - your or third parties' legal rights to forbid circumvention of - technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you - receive it, in any medium, provided that you conspicuously and - appropriately publish on each copy an appropriate copyright notice; keep - intact all notices stating that this License and any non-permissive terms - added in accord with section 7 apply to the code; keep intact all notices - of the absence of any warranty; and give all recipients a copy of this - License along with the Program. You may charge any price or no price for - each copy that you convey, and you may offer support or warranty - protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to - produce it from the Program, in the form of source code under the terms - of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified it, - and giving a relevant date. - - b) The work must carry prominent notices stating that it is released - under this License and any conditions added under section 7. This - requirement modifies the requirement in section 4 to “keep intact all - notices”. - - c) You must license the entire work, as a whole, under this License to - anyone who comes into possession of a copy. This License will therefore - apply, along with any applicable section 7 additional terms, to the - whole of the work, and all its parts, regardless of how they are - packaged. This License gives no permission to license the work in any - other way, but it does not invalidate such permission if you have - separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your work - need not make them do so. - - A compilation of a covered work with other separate and independent - works, which are not by their nature extensions of the covered work, and - which are not combined with it such as to form a larger program, in or on - a volume of a storage or distribution medium, is called an “aggregate” if - the compilation and its resulting copyright are not used to limit the - access or legal rights of the compilation's users beyond what the - individual works permit. Inclusion of a covered work in an aggregate does - not cause this License to apply to the other parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms of - sections 4 and 5, provided that you also convey the machine-readable - Corresponding Source under the terms of this License, in one of these - ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium customarily - used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a written - offer, valid for at least three years and valid for as long as you - offer spare parts or customer support for that product model, to give - anyone who possesses the object code either (1) a copy of the - Corresponding Source for all the software in the product that is - covered by this License, on a durable physical medium customarily used - for software interchange, for a price no more than your reasonable cost - of physically performing this conveying of source, or (2) access to - copy the Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This alternative is - allowed only occasionally and noncommercially, and only if you received - the object code with such an offer, in accord with subsection 6b. - - d) Convey the object code by offering access from a designated place - (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to copy - the object code is a network server, the Corresponding Source may be on - a different server (operated by you or a third party) that supports - equivalent copying facilities, provided you maintain clear directions - next to the object code saying where to find the Corresponding Source. - Regardless of what server hosts the Corresponding Source, you remain - obligated to ensure that it is available for as long as needed to - satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided you - inform other peers where the object code and Corresponding Source of - the work are being offered to the general public at no charge under - subsection 6d. - - A separable portion of the object code, whose source code is excluded - from the Corresponding Source as a System Library, need not be included - in conveying the object code work. - - A “User Product” is either (1) a “consumer product”, which means any - tangible personal property which is normally used for personal, family, - or household purposes, or (2) anything designed or sold for incorporation - into a dwelling. In determining whether a product is a consumer product, - doubtful cases shall be resolved in favor of coverage. For a particular - product received by a particular user, “normally used” refers to a - typical or common use of that class of product, regardless of the status - of the particular user or of the way in which the particular user - actually uses, or expects or is expected to use, the product. A product - is a consumer product regardless of whether the product has substantial - commercial, industrial or non-consumer uses, unless such uses represent - the only significant mode of use of the product. - - “Installation Information” for a User Product means any methods, - procedures, authorization keys, or other information required to install - and execute modified versions of a covered work in that User Product from - a modified version of its Corresponding Source. The information must - suffice to ensure that the continued functioning of the modified object - code is in no case prevented or interfered with solely because - modification has been made. - - If you convey an object code work under this section in, or with, or - specifically for use in, a User Product, and the conveying occurs as part - of a transaction in which the right of possession and use of the User - Product is transferred to the recipient in perpetuity or for a fixed term - (regardless of how the transaction is characterized), the Corresponding - Source conveyed under this section must be accompanied by the - Installation Information. But this requirement does not apply if neither - you nor any third party retains the ability to install modified object - code on the User Product (for example, the work has been installed in - ROM). - - The requirement to provide Installation Information does not include a - requirement to continue to provide support service, warranty, or updates - for a work that has been modified or installed by the recipient, or for - the User Product in which it has been modified or installed. Access - to a network may be denied when the modification itself materially - and adversely affects the operation of the network or violates the - rules and protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, in - accord with this section must be in a format that is publicly documented - (and with an implementation available to the public in source code form), - and must require no special password or key for unpacking, reading or - copying. - - 7. Additional Terms. - - “Additional permissions” are terms that supplement the terms of this - License by making exceptions from one or more of its conditions. - Additional permissions that are applicable to the entire Program shall be - treated as though they were included in this License, to the extent that - they are valid under applicable law. If additional permissions apply only - to part of the Program, that part may be used separately under those - permissions, but the entire Program remains governed by this License - without regard to the additional permissions. When you convey a copy of - a covered work, you may at your option remove any additional permissions - from that copy, or from any part of it. (Additional permissions may be - written to require their own removal in certain cases when you modify the - work.) You may place additional permissions on material, added by you to - a covered work, for which you have or can give appropriate copyright - permission. - - Notwithstanding any other provision of this License, for material you add - to a covered work, you may (if authorized by the copyright holders of - that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some trade - names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that material - by anyone who conveys the material (or modified versions of it) with - contractual assumptions of liability to the recipient, for any - liability that these contractual assumptions directly impose on those - licensors and authors. - - All other non-permissive additional terms are considered “further - restrictions” within the meaning of section 10. If the Program as you - received it, or any part of it, contains a notice stating that it is - governed by this License along with a term that is a further restriction, - you may remove that term. If a license document contains a further - restriction but permits relicensing or conveying under this License, you - may add to a covered work material governed by the terms of that license - document, provided that the further restriction does not survive such - relicensing or conveying. - - If you add terms to a covered work in accord with this section, you must - place, in the relevant source files, a statement of the additional terms - that apply to those files, or a notice indicating where to find the - applicable terms. Additional terms, permissive or non-permissive, may be - stated in the form of a separately written license, or stated as - exceptions; the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly - provided under this License. Any attempt otherwise to propagate or modify - it is void, and will automatically terminate your rights under this - License (including any patent licenses granted under the third paragraph - of section 11). - - However, if you cease all violation of this License, then your license - from a particular copyright holder is reinstated (a) provisionally, - unless and until the copyright holder explicitly and finally terminates - your license, and (b) permanently, if the copyright holder fails to - notify you of the violation by some reasonable means prior to 60 days - after the cessation. - - Moreover, your license from a particular copyright holder is reinstated - permanently if the copyright holder notifies you of the violation by some - reasonable means, this is the first time you have received notice of - violation of this License (for any work) from that copyright holder, and - you cure the violation prior to 30 days after your receipt of the notice. - - Termination of your rights under this section does not terminate the - licenses of parties who have received copies or rights from you under - this License. If your rights have been terminated and not permanently - reinstated, you do not qualify to receive new licenses for the same - material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or run a - copy of the Program. Ancillary propagation of a covered work occurring - solely as a consequence of using peer-to-peer transmission to receive a - copy likewise does not require acceptance. However, nothing other than - this License grants you permission to propagate or modify any covered - work. These actions infringe copyright if you do not accept this License. - Therefore, by modifying or propagating a covered work, you indicate your - acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically receives - a license from the original licensors, to run, modify and propagate that - work, subject to this License. You are not responsible for enforcing - compliance by third parties with this License. - - An “entity transaction” is a transaction transferring control of an - organization, or substantially all assets of one, or subdividing an - organization, or merging organizations. If propagation of a covered work - results from an entity transaction, each party to that transaction who - receives a copy of the work also receives whatever licenses to the work - the party's predecessor in interest had or could give under the previous - paragraph, plus a right to possession of the Corresponding Source of the - work from the predecessor in interest, if the predecessor has it or can - get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the rights - granted or affirmed under this License. For example, you may not impose a - license fee, royalty, or other charge for exercise of rights granted - under this License, and you may not initiate litigation (including a - cross-claim or counterclaim in a lawsuit) alleging that any patent claim - is infringed by making, using, selling, offering for sale, or importing - the Program or any portion of it. - - 11. Patents. - - A “contributor” is a copyright holder who authorizes use under this - License of the Program or a work on which the Program is based. The work - thus licensed is called the contributor's “contributor version”. - - A contributor's “essential patent claims” are all patent claims owned or - controlled by the contributor, whether already acquired or hereafter - acquired, that would be infringed by some manner, permitted by this - License, of making, using, or selling its contributor version, but do not - include claims that would be infringed only as a consequence of further - modification of the contributor version. For purposes of this definition, - “control” includes the right to grant patent sublicenses in a manner - consistent with the requirements of this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free - patent license under the contributor's essential patent claims, to make, - use, sell, offer for sale, import and otherwise run, modify and propagate - the contents of its contributor version. - - In the following three paragraphs, a “patent license” is any express - agreement or commitment, however denominated, not to enforce a patent - (such as an express permission to practice a patent or covenant not to - sue for patent infringement). To “grant” such a patent license to a party - means to make such an agreement or commitment not to enforce a patent - against the party. - - If you convey a covered work, knowingly relying on a patent license, and - the Corresponding Source of the work is not available for anyone to copy, - free of charge and under the terms of this License, through a publicly - available network server or other readily accessible means, then you must - either (1) cause the Corresponding Source to be so available, or (2) - arrange to deprive yourself of the benefit of the patent license for this - particular work, or (3) arrange, in a manner consistent with the - requirements of this License, to extend the patent license to downstream - recipients. “Knowingly relying” means you have actual knowledge that, but - for the patent license, your conveying the covered work in a country, or - your recipient's use of the covered work in a country, would infringe - one or more identifiable patents in that country that you have reason - to believe are valid. - - If, pursuant to or in connection with a single transaction or - arrangement, you convey, or propagate by procuring conveyance of, a - covered work, and grant a patent license to some of the parties receiving - the covered work authorizing them to use, propagate, modify or convey a - specific copy of the covered work, then the patent license you grant is - automatically extended to all recipients of the covered work and works - based on it. - - A patent license is “discriminatory” if it does not include within the - scope of its coverage, prohibits the exercise of, or is conditioned on - the non-exercise of one or more of the rights that are specifically - granted under this License. You may not convey a covered work if you are - a party to an arrangement with a third party that is in the business of - distributing software, under which you make payment to the third party - based on the extent of your activity of conveying the work, and under - which the third party grants, to any of the parties who would receive the - covered work from you, a discriminatory patent license (a) in connection - with copies of the covered work conveyed by you (or copies made from - those copies), or (b) primarily for and in connection with specific - products or compilations that contain the covered work, unless you - entered into that arrangement, or that patent license was granted, prior - to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting any - implied license or other defenses to infringement that may otherwise be - available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or - otherwise) that contradict the conditions of this License, they do not - excuse you from the conditions of this License. If you cannot use, - propagate or convey a covered work so as to satisfy simultaneously your - obligations under this License and any other pertinent obligations, then - as a consequence you may not use, propagate or convey it at all. For - example, if you agree to terms that obligate you to collect a royalty for - further conveying from those to whom you convey the Program, the only way - you could satisfy both those terms and this License would be to refrain - entirely from conveying the Program. - - 13. Offering the Program as a Service. - - If you make the functionality of the Program or a modified version - available to third parties as a service, you must make the Service Source - Code available via network download to everyone at no charge, under the - terms of this License. Making the functionality of the Program or - modified version available to third parties as a service includes, - without limitation, enabling third parties to interact with the - functionality of the Program or modified version remotely through a - computer network, offering a service the value of which entirely or - primarily derives from the value of the Program or modified version, or - offering a service that accomplishes for users the primary purpose of the - Program or modified version. - - “Service Source Code” means the Corresponding Source for the Program or - the modified version, and the Corresponding Source for all programs that - you use to make the Program or modified version available as a service, - including, without limitation, management software, user interfaces, - application program interfaces, automation software, monitoring software, - backup software, storage software and hosting software, all such that a - user could run an instance of the service using the Service Source Code - you make available. - - 14. Revised Versions of this License. - - MongoDB, Inc. may publish revised and/or new versions of the Server Side - Public License from time to time. Such new versions will be similar in - spirit to the present version, but may differ in detail to address new - problems or concerns. - - Each version is given a distinguishing version number. If the Program - specifies that a certain numbered version of the Server Side Public - License “or any later version” applies to it, you have the option of - following the terms and conditions either of that numbered version or of - any later version published by MongoDB, Inc. If the Program does not - specify a version number of the Server Side Public License, you may - choose any version ever published by MongoDB, Inc. - - If the Program specifies that a proxy can decide which future versions of - the Server Side Public License can be used, that proxy's public statement - of acceptance of a version permanently authorizes you to choose that - version for the Program. - - Later license versions may give you additional or different permissions. - However, no additional obligations are imposed on any author or copyright - holder as a result of your choosing to follow a later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY - APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT - HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY - OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM - IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF - ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING - WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS - THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING - ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF - THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO - LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU - OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER - PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided above - cannot be given local legal effect according to their terms, reviewing - courts shall apply local law that most closely approximates an absolute - waiver of all civil liability in connection with the Program, unless a - warranty or assumption of liability accompanies a copy of the Program in - return for a fee. - - END OF TERMS AND CONDITIONS diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/README.md b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/README.md deleted file mode 100644 index 76dd362412..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# ClearML Server for Kubernetes Clusters Using Helm - -# Cloud Ready Version (Advanced) - -## Auto-Magical Experiment Manager & Version Control for AI - -[![GitHub license](https://img.shields.io/badge/license-SSPL-green.svg)](https://img.shields.io/badge/license-SSPL-green.svg) -[![GitHub version](https://img.shields.io/github/release-pre/allegroai/clearml-server.svg)](https://img.shields.io/github/release-pre/allegroai/clearml-server.svg) -[![PyPI status](https://img.shields.io/badge/status-beta-yellow.svg)](https://img.shields.io/badge/status-beta-yellow.svg) - -## Introduction - -The **clearml-server** is the backend service infrastructure for [ClearML](https://github.com/allegroai/clearml). It allows multiple users to collaborate and manage their -experiments. By default, \*ClearML is set up to work with the ClearML Demo Server, which is open to anyone and resets periodically. In order to host your own server, you will need -to install **clearml-server** and point ClearML to it. - -**clearml-server** contains the following components: - -- The ClearML Web-App, a single-page UI for experiment management and browsing -- RESTful API for: - - Documenting and logging experiment information, statistics and results - - Querying experiments history, logs and results -- Locally-hosted file server for storing images and models making them easily accessible using the Web-App - -Use this repository to add **clearml-server** to your Helm and then deploy **clearml-server** on Kubernetes clusters using Helm. - -## Deploying Your Own Elasticsearch, Redis and Mongodb - -ClearML Server requires that you have elasticsearch, redis and mongodb services. This chart default templates contains [bitnami](https://bitnami.com/) charts for -[redis](https://github.com/bitnami/charts/tree/master/bitnami/redis) and [mongodb](https://github.com/bitnami/charts/tree/master/bitnami/mongodb), and the official chart for -elasticsearch (which is currently still beta). You can either use the default ones, or use your own deployments and set their name and ports in the appropriate sections of this -chart. In order to use your own deployment, make sure to disable the existing one in the `values.yaml` (for example, in order to disable elastic set -`elasticsearch.enabled = false`) - -## Prerequisites - -1. a Kubernetes cluster -2. Persistent Volumes for `pvc-apiserver.yaml`, `pvc-fileserver.yaml`, and `pvc-agentservices.yaml`. -3. Persistent volumes for elasticsearch, mongodb and redis (redis is optional). See relevant information for each chart: - - [elasticsearch](https://github.com/elastic/helm-charts/blob/7.6.2/elasticsearch/values.yaml) - - [mongodb](https://github.com/bitnami/charts/tree/master/bitnami/mongodb#parameters) - - [redis](https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters) Make sure to define the following values for each PV: - - elasticsearch - in the `values.yaml` set `elasticsearch.persistence.enabled=true` and set `elasticsearch.volumeClaimTemplate.storageClassName` to the storageClassName used in - your elasticsearch PV. - - mongodb - in order to define a persistent volume for mongodb, in the `values.yaml` set `mongodb.persistence.enabled=true` and set `mongodb.persistence.storageClass` to the - storageClassName used in your mongodb PV. Read [here](https://github.com/bitnami/charts/tree/master/bitnami/mongodb#parameters) for more details. - - redis - in order to define a persistent volume for redis, in the `values.yaml` set `redis.master.persistence.enabled=true` and set `redis.master.persistence.storageClass` to - the storageClassName used in your redis PV. Read [here](https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters) for more details. -4. `kubectl` is installed and configured (see [Install and Set Up kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) in the Kubernetes documentation) -5. `helm` installed (see [Installing Helm](https://helm.sh/docs/using_helm/#installing-helm) in the Helm documentation) - -## Deploying ClearML Server in Kubernetes Clusters Using Helm - -1. Add the **clearml-server** repository to your Helm: - - ``` - helm repo add allegroai https://allegroai.github.io/clearml-server-helm-cloud-ready/ - ``` - -2. Confirm the **clearml-server** repository is now in Helm: - - ``` - helm search repo clearml - ``` - - The helm search results must include `allegroai/clearml-server-cloud-ready`. - -3. Install `clearml-server-cloud-ready` on your cluster: - - ``` - helm install clearml-server allegroai/clearml-server-cloud-ready --namespace=clearml --create-namespace - ``` - - A clearml `namespace` is created in your cluster and **clearml-server** is deployed in it. - -## Updating ClearML Server application using Helm - -1. If you are upgrading from the [single node version](https://github.com/allegroai/clearml-server-helm) of ClearML Server helm charts, follow these steps first: - - 1. Log in to the node previously labeled as `app=trains` - 2. Copy each folder under /opt/clearml/data to it's persistent volume. - 3. Follow the [Deploying ClearML Server](##-Deploying-ClearML-Server-in-Kubernetes-Clusters-Using-Helm) instructions to deploy Clearml - -2. Update using new or updated `values.yaml` - - ``` - helm upgrade clearml-server allegroai/clearml-server-cloud-ready -f new-values.yaml - ``` - -3. If there are no breaking changes, you can update your deployment to match repository version: - - ``` - helm upgrade clearml-server allegroai/clearml-server-cloud-ready - ``` - - **Important**: - - - If you previously deployed a **clearml-server**, you may encounter errors. If so, you must first delete old deployment using the following command: - - ``` - helm delete --purge clearml-server - ``` - - After running the `helm delete` command, you can run the `helm install` command. - -## Port Mapping - -After **clearml-server** is deployed, the services expose the following node ports: - -- API server on `30008` -- Web server on `30080` -- File server on `30081` - -## Accessing ClearML Server - -Access **clearml-server** by creating a load balancer and domain name with records pointing to the load balancer. - -Once you have a load balancer and domain name set up, follow these steps to configure access to clearml-server on your k8s cluster: - -1. Create domain records - - - Create 3 records to be used for Web-App, File server and API access using the following rules: - - - `app.` - - `files.` - - `api.` - - (*for example, `app.clearml.mydomainname.com`, `files.clearml.mydomainname.com` and `api.clearml.mydomainname.com`*) - -2. Point the records you created to the load balancer - -3. Configure the load balancer to redirect traffic coming from the records you created: - - - `app.` should be redirected to k8s cluster nodes on port `30080` - - `files.` should be redirected to k8s cluster nodes on port `30081` - - `api.` should be redirected to k8s cluster nodes on port `30008` - -## Additional Configuration for ClearML Server - -You can also configure the **clearml-server** for: - -- fixed users (users with credentials) -- non-responsive experiment watchdog settings - -For detailed instructions, see the [Optional Configuration](https://github.com/allegroai/clearml-server#optional-configuration) section in the **clearml-server** repository README -file. diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/charts/mongodb-10.3.7.tgz b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/charts/mongodb-10.3.7.tgz deleted file mode 100644 index 945fe932085a0160086ffd77f1db43bb63a0a407..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52105 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 - set -x; - while [ $(curl -sw '%{http_code}' "http://{{ include "clearml.fullname" $ }}-apiserver:{{ $.Values.apiserver.service.port }}/debug.ping" -o /dev/null) -ne 200 ] ; do - echo "waiting for apiserver" ; - sleep 5 ; - done - containers: - - name: {{ $.Chart.Name }}-{{ .name }} - image: "{{ .image.repository }}:{{ .image.tag }}" - imagePullPolicy: {{ .image.pullPolicy }} - securityContext: - privileged: true - resources: - limits: - nvidia.com/gpu: - {{ .nvidiaGpusPerAgent }} - env: - - name: CLEARML_API_HOST - value: 'http://{{ include "clearml.fullname" $ }}-apiserver:{{ $.Values.apiserver.service.port }}' - - name: CLEARML_WEB_HOST - value: 'http://{{ include "clearml.fullname" $ }}-webserver:{{ $.Values.webserver.service.port }}' - - name: CLEARML_FILES_HOST - value: 'http://{{ include "clearml.fullname" $ }}-fileserver:{{ $.Values.fileserver.service.port }}' - - name: CLEARML_AGENT_GIT_USER - value: {{ .clearmlGitUser}} - - name: CLEARML_AGENT_GIT_PASS - value: {{ .clearmlGitPassword}} - - name: AWS_ACCESS_KEY_ID - value: {{ .awsAccessKeyId}} - - name: AWS_SECRET_ACCESS_KEY - value: {{ .awsSecretAccessKey}} - - name: AWS_DEFAULT_REGION - value: {{ .awsDefaultRegion}} - - name: AZURE_STORAGE_ACCOUNT - value: {{ .azureStorageAccount}} - - name: AZURE_STORAGE_KEY - value: {{ .azureStorageKey}} - - name: CLEARML_API_ACCESS_KEY - valueFrom: - secretKeyRef: - name: clearml-conf - key: tests_user_key - - name: CLEARML_API_SECRET_KEY - valueFrom: - secretKeyRef: - name: clearml-conf - key: tests_user_secret - command: - - /bin/sh - - -c - - "apt-get update ; - apt-get install -y curl python3-pip git; - python3 -m pip install -U pip ; - python3 -m pip install clearml-agent{{ .agentVersion}} ; - CLEARML_AGENT_K8S_HOST_MOUNT=/root/.clearml:/root/.clearml clearml-agent daemon --queue {{ .queues}}" - {{- with .nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} -{{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-agentservices.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-agentservices.yaml deleted file mode 100644 index 97fbaccc3b..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-agentservices.yaml +++ /dev/null @@ -1,100 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "clearml.fullname" . }}-agentservices - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - replicas: {{ .Values.agentservices.replicaCount }} - selector: - matchLabels: - {{- include "clearml.selectorLabelsAgentServices" . | nindent 6 }} - template: - metadata: - {{- with .Values.agentservices.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "clearml.selectorLabelsAgentServices" . | nindent 8 }} - spec: - volumes: - - name: agentservices-data - persistentVolumeClaim: - claimName: {{ include "clearml.fullname" . }}-agentservices-data - initContainers: - - name: init-agentservices - image: "{{ .Values.agentservices.image.repository }}:{{ .Values.agentservices.image.tag | default .Chart.AppVersion }}" - command: - - /bin/sh - - -c - - > - set -x; - while [ $(curl -sw '%{http_code}' "http://{{ include "clearml.fullname" . }}-apiserver:{{ .Values.apiserver.service.port }}/debug.ping" -o /dev/null) -ne 200 ] ; do - echo "waiting for apiserver" ; - sleep 5 ; - done - containers: - - name: {{ .Chart.Name }} - image: "{{ .Values.agentservices.image.repository }}:{{ .Values.agentservices.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.agentservices.image.pullPolicy }} - env: - - name: CLEARML_HOST_IP - value: {{ .Values.agentservices.clearmlHostIp }} - - name: CLEARML_API_HOST - value: "http://{{ include "clearml.fullname" . }}-apiserver:{{ .Values.apiserver.service.port }}" - - name: CLEARML_WEB_HOST - value: {{ .Values.agentservices.clearmlWebHost }} - - name: CLEARML_FILES_HOST - value: {{ .Values.agentservices.clearmlFilesHost }} - - name: CLEARML_AGENT_GIT_USER - value: {{ .Values.agentservices.clearmlGitUser }} - - name: CLEARML_AGENT_GIT_PASS - value: {{ .Values.agentservices.clearmlGitPassword }} - - name: CLEARML_AGENT_UPDATE_VERSION - value: {{ .Values.agentservices.agentVersion }} - - name: CLEARML_AGENT_DEFAULT_BASE_DOCKER - value: {{ .Values.agentservices.defaultBaseDocker }} - - name: AWS_ACCESS_KEY_ID - value: {{ .Values.agentservices.awsAccessKeyId }} - - name: AWS_SECRET_ACCESS_KEY - value: {{ .Values.agentservices.awsSecretAccessKey }} - - name: AWS_DEFAULT_REGION - value: {{ .Values.agentservices.awsDefaultRegion }} - - name: AZURE_STORAGE_ACCOUNT - value: {{ .Values.agentservices.azureStorageAccount }} - - name: AZURE_STORAGE_KEY - value: {{ .Values.agentservices.azureStorageKey }} - - name: GOOGLE_APPLICATION_CREDENTIALS - value: {{ .Values.agentservices.googleCredentials }} - - name: CLEARML_WORKER_ID - value: {{ .Values.agentservices.clearmlWorkerId }} - - name: CLEARML_API_ACCESS_KEY - valueFrom: - secretKeyRef: - name: clearml-conf - key: tests_user_key - - name: CLEARML_API_SECRET_KEY - valueFrom: - secretKeyRef: - name: clearml-conf - key: tests_user_secret - args: - - agentservices - volumeMounts: - - name: agentservices-data - mountPath: /root/.clearml - resources: - {{- toYaml .Values.agentservices.resources | nindent 12 }} - {{- with .Values.agentservices.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.agentservices.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.agentservices.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-apiserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-apiserver.yaml deleted file mode 100644 index a4c30f4aac..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-apiserver.yaml +++ /dev/null @@ -1,122 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "clearml.fullname" . }}-apiserver - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - replicas: {{ .Values.apiserver.replicaCount }} - selector: - matchLabels: - {{- include "clearml.selectorLabelsApiServer" . | nindent 6 }} - template: - metadata: - {{- with .Values.apiserver.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "clearml.selectorLabelsApiServer" . | nindent 8 }} - spec: - {{- if .Values.apiserver.storage.enableConfigVolume }} - volumes: - - name: apiserver-config - persistentVolumeClaim: - claimName: {{ include "clearml.fullname" . }}-apiserver-config - {{- end }} - containers: - - name: {{ .Chart.Name }} - image: "{{ .Values.apiserver.image.repository }}:{{ .Values.apiserver.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.apiserver.image.pullPolicy }} - ports: - - name: http - containerPort: 8008 - protocol: TCP - env: - - name: CLEARML_ELASTIC_SERVICE_HOST - value: "{{ tpl .Values.elasticsearch.name . }}" - - name: CLEARML_ELASTIC_SERVICE_PORT - value: "{{ .Values.elasticsearch.httpPort }}" - - name: CLEARML_MONGODB_SERVICE_HOST - value: "{{ tpl .Values.mongodb.service.name . }}" - - name: CLEARML_MONGODB_SERVICE_PORT - value: "{{ .Values.mongodb.service.port }}" - - name: CLEARML_REDIS_SERVICE_HOST - value: "{{ tpl .Values.redis.master.name . }}" - - name: CLEARML_REDIS_SERVICE_PORT - value: "{{ .Values.redis.master.port }}" - - name: CLEARML__APISERVER__PRE_POPULATE__ENABLED - value: "{{ .Values.apiserver.prepopulateEnabled }}" - - name: CLEARML__APISERVER__PRE_POPULATE__ZIP_FILES - value: "{{ .Values.apiserver.prepopulateZipFiles }}" - - name: CLEARML_SERVER_DEPLOYMENT_TYPE - value: "helm-cloud" - - name: CLEARML_CONFIG_DIR - value: /opt/clearml/config - - name: CLEARML__APISERVER__DEFAULT_COMPANY - value: {{ .Values.clearml.defaultCompany }} - - name: CLEARML__SECURE__HTTP__SESSION_SECRET__APISERVER - valueFrom: - secretKeyRef: - name: clearml-conf - key: http_session - - name: CLEARML__SECURE__AUTH__TOKEN_SECRET - valueFrom: - secretKeyRef: - name: clearml-conf - key: auth_token - - name: CLEARML__SECURE__CREDENTIALS__APISERVER__USER_KEY - valueFrom: - secretKeyRef: - name: clearml-conf - key: apiserver_key - - name: CLEARML__SECURE__CREDENTIALS__APISERVER__USER_SECRET - valueFrom: - secretKeyRef: - name: clearml-conf - key: apiserver_secret - - name: CLEARML__SECURE__CREDENTIALS__TESTS__USER_KEY - valueFrom: - secretKeyRef: - name: clearml-conf - key: tests_user_key - - name: CLEARML__SECURE__CREDENTIALS__TESTS__USER_SECRET - valueFrom: - secretKeyRef: - name: clearml-conf - key: tests_user_secret - {{- if .Values.apiserver.extraEnvs }} - {{ toYaml .Values.apiserver.extraEnvs | nindent 10 }} - {{- end }} - args: - - apiserver - livenessProbe: - initialDelaySeconds: {{ .Values.apiserver.livenessDelay }} - httpGet: - path: /debug.ping - port: 8008 - readinessProbe: - initialDelaySeconds: {{ .Values.apiserver.readinessDelay }} - failureThreshold: 8 - httpGet: - path: /debug.ping - port: 8008 - {{- if .Values.apiserver.storage.enableConfigVolume }} - volumeMounts: - - name: apiserver-config - mountPath: /opt/clearml/config - {{- end }} - resources: - {{- toYaml .Values.apiserver.resources | nindent 12 }} - {{- with .Values.apiserver.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.apiserver.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.apiserver.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-elastic.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-elastic.yaml deleted file mode 100644 index 0ea328f3f4..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-elastic.yaml +++ /dev/null @@ -1,264 +0,0 @@ -# Source: clearml-server-cloud-ready/charts/elasticsearch/templates/poddisruptionbudget.yaml -apiVersion: policy/v1beta1 -kind: PodDisruptionBudget -metadata: - name: "clearml-elastic-master-pdb" -spec: - maxUnavailable: 1 - selector: - matchLabels: - app: "clearml-elastic-master" ---- -# Source: clearml-server-cloud-ready/charts/elasticsearch/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: clearml-elastic-master-config - labels: - heritage: "Helm" - release: "clearml-server" - chart: "elasticsearch" - app: "clearml-elastic-master" -data: - elasticsearch.yml: | - xpack.security.enabled: false ---- -# Source: clearml-server-cloud-ready/charts/elasticsearch/templates/service.yaml -kind: Service -apiVersion: v1 -metadata: - name: clearml-elastic-master - labels: - heritage: "Helm" - release: "clearml-server" - chart: "elasticsearch" - app: "clearml-elastic-master" - annotations: - {} -spec: - type: ClusterIP - selector: - heritage: "Helm" - chart: "elasticsearch" - release: "clearml-server" - app: "clearml-elastic-master" - ports: - - name: http - protocol: TCP - port: 9200 - - name: transport - protocol: TCP - port: 9300 ---- -# Source: clearml-server-cloud-ready/charts/elasticsearch/templates/service.yaml -kind: Service -apiVersion: v1 -metadata: - name: clearml-elastic-master-headless - labels: - heritage: "Helm" - release: "clearml-server" - chart: "elasticsearch" - app: "clearml-elastic-master" - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" -spec: - clusterIP: None # This is needed for statefulset hostnames like elasticsearch-0 to resolve - # Create endpoints also if the related pod isn't ready - publishNotReadyAddresses: true - selector: - app: "clearml-elastic-master" - ports: - - name: http - port: 9200 - - name: transport - port: 9300 ---- -# Source: clearml-server-cloud-ready/charts/elasticsearch/templates/statefulset.yaml -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: clearml-elastic-master - labels: - heritage: "Helm" - release: "clearml-server" - chart: "elasticsearch" - app: "clearml-elastic-master" - annotations: - esMajorVersion: "7" -spec: - serviceName: clearml-elastic-master-headless - selector: - matchLabels: - app: "clearml-elastic-master" - replicas: 1 - podManagementPolicy: Parallel - updateStrategy: - type: RollingUpdate - volumeClaimTemplates: - - metadata: - name: clearml-elastic-master - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 50Gi - template: - metadata: - name: "clearml-elastic-master" - labels: - heritage: "Helm" - release: "clearml-server" - chart: "elasticsearch" - app: "clearml-elastic-master" - annotations: - - configchecksum: 74bf3a32b86b711225b81f59050eb46d9c7e332399326f6fd4ee8627b4febfa - spec: - {{- with .Values.elasticsearch.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - securityContext: - fsGroup: 1000 - runAsUser: 1000 - affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchExpressions: - - key: app - operator: In - values: - - "clearml-elastic-master" - topologyKey: kubernetes.io/hostname - terminationGracePeriodSeconds: 120 - volumes: - - name: esconfig - configMap: - name: clearml-elastic-master-config - initContainers: - - name: configure-sysctl - securityContext: - runAsUser: 0 - privileged: true - image: "docker.elastic.co/elasticsearch/elasticsearch:7.6.2" - imagePullPolicy: "IfNotPresent" - command: ["sysctl", "-w", "vm.max_map_count=262144"] - resources: - {} - - containers: - - name: "elasticsearch" - securityContext: - capabilities: - # drop: - # - ALL - add: - - IPC_LOCK - - SYS_RESOURCE - # runAsNonRoot: true - runAsUser: 0 - # privileged: true - # runAsUser: 1000 - image: {{ .Values.elasticsearch.image }} - imagePullPolicy: "Always" #"IfNotPresent" - readinessProbe: - exec: - command: - - sh - - -c - - | - #!/usr/bin/env bash -e - # If the node is starting up wait for the cluster to be ready (request params: 'wait_for_status=yellow&timeout=1s' ) - # Once it has started only check that the node itself is responding - START_FILE=/tmp/.es_start_file - - http () { - local path="${1}" - if [ -n "${ELASTIC_USERNAME}" ] && [ -n "${ELASTIC_PASSWORD}" ]; then - BASIC_AUTH="-u ${ELASTIC_USERNAME}:${ELASTIC_PASSWORD}" - else - BASIC_AUTH='' - fi - curl -XGET -s -k --fail ${BASIC_AUTH} http://127.0.0.1:9200${path} - } - - if [ -f "${START_FILE}" ]; then - echo 'Elasticsearch is already running, lets check the node is healthy and there are master nodes available' - http "/_cluster/health?timeout=0s" - else - echo 'Waiting for elasticsearch cluster to become ready (request params: "wait_for_status=yellow&timeout=1s" )' - if http "/_cluster/health?wait_for_status=yellow&timeout=1s" ; then - touch ${START_FILE} - exit 0 - else - echo 'Cluster is not yet ready (request params: "wait_for_status=yellow&timeout=1s" )' - exit 1 - fi - fi - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 10 - successThreshold: 3 - timeoutSeconds: 5 - ports: - - name: http - containerPort: 9200 - - name: transport - containerPort: 9300 - resources: - limits: - cpu: 1000m - memory: 4Gi - requests: - cpu: 1000m - memory: 4Gi - env: - - name: node.name - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: cluster.initial_master_nodes - value: "clearml-elastic-master-0," - - name: discovery.seed_hosts - value: "clearml-elastic-master-headless" - - name: cluster.name - value: "clearml-elastic" - - name: network.host - value: "0.0.0.0" - - name: ES_JAVA_OPTS - value: "-Xmx2g -Xms2g" - - name: node.data - value: "true" - - name: node.ingest - value: "true" - - name: node.master - value: "true" - - name: bootstrap.memory_lock - value: "true" - - name: cluster.routing.allocation.node_initial_primaries_recoveries - value: "500" - - name: cluster.routing.allocation.disk.watermark.low - value: 500mb - - name: cluster.routing.allocation.disk.watermark.high - value: 500mb - - name: cluster.routing.allocation.disk.watermark.flood_stage - value: 500mb - - name: http.compression_level - value: "7" - - name: reindex.remote.whitelist - value: '*.*' - - name: xpack.monitoring.enabled - value: "false" - - name: xpack.security.enabled - value: "false" - volumeMounts: - - name: "clearml-elastic-master" - mountPath: /usr/share/elasticsearch/data - - - name: esconfig - mountPath: /usr/share/elasticsearch/config/elasticsearch.yml - subPath: elasticsearch.yml ---- diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-fileserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-fileserver.yaml deleted file mode 100644 index f3cf04f02a..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-fileserver.yaml +++ /dev/null @@ -1,69 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "clearml.fullname" . }}-fileserver - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - replicas: {{ .Values.fileserver.replicaCount }} - selector: - matchLabels: - {{- include "clearml.selectorLabelsFileServer" . | nindent 6 }} - template: - metadata: - {{- with .Values.fileserver.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "clearml.selectorLabelsFileServer" . | nindent 8 }} - spec: - volumes: - - name: fileserver-data - persistentVolumeClaim: - claimName: {{ include "clearml.fullname" . }}-fileserver-data - containers: - - name: {{ .Chart.Name }} - image: "{{ .Values.fileserver.image.repository }}:{{ .Values.fileserver.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.fileserver.image.pullPolicy }} - ports: - - name: http - containerPort: 8081 - protocol: TCP - env: - - name: CLEARML_CONFIG_DIR - value: /opt/clearml/config - {{- if .Values.fileserver.extraEnvs }} - {{ toYaml .Values.fileserver.extraEnvs | nindent 10 }} - {{- end }} - args: - - fileserver - livenessProbe: - exec: - command: - - curl - - -X OPTIONS - - http://localhost:8081/ - readinessProbe: - exec: - command: - - curl - - -X OPTIONS - - http://localhost:8081/ - volumeMounts: - - name: fileserver-data - mountPath: /mnt/fileserver - resources: - {{- toYaml .Values.fileserver.resources | nindent 12 }} - {{- with .Values.fileserver.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.fileserver.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.fileserver.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-webserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-webserver.yaml deleted file mode 100644 index 57c738129d..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/deployment-webserver.yaml +++ /dev/null @@ -1,64 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "clearml.fullname" . }}-webserver - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - replicas: {{ .Values.webserver.replicaCount }} - selector: - matchLabels: - {{- include "clearml.selectorLabelsWebServer" . | nindent 6 }} - template: - metadata: - {{- with .Values.webserver.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "clearml.selectorLabelsWebServer" . | nindent 8 }} - spec: - containers: - - name: {{ .Chart.Name }} - image: "{{ .Values.webserver.image.repository }}:{{ .Values.webserver.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.webserver.image.pullPolicy }} - ports: - - name: http - containerPort: 80 - protocol: TCP - livenessProbe: - exec: - command: - - curl - - -X OPTIONS - - http://0.0.0.0:80/ - readinessProbe: - exec: - command: - - curl - - -X OPTIONS - - http://0.0.0.0:80/ - env: - - name: NGINX_APISERVER_ADDRESS - value: "http://{{ include "clearml.fullname" . }}-apiserver:{{ .Values.apiserver.service.port }}" - - name: NGINX_FILESERVER_ADDRESS - value: "http://{{ include "clearml.fullname" . }}-fileserver:{{ .Values.fileserver.service.port }}" - {{- if .Values.webserver.extraEnvs }} - {{ toYaml .Values.webserver.extraEnvs | nindent 10 }} - {{- end }} - args: - - webserver - resources: - {{- toYaml .Values.webserver.resources | nindent 12 }} - {{- with .Values.webserver.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.webserver.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.webserver.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/ingress.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/ingress.yaml deleted file mode 100644 index dcdac14779..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/ingress.yaml +++ /dev/null @@ -1,48 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "clearml.fullname" . -}} -{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} -kind: Ingress -metadata: - name: {{ $fullName }} - labels: - {{- include "clearml.labels" . | nindent 4 }} - {{- with .Values.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- if .Values.ingress.tls.secretName }} - tls: - - hosts: - - "app.{{ .Values.ingress.host }}" - - "files.{{ .Values.ingress.host }}" - - "api.{{ .Values.ingress.host }}" - secretName: {{ .Values.ingress.tls.secretName }} - {{- end }} - rules: - - host: "app.{{ .Values.ingress.host }}" - http: - paths: - - path: "/*" - backend: - serviceName: {{ include "clearml.fullname" . }}-webserver - servicePort: {{ .Values.webserver.service.port }} - - host: "api.{{ .Values.ingress.host }}" - http: - paths: - - path: "/*" - backend: - serviceName: {{ include "clearml.fullname" . }}-apiserver - servicePort: {{ .Values.apiserver.service.port }} - - host: "files.{{ .Values.ingress.host }}" - http: - paths: - - path: "/*" - backend: - serviceName: {{ include "clearml.fullname" . }}-fileserver - servicePort: {{ .Values.fileserver.service.port }} -{{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-agentservices.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-agentservices.yaml deleted file mode 100644 index 47dc2f4db3..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-agentservices.yaml +++ /dev/null @@ -1,13 +0,0 @@ -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ include "clearml.fullname" . }}-agentservices-data - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.agentservices.storage.data.size | quote }} - storageClassName: {{ .Values.agentservices.storage.data.class | quote }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-apiserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-apiserver.yaml deleted file mode 100644 index 80f226be98..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-apiserver.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.apiserver.storage.enableConfigVolume }} -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ include "clearml.fullname" . }}-apiserver-config - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.apiserver.storage.config.size | quote }} - storageClassName: {{ .Values.apiserver.storage.config.class | quote }} -{{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-fileserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-fileserver.yaml deleted file mode 100644 index 293e3577f0..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/pvc-fileserver.yaml +++ /dev/null @@ -1,13 +0,0 @@ -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ include "clearml.fullname" . }}-fileserver-data - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: {{ .Values.fileserver.storage.data.size | quote }} - storageClassName: {{ .Values.fileserver.storage.data.class | quote }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secret-agent.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secret-agent.yaml deleted file mode 100644 index 720bfe47b5..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secret-agent.yaml +++ /dev/null @@ -1,11 +0,0 @@ -{{- range .Values.agentGroups }} ---- -{{ if .clearmlConfig }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ .name }}-conf -data: - clearml.conf: {{ .clearmlConfig | b64enc }} -{{ end }} -{{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secrets.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secrets.yaml deleted file mode 100644 index 2fde1e7ef8..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/secrets.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: clearml-conf -data: - apiserver_key: NTQ0MkYzNDQzTUpNT1JXWkEzWkg= - apiserver_secret: QnhhcElSbzlaSU5pOHgyNUNSeHo4V2RtcjJwUWp6dVdWQjRQTkFTWnFDdFR5V2dXVlE= - http_session: OVR3MjBSYmhKMWJMQmlIRU9XWHZocGxLR1ViVGdMekF0d0ZOMm9MUXZXd1MwdVJwRDU= - auth_token: MVNDZjBvdjNObTU0NFRkMm9aMGdYU3JzTng1WGhNV2RWbEt6MXRPZ2N4MTU4YkQ1UlY= - tests_user_key: RU5QMzlFUU00U0xBQ0dENUZYQjc= - tests_user_secret: bFBjbTBpbWJjQlo4bXdnTzd0cGFkdXRpUzNnbkpEMDV4OWo3YWZ3WFBTMzVJS2JwaVE= diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-apiserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-apiserver.yaml deleted file mode 100644 index 38683605fe..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-apiserver.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "clearml.fullname" . }}-apiserver - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - type: {{ .Values.apiserver.service.type }} - ports: - - port: {{ .Values.apiserver.service.port }} - targetPort: {{ .Values.apiserver.service.port }} - nodePort: 30008 - protocol: TCP - selector: - {{- include "clearml.selectorLabelsApiServer" . | nindent 4 }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-fileserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-fileserver.yaml deleted file mode 100644 index 6f96e276c2..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-fileserver.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "clearml.fullname" . }}-fileserver - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - type: {{ .Values.fileserver.service.type }} - ports: - - port: {{ .Values.fileserver.service.port }} - targetPort: {{ .Values.fileserver.service.port }} - nodePort: 30081 - protocol: TCP - selector: - {{- include "clearml.selectorLabelsFileServer" . | nindent 4 }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-webserver.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-webserver.yaml deleted file mode 100644 index 5ed6e8a052..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/templates/service-webserver.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "clearml.fullname" . }}-webserver - labels: - {{- include "clearml.labels" . | nindent 4 }} -spec: - type: {{ .Values.webserver.service.type }} - ports: - - port: {{ .Values.webserver.service.port }} - targetPort: {{ .Values.webserver.service.port }} - nodePort: 30080 - protocol: TCP - selector: - {{- include "clearml.selectorLabelsWebServer" . | nindent 4 }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/values.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/values.yaml deleted file mode 100644 index 35ba5901be..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/chart/values.yaml +++ /dev/null @@ -1,264 +0,0 @@ -clearml: - defaultCompany: "d1bd92a3b039400cbafc60a7a5b1e52b" -ingress: - enabled: false - name: clearml-server-ingress - annotations: {} - host: "" - tls: - secretName: "" - -apiserver: - prepopulateEnabled: "true" - prepopulateZipFiles: "/opt/clearml/db-pre-populate" - prepopulateArtifactsPath: "/mnt/fileserver" - configDir: /opt/clearml/config - - service: - type: NodePort - port: 8008 - - livenessDelay: 60 - readinessDelay: 60 - - replicaCount: 1 - - image: - repository: "allegroai/clearml" - pullPolicy: IfNotPresent - tag: "1.0.2" - - extraEnvs: [] - - podAnnotations: {} - - resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - nodeSelector: - app: "clearml" - - tolerations: [] - - affinity: {} - - # Optional: used in pvc-apiserver containing optional server configuration files - storage: - enableConfigVolume: false - config: - class: "standard" - size: 1Gi - -fileserver: - service: - type: NodePort - port: 8081 - - replicaCount: 1 - - image: - repository: "allegroai/clearml" - pullPolicy: IfNotPresent - tag: "1.0.2" - - extraEnvs: [] - - podAnnotations: {} - - resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - - nodeSelector: - app: "clearml" - - tolerations: [] - - affinity: {} - - storage: - data: - class: "standard" - size: 50Gi - -webserver: - extraEnvs: [] - - service: - type: NodePort - port: 80 - - replicaCount: 1 - - image: - repository: "allegroai/clearml" - pullPolicy: IfNotPresent - tag: "1.0.2" - - podAnnotations: {} - - resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - - nodeSelector: - app: "clearml" - - tolerations: [] - - affinity: {} - -agentservices: - clearmlHostIp: null - agentVersion: "" - clearmlWebHost: null - clearmlFilesHost: null - clearmlGitUser: null - clearmlGitPassword: null - awsAccessKeyId: null - awsSecretAccessKey: null - awsDefaultRegion: null - azureStorageAccount: null - azureStorageKey: null - googleCredentials: null - clearmlWorkerId: "clearml-services" - - replicaCount: 1 - - image: - repository: "allegroai/clearml-agent-services" - pullPolicy: IfNotPresent - tag: "latest" - - extraEnvs: [] - - podAnnotations: {} - - resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - - nodeSelector: - app: "clearml" - - tolerations: [] - - affinity: {} - - storage: - data: - class: "standard" - size: 50Gi - -agentGroups: - - name: agent-group0 - replicaCount: 0 - nvidiaGpusPerAgent: 1 - agentVersion: "" # if set, it *MUST* include comparison operator (for example ">=0.16.1") - queues: "default" # multiple queues can be specified separated by a space (for example "important_jobs default") - clearmlGitUser: null - clearmlGitPassword: null - clearmlAccessKey: null - clearmlSecretKey: null - awsAccessKeyId: null - awsSecretAccessKey: null - awsDefaultRegion: null - azureStorageAccount: null - azureStorageKey: null - clearmlConfig: |- - sdk { - } - - image: - repository: "nvidia/cuda" - pullPolicy: IfNotPresent - tag: "11.0-base-ubuntu18.04" - - podAnnotations: {} - - nodeSelector: - app: "clearml" - - tolerations: [] - - affinity: {} - -redis: # configuration from https://github.com/bitnami/charts/blob/master/bitnami/redis/values.yaml - enabled: true - image: - registry: docker.io - repository: bitnami/redis - tag: 5.0.10-debian-10-r88 - usePassword: false - databaseNumber: 0 - master: - name: "{{ .Release.Name }}-redis-master" - port: 6379 - persistence: - enabled: true - accessModes: - - ReadWriteOnce - size: 5Gi - cluster: - enabled: false - -mongodb: # configuration from https://github.com/bitnami/charts/blob/master/bitnami/mongodb/values.yaml - enabled: true - image: - registry: docker.io - repository: bitnami/mongodb - tag: 3.6.21-debian-9-r71 - architecture: standalone - auth: - enabled: false - replicaCount: 1 - persistence: - enabled: true - accessModes: - - ReadWriteOnce - size: 50Gi - service: - name: "{{ .Release.Name }}-mongodb" - type: ClusterIP - port: 27017 - portName: mongo-service - -elasticsearch: - enabled: false - name: "{{ .Release.Name }}-elastic-master" - image: balast/elasticsearch:6_50 - httpPort: 9200 - nodeSelector: - app: "clearml" diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/ingress.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/ingress.tf deleted file mode 100644 index 1af5f7ed2c..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/ingress.tf +++ /dev/null @@ -1,101 +0,0 @@ -locals { - clearml_webserver_subdomain = "app.clearml" - clearml_fileserver_subdomain = "files.clearml" - clearml_apiserver_subdomain = "api.clearml" - clearml-prefix = "clearml-clearml-server-cloud-ready" - clearml_webserver = "${local.clearml-prefix}-webserver" - clearml_fileserver = "${local.clearml-prefix}-fileserver" - clearml_apiserver = "${local.clearml-prefix}-apiserver" - - forward_auth_middleware = "traefik-forward-auth" - clearml_middleware = var.enable-forward-auth ? [ - { - name = local.forward_auth_middleware - namespace = var.namespace - } - ] : [] -} - -resource "kubernetes_manifest" "clearml-app" { - manifest = { - apiVersion = "traefik.containo.us/v1alpha1" - kind = "IngressRoute" - metadata = { - name = "clearml-app" - namespace = var.namespace - } - spec = { - entryPoints = ["websecure"] - routes = [ - { - kind = "Rule" - match = "Host(`${local.clearml_webserver_subdomain}.${var.external-url}`)" - middlewares = local.clearml_middleware - services = [ - { - name = local.clearml_webserver - port = 80 - namespace = var.namespace - } - ] - } - ] - } - } -} - -resource "kubernetes_manifest" "clearml-files" { - manifest = { - apiVersion = "traefik.containo.us/v1alpha1" - kind = "IngressRoute" - metadata = { - name = "clearml-files" - namespace = var.namespace - } - spec = { - entryPoints = ["websecure"] - routes = [ - { - kind = "Rule" - match = "Host(`${local.clearml_fileserver_subdomain}.${var.external-url}`)" - middlewares = local.clearml_middleware - services = [ - { - name = local.clearml_fileserver - port = 8081 - namespace = var.namespace - } - ] - } - ] - } - } -} - -resource "kubernetes_manifest" "clearml-api" { - manifest = { - apiVersion = "traefik.containo.us/v1alpha1" - kind = "IngressRoute" - metadata = { - name = "clearml-api" - namespace = var.namespace - } - spec = { - entryPoints = ["websecure"] - routes = [ - { - kind = "Rule" - match = "Host(`${local.clearml_apiserver_subdomain}.${var.external-url}`)" - middlewares = local.clearml_middleware - services = [ - { - name = local.clearml_apiserver - port = 8008 - namespace = var.namespace - } - ] - } - ] - } - } -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/main.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/main.tf deleted file mode 100644 index c14f831f2f..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/main.tf +++ /dev/null @@ -1,58 +0,0 @@ -resource "helm_release" "clearml" { - name = "clearml" - namespace = var.namespace - chart = "${path.module}/chart" - dependency_update = true - values = concat([ - file("${path.module}/chart/values.yaml") - ], var.overrides) - - dynamic "set" { - for_each = var.node_selector - content { - name = "apiserver.nodeSelector.${set.key}" - value = set.value - } - } - - dynamic "set" { - for_each = var.node_selector - content { - name = "fileserver.nodeSelector.${set.key}" - value = set.value - } - } - - dynamic "set" { - for_each = var.node_selector - content { - name = "webserver.nodeSelector.${set.key}" - value = set.value - } - } - - dynamic "set" { - for_each = var.node_selector - content { - name = "agentservices.nodeSelector.${set.key}" - value = set.value - } - } - - // dynamic "set" { - // for_each = var.node_selector - // content { - // name = "agentGroups.nodeSelector.${set.key}" - // value = set.value - // } - // } - - dynamic "set" { - for_each = var.node_selector - content { - name = "elasticsearch.nodeSelector.${set.key}" - value = set.value - } - } - -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/variables.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/variables.tf deleted file mode 100644 index 7f70e6d484..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/clearml/variables.tf +++ /dev/null @@ -1,34 +0,0 @@ -variable "namespace" { - description = "namespace to deploy clearml" - type = string - default = "dev" -} - -variable "node_selector" { - description = "Node to deploy on" - default = { - "app" = "clearml" - } -} - -variable "elasticsearch_image" { - description = "Elasticsearch docker image" - type = string - default = "balast/elasticsearch:6_50" -} - -variable "external-url" { - description = "External url that jupyterhub cluster is accessible" - type = string -} - -variable "enable-forward-auth" { - type = bool - default = true -} - -variable "overrides" { - description = "Clearml helm chart overrides" - type = list(string) - default = [] -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/main.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/main.tf deleted file mode 100644 index b00ff0d07a..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/main.tf +++ /dev/null @@ -1,76 +0,0 @@ -resource "helm_release" "kbatch" { - name = "kbatch" - namespace = var.namespace - repository = "https://kbatch-dev.github.io/helm-chart" - chart = "kbatch-proxy" - version = local.kbatch_version - - values = concat([ - file("${path.module}/values.yaml"), - jsonencode({ - app = { - jupyterhub_api_token = var.jupyterhub_api_token - jupyterhub_api_url = "https://${var.external-url}/hub/api/" - extra_env = { - KBATCH_PREFIX = "" - KBATCH_JOB_EXTRA_ENV = jsonencode({ - DASK_GATEWAY__AUTH__TYPE = "jupyterhub" - DASK_GATEWAY__CLUSTER__OPTIONS__IMAGE = "${var.dask-worker-image.name}:${var.dask-worker-image.tag}" - DASK_GATEWAY__ADDRESS = "${var.dask-gateway-address}" - DASK_GATEWAY__PROXY_ADDRESS = "${var.dask-gateway-proxy-address}" - }) - } - } - image = { - tag = local.kbatch_version - } - }) - ]) - - set_sensitive { - name = "jupyterHubToken" - value = var.jupyterhub_api_token - } - - set { - name = "kbatchImage" - value = var.image - } - - set { - name = "namespace" - value = var.namespace - } - -} - -resource "kubernetes_cluster_role" "kbatch" { - metadata { - name = "${var.name}-kbatch" - } - - rule { - api_groups = ["", "batch"] - resources = ["*"] - verbs = ["get", "watch", "list", "patch", "create", "delete"] - } -} - - -resource "kubernetes_cluster_role_binding" "kbatch" { - metadata { - name = "${var.name}-kbatch" - } - - role_ref { - api_group = "rbac.authorization.k8s.io" - kind = "ClusterRole" - name = kubernetes_cluster_role.kbatch.metadata.0.name - } - subject { - kind = "ServiceAccount" - name = local.kbatch_service_account_name - namespace = var.namespace - api_group = "" - } -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/values.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/values.yaml deleted file mode 100644 index b7c2489d1f..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/values.yaml +++ /dev/null @@ -1 +0,0 @@ -# https://github.com/kbatch-dev/helm-chart/blob/main/kbatch/values.yaml diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/variables.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/variables.tf deleted file mode 100644 index 40cba6cd29..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/variables.tf +++ /dev/null @@ -1,57 +0,0 @@ -variable "name" { - description = "name prefix to assign to kbatch" - type = string - default = "nebari" -} - -variable "jupyterhub_api_token" { - type = string - default = "" -} - -variable "namespace" { - type = string - default = "dev" -} - -variable "image" { - type = string - default = "" -} - -variable "node-group" { - description = "Node key value pair for bound resources" - type = object({ - key = string - value = string - }) -} - -variable "external-url" { - description = "External url that jupyterhub cluster is accessible" - type = string -} - -variable "overrides" { - description = "kbatch helm chart list of overrides" - type = list(string) - default = [] -} - -variable "dask-gateway-address" { - description = "Dask Gateway address" - type = string -} - -variable "dask-gateway-proxy-address" { - description = "Dask Gateway proxy-address" - type = string -} - -variable "dask-worker-image" { - description = "Dask worker image" - type = object({ - name = string - tag = string - }) -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/versions.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/versions.tf deleted file mode 100644 index 268d9c72d9..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/kbatch/versions.tf +++ /dev/null @@ -1,18 +0,0 @@ -terraform { - required_providers { - helm = { - source = "hashicorp/helm" - version = "2.1.2" - } - kubernetes = { - source = "hashicorp/kubernetes" - version = "2.20.0" - } - } - required_version = ">= 1.0" -} - -locals { - kbatch_service_account_name = "kbatch-kbatch-proxy" - kbatch_version = "0.4.2" -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/.helmignore b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/Chart.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/Chart.yaml deleted file mode 100644 index 45d157bb49..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/Chart.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v2 -name: prefect -description: A Helm chart for deploying prefect - -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 0.1.0 diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/_helpers.tpl b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/_helpers.tpl deleted file mode 100644 index 9e91be6aad..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/_helpers.tpl +++ /dev/null @@ -1,63 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "prefect.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "prefect.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "prefect.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "prefect.labels" -}} -helm.sh/chart: {{ include "prefect.chart" . }} -{{ include "prefect.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "prefect.selectorLabels" -}} -app.kubernetes.io/name: {{ include "prefect.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "prefect.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "prefect.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/prefect.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/prefect.yaml deleted file mode 100644 index b6ecdb82b6..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/prefect.yaml +++ /dev/null @@ -1,111 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: prefect-agent - name: prefect-agent -spec: - replicas: 1 - selector: - matchLabels: - app: prefect-agent - template: - metadata: - labels: - app: prefect-agent - spec: - serviceAccountName: {{ .Values.serviceAccount }} - containers: - - args: - - prefect agent start kubernetes -e JUPYTERHUB_API_TOKEN=$JUPYTERHUB_API_TOKEN {{- range $k, $v := .Values.secretEnvVars }} {{ printf " -e %s=$%s" $k $k -}} {{ end }} - command: - - /bin/bash - - -c - env: - {{- range $k, $v := .Values.envVars }} - - name: {{ $k }} - value: {{ squote $v -}} - {{ end }} - {{- range $i, $k := keys .Values.secretEnvVars }} - - name: {{ $k }} - valueFrom: - secretKeyRef: - name: prefect-envsecret-{{ $i }} - key: prefectEnvSecret{{ $i -}} - {{ end }} - - name: PREFECT__CLOUD__AGENT__AUTH_TOKEN - valueFrom: - secretKeyRef: - name: prefect-token - key: prefectToken - - name: JUPYTERHUB_API_TOKEN - valueFrom: - secretKeyRef: - name: jupyterhub-token - key: jupyterHubToken - - name: PREFECT__CLOUD__API - value: {{ .Values.cloudApi }} - - name: NAMESPACE - value: {{ .Values.namespace }} - - name: SERVICE_ACCOUNT_NAME - value: {{ .Values.serviceAccount }} - - name: PREFECT__BACKEND - value: cloud - - name: PREFECT__CLOUD__AGENT__AGENT_ADDRESS - value: http://:8080 - image: {{ .Values.prefectImage }} - imagePullPolicy: Always - livenessProbe: - failureThreshold: 2 - httpGet: - path: /api/health - port: 8080 - initialDelaySeconds: 40 - periodSeconds: 40 - name: agent - resources: - limits: - cpu: 100m - memory: 128Mi - ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ .Values.serviceAccount }} - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: prefect-agent-rbac - namespace: {{ .Values.namespace }} -rules: - - apiGroups: - - batch - - extensions - resources: - - jobs - verbs: - - '*' - - apiGroups: - - '*' - resources: - - pods - verbs: - - '*' - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: prefect-agent-rbac - namespace: {{ .Values.namespace }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: prefect-agent-rbac -subjects: - - kind: ServiceAccount - name: {{ .Values.serviceAccount }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/secret.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/secret.yaml deleted file mode 100644 index 02af94d0c3..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/templates/secret.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: prefect-token -data: - prefectToken: "{{ .Values.prefectToken | b64enc }}" - ---- -apiVersion: v1 -kind: Secret -metadata: - name: jupyterhub-token -data: - jupyterHubToken: "{{ .Values.jupyterHubToken | b64enc }}" - ---- -{{ $index := dict "index" "0" }} -{{- range $k, $v := .Values.secretEnvVars }} -{{ $i := get $index "index" }} -{{ $ni := add1 $i }} -apiVersion: v1 -kind: Secret -metadata: - name: prefect-envsecret-{{ $i }} -data: - prefectEnvSecret{{ $i }}: "{{ $v | b64enc }}" -{{ $_ := set $index "index" $ni }} ---- -{{ end }} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/values.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/values.yaml deleted file mode 100644 index 46063e6e3a..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/chart/values.yaml +++ /dev/null @@ -1,5 +0,0 @@ -prefectImage: -namespace: -serviceAccount: prefect -prefectToken: "" -cloudApi: "" diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/main.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/main.tf deleted file mode 100644 index 2cab6c42cf..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/main.tf +++ /dev/null @@ -1,33 +0,0 @@ -resource "helm_release" "prefect" { - name = "prefect" - namespace = var.namespace - chart = "${path.module}/chart" - - values = concat([ - file("${path.module}/values.yaml")], var.overrides) - - set_sensitive { - name = "prefectToken" - value = var.prefect_token - } - - set_sensitive { - name = "jupyterHubToken" - value = var.jupyterhub_api_token - } - - set { - name = "prefectImage" - value = var.image - } - - set { - name = "namespace" - value = var.namespace - } - - set { - name = "cloudApi" - value = var.cloud_api - } -} diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/values.yaml b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/values.yaml deleted file mode 100644 index 65fbeba700..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/values.yaml +++ /dev/null @@ -1,17 +0,0 @@ - -envVars: {} - -secretEnvVars: {} - -prefect_agent: - job: - imagePullSecrets: '' - imagePullPolicy: '' - resources: - requests: - memory: '' - cpu: '' - limits: - memory: '' - cpu: '' - prefectLabels: '[]' diff --git a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/variables.tf b/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/variables.tf deleted file mode 100644 index a6dbdd935a..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/modules/kubernetes/services/prefect/variables.tf +++ /dev/null @@ -1,29 +0,0 @@ -variable "jupyterhub_api_token" { - type = string - default = "" -} - -variable "namespace" { - type = string - default = "dev" -} - -variable "prefect_token" { - type = string -} - -variable "image" { - type = string - default = "prefecthq/prefect:0.14.22-python3.8" -} - -variable "cloud_api" { - type = string - default = "https://api.prefect.io" -} - -variable "overrides" { - description = "Prefect helm chart list of overrides" - type = list(string) - default = [] -} diff --git a/src/_nebari/stages/kubernetes_services/template/prefect.tf b/src/_nebari/stages/kubernetes_services/template/prefect.tf deleted file mode 100644 index dea9c18a9a..0000000000 --- a/src/_nebari/stages/kubernetes_services/template/prefect.tf +++ /dev/null @@ -1,34 +0,0 @@ -# ======================= VARIABLES ====================== -variable "prefect-enabled" { - description = "Prefect enabled or disabled" - type = bool -} - -variable "prefect-image" { - description = "Prefect image" - type = string -} - -variable "prefect-token" { - description = "Prefect token" - type = string -} - -variable "prefect-overrides" { - description = "Prefect token" - type = map(any) -} - - -# ====================== RESOURCES ======================= -module "prefect" { - count = var.prefect-enabled ? 1 : 0 - - source = "./modules/kubernetes/services/prefect" - - namespace = var.environment - jupyterhub_api_token = module.jupyterhub.services.prefect.api_token - prefect_token = var.prefect-token - image = var.prefect-image - overrides = [yamlencode(var.prefect-overrides)] -}