├── CODEOWNERS ├── .gitignore ├── README.md ├── argoexec ├── rock-ci-metadata.yaml ├── tests │ └── test_rock.py ├── tox.ini └── rockcraft.yaml ├── workflow-controller ├── rock-ci-metadata.yaml ├── tests │ └── test_rock.py ├── tox.ini └── rockcraft.yaml ├── .github ├── workflows │ ├── scan_images.yaml │ ├── on_pull_request.yaml │ └── on_push.yaml ├── .jira_sync_config.yaml └── ISSUE_TEMPLATE │ ├── task.yaml │ └── bug.yaml ├── SECURITY.md └── LICENSE /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @canonical/kubeflow 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | charm_repo 3 | *.rock 4 | *.tar 5 | *.pyc 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # argo-workflows-rocks 2 | rocks for Argoi Workflows 3 | -------------------------------------------------------------------------------- /argoexec/rock-ci-metadata.yaml: -------------------------------------------------------------------------------- 1 | integrations: 2 | - consumer-repository: https://github.com/canonical/argo-operators.git 3 | replace-image: 4 | - file: charms/argo-controller/config.yaml 5 | path: options.executor-image.default 6 | 7 | -------------------------------------------------------------------------------- /workflow-controller/rock-ci-metadata.yaml: -------------------------------------------------------------------------------- 1 | integrations: 2 | - consumer-repository: https://github.com/canonical/argo-operators.git 3 | 4 | replace-image: 5 | - file: charms/argo-controller/metadata.yaml 6 | path: resources.oci-image.upstream-source 7 | -------------------------------------------------------------------------------- /.github/workflows/scan_images.yaml: -------------------------------------------------------------------------------- 1 | name: Scan images 2 | 3 | on: 4 | schedule: 5 | - cron: '00 23 * * *' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | 10 | scan-images: 11 | name: Scan published images and report vulnerabilities 12 | uses: canonical/charmed-kubeflow-workflows/.github/workflows/get-published-images-scan-and-report.yaml@main 13 | secrets: 14 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 15 | with: 16 | severity: "HIGH,CRITICAL" 17 | -------------------------------------------------------------------------------- /.github/workflows/on_pull_request.yaml: -------------------------------------------------------------------------------- 1 | name: On PR 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | 8 | on-pull-request: 9 | uses: canonical/charmed-kubeflow-workflows/.github/workflows/get-rocks-modified-and-build-scan-test-publish.yaml@main 10 | permissions: 11 | pull-requests: read 12 | secrets: inherit 13 | with: 14 | microk8s-channel: 1.32-strict/stable 15 | juju-channel: 3.6/stable 16 | python-version: "3.8" 17 | rockcraft-channel: latest/stable 18 | -------------------------------------------------------------------------------- /.github/workflows/on_push.yaml: -------------------------------------------------------------------------------- 1 | name: On Push 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - track/** 8 | 9 | jobs: 10 | 11 | on-push: 12 | uses: canonical/charmed-kubeflow-workflows/.github/workflows/get-rocks-modified-and-build-scan-test-publish.yaml@main 13 | permissions: 14 | pull-requests: read 15 | secrets: inherit 16 | with: 17 | microk8s-channel: 1.32-strict/stable 18 | juju-channel: 3.6/stable 19 | python-version: "3.8" 20 | rockcraft-channel: latest/stable 21 | -------------------------------------------------------------------------------- /.github/.jira_sync_config.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | # Jira project key to create the issue in 3 | jira_project_key: "KF" 4 | 5 | # Dictionary mapping GitHub issue status to Jira issue status 6 | status_mapping: 7 | opened: Untriaged 8 | closed: done 9 | 10 | # (Optional) GitHub labels. Only issues with one of those labels will be synchronized. 11 | # If not specified, all issues will be synchronized 12 | labels: 13 | - bug 14 | - enhancement 15 | 16 | # (Optional) (Default: false) Add a new comment in GitHub with a link to Jira created issue 17 | add_gh_comment: true 18 | 19 | # (Optional) (Default: true) Synchronize issue description from GitHub to Jira 20 | sync_description: true 21 | 22 | # (Optional) (Default: true) Synchronize comments from GitHub to Jira 23 | sync_comments: false 24 | 25 | # (Optional) (Default: None) Parent Epic key to link the issue to 26 | epic_key: "KF-4805" 27 | 28 | # (Optional) Dictionary mapping GitHub issue labels to Jira issue types. 29 | # If label on the issue is not in specified list, this issue will be created as a Bug 30 | label_mapping: 31 | enhancement: Story 32 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security policy 2 | 3 | ## Supported Versions 4 | 5 | The Charmed Kubeflow project releases with a cadence of ~6 months, supports the latest two minor versions of Kubeflow, and keeps up to date with the upstream project. Whenever a new version of Kubeflow is released, a new version of Charmed Kubeflow is also released, and the oldest version is dropped from support. Please also to [Supported versions](https://charmed-kubeflow.io/docs/supported-versions) for details on the actual versions. 6 | Since this repository contains rocks used by the Charmed Kubeflow project, the same policy is expected for the rocks and oci-images generated from them (i.e. 1.9-xxxxx). 7 | 8 | ## Reporting a Vulnerability 9 | 10 | To report a security issue, file a [Private Security Report](https://github.com/canonical/bundle-kubeflow/security/advisories/new) with a description of the issue, the steps you took that led to the issue, affected versions, and, if known, mitigations for the issue. 11 | The [Ubuntu Security disclosure and embargo policy](https://ubuntu.com/security/disclosure-policy) contains more information about what you can expect when you contact us and what we expect from you. 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/task.yaml: -------------------------------------------------------------------------------- 1 | name: Task 2 | description: File an enhancement proposal 3 | labels: "enhancement" 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: > 8 | Thanks for taking the time to fill out this enhancement 9 | proposal! Before submitting your issue, please make sure there 10 | isn't already a prior issue concerning this. If there is, 11 | please join that discussion instead. 12 | - type: textarea 13 | id: enhancement-proposal-context 14 | attributes: 15 | label: Context 16 | description: > 17 | Describe why we should work on this task/enhancement, as well as 18 | existing context we should be aware of 19 | validations: 20 | required: true 21 | - type: textarea 22 | id: enhancement-proposal-what 23 | attributes: 24 | label: What needs to get done 25 | description: > 26 | Describe what needs to get done 27 | placeholder: | 28 | 1. Look into X 29 | 2. Implement Y 30 | 3. Create file Z 31 | validations: 32 | required: true 33 | - type: textarea 34 | id: enhancement-proposal-dod 35 | attributes: 36 | label: Definition of Done 37 | description: > 38 | What are the requirements for the task to be considered done 39 | placeholder: | 40 | 1. We know how X works (spike) 41 | 2. Code is doing Y 42 | 3. Charm has functionality Z 43 | validations: 44 | required: true 45 | -------------------------------------------------------------------------------- /workflow-controller/tests/test_rock.py: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Canonical Ltd. 2 | # See LICENSE file for licensing details. 3 | 4 | import subprocess 5 | 6 | import pytest 7 | from charmed_kubeflow_chisme.rock import CheckRock 8 | 9 | 10 | @pytest.mark.abort_on_fail 11 | def test_rock(): 12 | """Test rock.""" 13 | check_rock = CheckRock("rockcraft.yaml") 14 | rock_image = check_rock.get_name() 15 | rock_version = check_rock.get_version() 16 | LOCAL_ROCK_IMAGE = f"{rock_image}:{rock_version}" 17 | 18 | # assert the rock contains the expected files 19 | subprocess.run( 20 | [ 21 | "docker", 22 | "run", 23 | "--rm", 24 | "--entrypoint", 25 | "/bin/bash", 26 | LOCAL_ROCK_IMAGE, 27 | "-c", 28 | "ls -la /etc/ssh/ssh_known_hosts", 29 | ], 30 | check=True, 31 | ) 32 | 33 | subprocess.run( 34 | [ 35 | "docker", 36 | "run", 37 | "--rm", 38 | "--entrypoint", 39 | "/bin/bash", 40 | LOCAL_ROCK_IMAGE, 41 | "-c", 42 | "ls -la /etc/nsswitch.conf", 43 | ], 44 | check=True, 45 | ) 46 | 47 | subprocess.run( 48 | [ 49 | "docker", 50 | "run", 51 | "--rm", 52 | "--entrypoint", 53 | "/bin/bash", 54 | LOCAL_ROCK_IMAGE, 55 | "-c", 56 | "ls -la /bin/workflow-controller", 57 | ], 58 | check=True, 59 | ) 60 | -------------------------------------------------------------------------------- /argoexec/tests/test_rock.py: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Canonical Ltd. 2 | # See LICENSE file for licensing details. 3 | 4 | import pytest 5 | import subprocess 6 | 7 | from charmed_kubeflow_chisme.rock import CheckRock 8 | 9 | 10 | @pytest.mark.abort_on_fail 11 | def test_rock(): 12 | """Test rock.""" 13 | check_rock = CheckRock("rockcraft.yaml") 14 | rock_image = check_rock.get_name() 15 | rock_version = check_rock.get_version() 16 | LOCAL_ROCK_IMAGE = f"{rock_image}:{rock_version}" 17 | 18 | # assert the rock contains the expected files 19 | subprocess.run( 20 | [ 21 | "docker", 22 | "run", 23 | "--rm", 24 | LOCAL_ROCK_IMAGE, 25 | "exec", 26 | "ls", 27 | "-la", 28 | "/etc/ssh/ssh_known_hosts", 29 | ], 30 | check=True, 31 | ) 32 | 33 | subprocess.run( 34 | [ 35 | "docker", 36 | "run", 37 | "--rm", 38 | LOCAL_ROCK_IMAGE, 39 | "exec", 40 | "ls", 41 | "-la", 42 | "/etc/ssh/nsswitch.conf", 43 | ], 44 | check=True, 45 | ) 46 | 47 | subprocess.run( 48 | [ 49 | "docker", 50 | "run", 51 | "--rm", 52 | LOCAL_ROCK_IMAGE, 53 | "exec", 54 | "ls", 55 | "-la", 56 | "/bin/arch.sh", 57 | ], 58 | check=True, 59 | ) 60 | 61 | subprocess.run( 62 | ["docker", "run", "--rm", LOCAL_ROCK_IMAGE, "exec", "ls", "-la", "/bin/os.sh"], 63 | check=True, 64 | ) 65 | -------------------------------------------------------------------------------- /argoexec/tox.ini: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Canonical Ltd. 2 | # See LICENSE file for licensing details. 3 | [tox] 4 | skipsdist = True 5 | skip_missing_interpreters = True 6 | envlist = pack, export-to-docker, sanity, integration 7 | 8 | [testenv] 9 | setenv = 10 | PYTHONPATH={toxinidir} 11 | PYTHONBREAKPOINT=ipdb.set_trace 12 | CHARM_REPO=https://github.com/canonical/kserve-operators.git 13 | CHARM_BRANCH=main 14 | LOCAL_CHARM_DIR=charm_repo 15 | 16 | [testenv:pack] 17 | passenv = * 18 | allowlist_externals = 19 | rockcraft 20 | commands = 21 | rockcraft pack 22 | 23 | [testenv:export-to-docker] 24 | passenv = * 25 | allowlist_externals = 26 | bash 27 | skopeo 28 | yq 29 | commands = 30 | # pack rock and export to docker 31 | bash -c 'NAME=$(yq eval .name rockcraft.yaml) && \ 32 | VERSION=$(yq eval .version rockcraft.yaml) && \ 33 | ARCH=$(yq eval ".platforms | keys | .[0]" rockcraft.yaml) && \ 34 | ROCK="$\{NAME\}_$\{VERSION\}_$\{ARCH\}.rock" && \ 35 | DOCKER_IMAGE=$NAME:$VERSION && \ 36 | echo "Exporting $ROCK to docker as $DOCKER_IMAGE" && \ 37 | skopeo --insecure-policy copy oci-archive:$ROCK docker-daemon:$DOCKER_IMAGE' 38 | 39 | [testenv:sanity] 40 | passenv = * 41 | deps = 42 | pytest 43 | charmed-kubeflow-chisme 44 | commands = 45 | # run rock tests 46 | pytest -s -v --tb native --show-capture=all --log-cli-level=INFO {posargs} {toxinidir}/tests 47 | 48 | [testenv:integration] 49 | passenv = * 50 | allowlist_externals = 51 | echo 52 | commands = 53 | # TODO: Implement integration tests here 54 | echo "WARNING: This is a placeholder test - no test is implemented here." 55 | -------------------------------------------------------------------------------- /workflow-controller/tox.ini: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Canonical Ltd. 2 | # See LICENSE file for licensing details. 3 | [tox] 4 | skipsdist = True 5 | skip_missing_interpreters = True 6 | envlist = pack, export-to-docker, sanity, integration 7 | 8 | [testenv] 9 | setenv = 10 | PYTHONPATH={toxinidir} 11 | PYTHONBREAKPOINT=ipdb.set_trace 12 | CHARM_REPO=https://github.com/canonical/argo-operators.git 13 | CHARM_BRANCH=main 14 | LOCAL_CHARM_DIR=charms/argo-controller 15 | 16 | [testenv:pack] 17 | passenv = * 18 | allowlist_externals = 19 | rockcraft 20 | commands = 21 | rockcraft pack 22 | 23 | [testenv:export-to-docker] 24 | passenv = * 25 | allowlist_externals = 26 | bash 27 | skopeo 28 | yq 29 | commands = 30 | # pack rock and export to docker 31 | bash -c 'NAME=$(yq eval .name rockcraft.yaml) && \ 32 | VERSION=$(yq eval .version rockcraft.yaml) && \ 33 | ARCH=$(yq eval ".platforms | keys | .[0]" rockcraft.yaml) && \ 34 | ROCK="$\{NAME\}_$\{VERSION\}_$\{ARCH\}.rock" && \ 35 | DOCKER_IMAGE=$NAME:$VERSION && \ 36 | echo "Exporting $ROCK to docker as $DOCKER_IMAGE" && \ 37 | rockcraft.skopeo --insecure-policy copy oci-archive:$ROCK docker-daemon:$DOCKER_IMAGE' 38 | 39 | [testenv:sanity] 40 | passenv = * 41 | deps = 42 | pytest 43 | charmed-kubeflow-chisme 44 | commands = 45 | # run rock tests 46 | pytest -s -v \ 47 | --tb native \ 48 | --show-capture=all --log-cli-level=INFO {posargs} {toxinidir}/tests 49 | 50 | [testenv:integration] 51 | passenv = * 52 | allowlist_externals = 53 | echo 54 | commands = 55 | # TODO: Implement integration tests here 56 | echo "WARNING: This is a placeholder test - no test is implemented here." 57 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yaml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | labels: ["bug"] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: > 8 | Thanks for taking the time to fill out this bug report! Before submitting your issue, please make 9 | sure you are using the latest version of the charms. If not, please switch to the newest revision prior to 10 | posting your report to make sure it's not already solved. 11 | - type: textarea 12 | id: bug-description 13 | attributes: 14 | label: Bug Description 15 | description: > 16 | If applicable, add screenshots to help explain your problem. If applicable, add screenshots to 17 | help explain the problem you are facing. 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: reproduction 22 | attributes: 23 | label: To Reproduce 24 | description: > 25 | Please provide a step-by-step instruction of how to reproduce the behavior. 26 | placeholder: | 27 | 1. `juju deploy ...` 28 | 2. `juju relate ...` 29 | 3. `juju status --relations` 30 | validations: 31 | required: true 32 | - type: textarea 33 | id: environment 34 | attributes: 35 | label: Environment 36 | description: > 37 | We need to know a bit more about the context in which you run the charm. 38 | - Are you running Juju locally, on lxd, in multipass or on some other platform? 39 | - What track and channel you deployed the charm from (ie. `latest/edge` or similar). 40 | - Version of any applicable components, like the juju snap, the model controller, lxd, microk8s, and/or multipass. 41 | validations: 42 | required: true 43 | - type: textarea 44 | id: logs 45 | attributes: 46 | label: Relevant Log Output 47 | description: > 48 | Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. 49 | Fetch the logs using `juju debug-log --replay` and `kubectl logs ...`. Additional details available in the juju docs 50 | at https://juju.is/docs/olm/juju-logs 51 | render: shell 52 | validations: 53 | required: true 54 | - type: textarea 55 | id: additional-context 56 | attributes: 57 | label: Additional Context 58 | -------------------------------------------------------------------------------- /workflow-controller/rockcraft.yaml: -------------------------------------------------------------------------------- 1 | # From: https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile 2 | #!/usr/bin/env python3 3 | # Copyright 2023 Canonical Ltd. 4 | # See LICENSE file for licensing details. 5 | name: workflow-controller 6 | summary: An image for Argo Workflows controller. 7 | description: | 8 | This image is used as part of the Charmed Kubeflow product. An Argo workflow controller is a process that conforms to a specific interface that allows Argo to perform certain actions like monitoring pod logs, collecting artifacts, managing container lifecycles, etc. 9 | version: "3.5.14" 10 | license: Apache-2.0 11 | base: ubuntu@24.04 12 | run-user: _daemon_ 13 | 14 | platforms: 15 | amd64: 16 | 17 | services: 18 | argo-controller: 19 | override: replace 20 | command: workflow-controller 21 | startup: enabled 22 | 23 | parts: 24 | controller: 25 | plugin: nil 26 | source: https://github.com/argoproj/argo-workflows 27 | source-type: git 28 | source-tag: v3.5.14 29 | build-snaps: 30 | - go/1.23/stable 31 | build-packages: 32 | - git 33 | - make 34 | - ca-certificates 35 | - wget 36 | - curl 37 | - gcc 38 | - mailcap 39 | - bash 40 | stage-packages: 41 | - base-files 42 | - netbase 43 | - tzdata 44 | override-build: | 45 | # builder stage 46 | # https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile#L21 47 | go mod download 48 | 49 | # reset LDFLAGS, since rockcraft addes entries that go can't parse. 50 | LDFLAGS="" 51 | 52 | # workflow-controller-build 53 | # https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile#L56 54 | make dist/workflow-controller 55 | 56 | # workflow-controller stage 57 | # https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile#L90 58 | install -DT "./dist/workflow-controller" "$CRAFT_PART_INSTALL/bin/workflow-controller" 59 | 60 | copy-hack-files: 61 | plugin: dump 62 | after: [controller] 63 | source: https://github.com/argoproj/argo-workflows 64 | source-type: git 65 | source-subdir: hack 66 | source-tag: v3.5.14 67 | # Move the files we want to copy in the expected place in the part's install dir 68 | organize: 69 | ssh_known_hosts: etc/ssh/ssh_known_hosts 70 | nsswitch.conf: etc/nsswitch.conf 71 | # Only keep the 2 files we want from the part's install dir 72 | stage: 73 | - etc/ssh/ssh_known_hosts 74 | - etc/nsswitch.conf 75 | -------------------------------------------------------------------------------- /argoexec/rockcraft.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Canonical Ltd. 2 | # See LICENSE file for licensing details. 3 | # Based on: https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile 4 | name: argoexec 5 | summary: An image for Argo Workflows executor. 6 | description: | 7 | This image is used as part of the Charmed Kubeflow product. An Argo workflow executor is a process that conforms to a specific interface that allows Argo to perform certain actions like monitoring pod logs, collecting artifacts, managing container lifecycles, etc. 8 | license: Apache-2.0 9 | base: ubuntu@22.04 10 | version: "3.5.14" 11 | run-user: _daemon_ 12 | services: 13 | argoexec: 14 | override: replace 15 | command: argoexec 16 | startup: enabled 17 | working-dir: "/bin" 18 | platforms: 19 | amd64: 20 | 21 | parts: 22 | security-team-requirement: 23 | plugin: nil 24 | override-build: | 25 | mkdir -p ${CRAFT_PART_INSTALL}/usr/share/rocks 26 | (echo "# os-release" && cat /etc/os-release && echo "# dpkg-query" && \ 27 | dpkg-query --root=${CRAFT_PROJECT_DIR}/../bundles/ubuntu-22.04/rootfs/ -f '${db:Status-Abbrev},${binary:Package},${Version},${source:Package},${Source:Version}\n' -W) \ 28 | > ${CRAFT_PART_INSTALL}/usr/share/rocks/dpkg.query 29 | 30 | base-deps: 31 | plugin: nil 32 | stage-packages: 33 | - base-files 34 | - netbase 35 | - tzdata 36 | 37 | builder: 38 | plugin: make 39 | after: [base-deps] 40 | source: https://github.com/argoproj/argo-workflows 41 | source-type: git 42 | source-tag: v3.5.14 43 | build-snaps: 44 | - go/1.23/stable 45 | build-packages: 46 | - git 47 | - make 48 | - ca-certificates 49 | - wget 50 | - curl 51 | - gcc 52 | - mailcap 53 | stage-packages: 54 | - git 55 | - libcap2 56 | - jq 57 | - tar 58 | - gzip 59 | override-build: | 60 | # builder stage https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile#L21 61 | go mod download 62 | 63 | # reset LDFLAGS because Go has different format, i.e. '-L' is undefined in Go 64 | LDFLAGS="" 65 | 66 | # argoexec-build stage https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile#L46 67 | make dist/argoexec 68 | 69 | # argoexec stage https://github.com/argoproj/argo-workflows/blob/v3.5.14/Dockerfile#L79 70 | install -DT "./dist/argoexec" "$CRAFT_PART_INSTALL/bin/argoexec" 71 | install -DT "/etc/mime.types" "$CRAFT_PART_INSTALL/etc/mime.types" 72 | 73 | copy-files: 74 | plugin: dump 75 | after: [builder] 76 | source: https://github.com/argoproj/argo-workflows 77 | source-type: git 78 | source-subdir: hack 79 | source-tag: v3.5.14 80 | organize: 81 | ssh_known_hosts: etc/ssh/ssh_known_hosts 82 | nsswitch.conf: etc/ssh/nsswitch.conf 83 | arch.sh: bin/arch.sh 84 | os.sh: bin/os.sh 85 | stage: 86 | - etc/ssh/ssh_known_hosts 87 | - etc/ssh/nsswitch.conf 88 | - bin/arch.sh 89 | - bin/os.sh 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------