blob: b08885fd854d8193ac90d3638bf52f2fedcd597f [file] [log] [blame]
---
# omec-ci jobs
# Uses github pull request builder to trigger and Jenkinsfiles from this repo
# https://github.com/omec-project/omec-project-ci
# generic OMEC test-case jobs, shared by other projects and triggered within pipelines
- project:
name: omec
build-node: 'intel-102'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-tc1'
- 'omec-tc2'
- 'omec-deploy':
pod: 'dev'
build-node: 'omec-ci'
cp-context: 'dev-central-gcp'
dp-context: 'dev-edge-onf-menlo'
central-config: 'acc-gcp/app_values/omec-cp.yaml'
edge-config: 'ace-menlo/app_values/omec-upf.yaml'
- 'omec-ng40-test':
pod: 'dev'
build-node: 'omec-ci'
ng40-vm: 'ng40@192.168.122.101'
cp-context: 'dev-central-gcp'
dp-context: 'dev-edge-onf-menlo'
- 'omec-archive-artifacts':
pod: 'dev'
build-node: 'omec-ci'
cp-context: 'dev-central-gcp'
dp-context: 'dev-edge-onf-menlo'
log-since: '1h'
- 'omec-postmerge':
project: '{name}'
build-node: 'omec-ci'
c3po-branch-name: 'master'
spgw-branch-name: 'master'
nucleus-branch-name: 'master'
upf-branch-name: 'master'
pipeline-file: 'omec-postmerge.groovy'
# for ngic-rtc
- project:
name: ngic-rtc
project: '{name}'
build-node: 'intel-102'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-combined':
pipeline-file: 'Jenkinsfile-omec-combined.groovy'
mme-repo: 'Nucleus'
- 'omec-install':
sub-project: '{name}'
branch: 'central-cp-multi-upfs'
pipeline-file: 'Jenkinsfile-omec-install-ngic-rtc-vnf.groovy'
- 'omec-fossa':
pipeline-file: 'omec-fossa-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-reuse':
pipeline-file: 'omec-reuse-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'docker-publish-github':
build-timeout: 30
docker-repo: 'omecproject'
build-node: 'ubuntu16.04-basebuild-4c-8g'
- 'omec-container'
# for c3po
- project:
name: c3po
project: '{name}'
build-node: 'intel-102'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-combined':
pipeline-file: 'Jenkinsfile-omec-combined.groovy'
mme-repo: 'Nucleus'
- 'omec-install':
sub-project: 'c3po-sgx'
branch: 'master'
pipeline-file: 'Jenkinsfile-omec-install-c3po-sgx-vnf.groovy'
- 'omec-install':
sub-project: 'c3po-hss'
branch: 'master'
pipeline-file: 'Jenkinsfile-omec-install-c3po-hss-vnf.groovy'
- 'omec-fossa':
pipeline-file: 'omec-fossa-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-reuse':
pipeline-file: 'omec-reuse-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'docker-publish-github':
build-timeout: 30
docker-repo: 'omecproject'
build-node: 'ubuntu16.04-basebuild-8c-15g'
- 'omec-container'
# for openmme
- project:
name: openmme
project: '{name}'
build-node: 'intel-102'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-combined':
pipeline-file: 'Jenkinsfile-omec-combined.groovy'
mme-repo: 'openmme'
- 'omec-install':
sub-project: '{name}'
branch: 'master'
pipeline-file: 'Jenkinsfile-omec-install-openmme-vnf.groovy'
- 'omec-fossa':
pipeline-file: 'omec-fossa-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-reuse':
pipeline-file: 'omec-reuse-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'docker-publish-github':
build-timeout: 30
docker-repo: 'omecproject'
build-node: 'ubuntu16.04-basebuild-1c-2g'
# for nucleus
- project:
name: Nucleus
project: '{name}'
build-node: 'intel-102'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-combined':
pipeline-file: 'Jenkinsfile-omec-combined.groovy'
mme-repo: 'Nucleus'
- 'omec-install':
sub-project: '{name}'
branch: 'master'
pipeline-file: 'Jenkinsfile-omec-install-Nucleus-vnf.groovy'
- 'omec-fossa':
pipeline-file: 'omec-fossa-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-reuse':
pipeline-file: 'omec-reuse-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'docker-publish-github':
build-timeout: 60
docker-repo: 'omecproject'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-container'
# for freediameter
- project:
name: freediameter
project: '{name}'
build-node: 'intel-102'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-fossa':
pipeline-file: 'omec-fossa-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-reuse':
pipeline-file: 'omec-reuse-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
# for ignite
- project:
name: ignite
project: '{name}'
build-node: 'intel-102'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-fossa':
pipeline-file: 'omec-fossa-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-reuse':
pipeline-file: 'omec-reuse-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
# for upf-epc
- project:
name: upf-epc
project: '{name}'
github-organization: 'omec-project'
github_pr_auth_id: '64fe2b1a-b33a-4f13-8442-ad8360434003'
github_pr_org_list:
- 'omec-project'
jobs:
- 'omec-fossa':
pipeline-file: 'omec-fossa-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'omec-reuse':
pipeline-file: 'omec-reuse-scan.groovy'
build-node: 'ubuntu16.04-basebuild-1c-2g'
- 'docker-publish-github':
build-timeout: 30
docker-repo: 'omecproject'
build-node: 'ubuntu16.04-basebuild-2c-4g'
extraEnvironmentVars: CPU=haswell
- 'omec-container'
# Combined pipeline
- job-template:
id: 'omec-combined'
name: 'omec_{project}_combined'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created by {id} job-template from ci-management/jjb/omec-ci.yaml<br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
- github:
url: 'https://github.com/{github-organization}/{project}'
- build-blocker:
use-build-blocker: true
blocking-jobs:
- "omec_.*_combined"
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on'
- string:
name: project
default: '{project}'
description: 'Name of the project'
- string:
name: mmeRepo
default: '{mme-repo}'
description: 'Name of the MME repo to test (openmme/Nucleus)'
triggers:
- cord-infra-github-pr-trigger:
github_pr_org_list: '{obj:github_pr_org_list}'
github_pr_auth_id: '{github_pr_auth_id}'
status_context: 'CORD Jenkins - Combined Steps Verification'
concurrent: false
pipeline-scm:
script-path: '{pipeline-file}'
scm:
- git:
url: 'https://github.com/{github-organization}/omec-project-ci'
branches:
- 'master'
# install jobs, run for each project
- job-template:
id: 'omec-install'
name: 'omec_{sub-project}_install'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created by {id} job-template from ci-management/jjb/omec-ci.yaml<br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
- github:
url: 'https://github.com/{github-organization}/{project}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on'
- string:
name: project
default: '{project}'
description: 'Name of the project'
- string:
name: branch
default: '{branch}'
description: 'Branch of the project'
concurrent: false
pipeline-scm:
script-path: '{pipeline-file}'
scm:
- git:
url: 'https://github.com/{github-organization}/omec-project-ci'
branches:
- 'master'
# FOSSA License Scan
- job-template:
id: 'omec-fossa'
name: 'omec_{project}_fossa'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created by {id} job-template from ci-management/jjb/omec-ci.yaml<br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
- github:
url: 'https://github.com/{github-organization}/{project}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: ghprbPullId
default: '$ghprbPullId'
description: 'Pull request number to fetch changes from. Leave blank to run manually.'
- string:
name: branch
default: '$ghprbTargetBranch'
description: 'Branch to run. Only used when manually run.'
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on'
- string:
name: project
default: '{project}'
description: 'Name of the project'
- string:
name: ghprbGhRepository
default: '{github-organization}/{project}'
description: 'Repository of the project.'
triggers:
- cord-infra-github-pr-trigger:
github_pr_org_list: '{obj:github_pr_org_list}'
github_pr_auth_id: '{github_pr_auth_id}'
status_context: 'CORD Jenkins - FOSSA Verification'
concurrent: false
project-type: pipeline
dsl: !include-raw-escape: pipeline/{pipeline-file}
# REUSE License Scan
- job-template:
id: 'omec-reuse'
name: 'omec_{project}_reuse'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created by {id} job-template from ci-management/jjb/omec-ci.yaml<br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
- github:
url: 'https://github.com/{github-organization}/{project}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: ghprbPullId
default: '$ghprbPullId'
description: 'Pull request number to fetch changes from. Leave blank to run manually.'
- string:
name: branch
default: '$ghprbTargetBranch'
description: 'Branch to run. Only used when manually run.'
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on'
- string:
name: project
default: '{project}'
description: 'Name of the project'
- string:
name: ghprbGhRepository
default: '{github-organization}/{project}'
description: 'Repository of the project.'
triggers:
- cord-infra-github-pr-trigger:
github_pr_org_list: '{obj:github_pr_org_list}'
github_pr_auth_id: '{github_pr_auth_id}'
status_context: 'CORD Jenkins - Licenses Verification'
concurrent: false
project-type: pipeline
dsl: !include-raw-escape: pipeline/{pipeline-file}
# tests
- job-template:
id: 'omec-tc1'
name: 'omec_tc1'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created by {id} job-template from ci-management/jjb/omec-ci.yaml<br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on'
- string:
name: mmeRepo
default: 'openmme'
description: 'Name of the MME repo to test (openmme/Nucleus)'
concurrent: false
pipeline-scm:
script-path: 'Jenkinsfile-omec-test-TC1.groovy'
scm:
- git:
url: 'https://github.com/omec-project/omec-project-ci'
branches:
- 'master'
- job-template:
id: 'omec-tc2'
name: 'omec_tc2'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created by {id} job-template from ci-management/jjb/omec-ci.yaml<br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on'
- string:
name: mmeRepo
default: 'openmme'
description: 'Name of the MME repo to test (openmme/Nucleus)'
concurrent: false
pipeline-scm:
script-path: 'Jenkinsfile-omec-test-TC2.groovy'
scm:
- git:
url: 'https://github.com/omec-project/omec-project-ci'
branches:
- 'master'
# Post-merge job
# Triggered by Github pull request merge
- job-template:
id: omec-postmerge
name: '{project}_postmerge'
description: |
Created by {id} job-template from ci-management/jjb/omec-ci.yaml
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
triggers:
- cord-infra-github-pr-trigger-merge:
project: '{project}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins node to run the job on'
- string:
name: registry
default: 'omecproject'
description: 'Docker registry to push images to'
- string:
name: repoName
default: ''
description: 'Name of the git repo. Populated by Generic Webhook Trigger'
- string:
name: repoUrl
default: ''
description: 'URL to the git repo. Populated by Generic Webhook Trigger'
- string:
name: branchName
default: ''
description: 'Branch of the project. Populated by Generic Webhook Trigger'
- string:
name: commitHash
default: ''
description: 'SHA string of the merged commit. Populated by Generic Webhook Trigger'
- string:
name: c3poBranchName
default: '{c3po-branch-name}'
description: 'Branch name of c3po repo which we run tests against'
- string:
name: spgwBranchName
default: '{spgw-branch-name}'
description: 'Branch name of spgw repo which we run tests against'
- string:
name: nucleusBranchName
default: '{nucleus-branch-name}'
description: 'Branch name of Nucleus repo which we run tests against'
- string:
name: upfBranchName
default: '{upf-branch-name}'
description: 'Branch name of upf-epc repo which we run tests against'
- string:
name: maintainers
default: 'jeremyr@opennetworking.org, you@opennetworking.org'
description: "The person that sould be notified if this job fails"
project-type: pipeline
concurrent: false
dsl: !include-raw-escape: pipeline/{pipeline-file}
# OMEC CI job which builds docker images, deploys and tests OMEC
- job-template:
id: 'omec-container'
name: 'omec_{project}_container'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created by {id} job-template from ci-management/jjb/omec-ci.yaml<br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
- github:
url: 'https://github.com/{github-organization}/{project}'
- build-blocker:
use-build-blocker: true
blocking-jobs:
- ".*_container"
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: 'omec-ci'
description: 'Name of the Jenkins executor node to run the job on'
- string:
name: project
default: '{project}'
description: 'Name of the project'
- string:
name: ghprbTargetBranch
default: '$ghprbTargetBranch'
description: 'GitHub Pull-Request builder value. Replace default value to test manually.'
- string:
name: ghprbPullId
default: '$ghprbPullId'
description: 'GitHub Pull-Request builder value. Replace default value to test manually.'
- string:
name: ghprbActualCommit
default: '$ghprbActualCommit'
description: 'GitHub Pull-Request builder value. Replace default value to test manually.'
- string:
name: registry
default: 'registry.aetherproject.org/omecproject'
description: 'Docker registry that stores images built for CI testing'
- string:
name: c3poBranch
default: 'master'
description: 'Branch name of c3po repo which we run tests against'
- string:
name: nucleusBranch
default: 'master'
description: 'Branch name of Nucleus repo which we run tests against'
- string:
name: spgwBranch
default: 'master'
description: 'Branch name of spgw repo which we run tests against'
- string:
name: upfBranch
default: 'master'
description: 'Branch name of upf-epc repo which we run tests against'
triggers:
- cord-infra-github-pr-trigger:
github_pr_org_list: '{obj:github_pr_org_list}'
github_pr_auth_id: '{github_pr_auth_id}'
status_context: 'CORD Jenkins - Container Based Verification'
concurrent: false
pipeline-scm:
script-path: 'Jenkinsfile-omec-container.groovy'
scm:
- git:
url: 'https://github.com/{github-organization}/omec-project-ci'
branches:
- 'master'
# OMEC deployment job
- job-template:
id: 'omec-deploy'
name: 'omec_deploy_{pod}'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created from job-template {id} from ci-management/jjb/omec-ci.yaml <br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on.'
- string:
name: cpContext
default: '{cp-context}'
description: 'K8S context for omec control plane.'
- string:
name: dpContext
default: '{dp-context}'
description: 'K8S context for omec data plane.'
- string:
name: centralConfig
default: '{central-config}'
description: 'Directory name for central yaml files under aether-pod-configs.'
- string:
name: edgeConfig
default: '{edge-config}'
description: 'Directory name for edge yaml files under aether-pod-configs.'
- string:
name: hssdbImage
default: 'omecproject/c3po-hssdb:master-latest'
description: 'Docker image for hssdb. Leave empty to use default helm-charts value'
- string:
name: hssImage
default: 'omecproject/c3po-hss:master-latest'
description: 'Docker image for hss. Leave empty to use default helm-charts value'
- string:
name: mmeImage
default: 'omecproject/nucleus:master-latest'
description: 'Docker image for mme. Leave empty to use default helm-charts value'
- string:
name: spgwcImage
default: 'omecproject/spgw:master-latest'
description: 'Docker image for spgwc. Leave empty to use default helm-charts value'
- string:
name: bessImage
default: 'omecproject/upf-epc-bess:master-latest'
description: 'Docker image for bess. Leave empty to use default helm-charts value'
- string:
name: zmqifaceImage
default: 'omecproject/upf-epc-cpiface:master-latest'
description: 'Docker image for zmqiface. Leave empty to use default helm-charts value'
- string:
name: pfcpifaceImage
default: 'omecproject/upf-epc-pfcpiface:master-latest'
description: 'Docker image for pfcpiface. Leave empty to use default helm-charts value'
concurrent: false
pipeline-scm:
script-path: 'Jenkinsfile-omec-deploy.groovy'
scm:
- git:
url: 'https://github.com/{github-organization}/omec-project-ci'
branches:
- 'master'
# OMEC test job
- job-template:
id: 'omec-ng40-test'
name: 'omec_ng40-test_{pod}'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created from job-template {id} from ci-management/jjb/omec-ci.yaml <br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on.'
- string:
name: timeout
default: '30'
description: 'Timeout period for this pipeline in minutes.'
- string:
name: ng40VM
default: '{ng40-vm}'
description: 'user@IP for accessing NG40 VM from the build node.'
- string:
name: ntlFile
default: 'ci.ntl'
description: 'NG40 test automation file'
- string:
name: cpContext
default: '{cp-context}'
description: 'K8S context for omec control plane.'
- string:
name: dpContext
default: '{dp-context}'
description: 'K8S context for omec data plane.'
concurrent: false
pipeline-scm:
script-path: 'Jenkinsfile-omec-ng40-test.groovy'
scm:
- git:
url: 'https://github.com/{github-organization}/omec-project-ci'
branches:
- 'master'
# OMEC archive artifacts job
- job-template:
id: 'omec-archive-artifacts'
name: 'omec_archive-artifacts_{pod}'
project-type: pipeline
description: |
<!-- Managed by Jenkins Job Builder -->
Created from job-template {id} from ci-management/jjb/omec-ci.yaml <br />
properties:
- cord-infra-properties:
build-days-to-keep: '{build-days-to-keep}'
artifact-num-to-keep: '{artifact-num-to-keep}'
wrappers:
- lf-infra-wrappers:
build-timeout: '{build-timeout}'
jenkins-ssh-credential: '{jenkins-ssh-credential}'
parameters:
- string:
name: buildNode
default: '{build-node}'
description: 'Name of the Jenkins executor node to run the job on.'
- string:
name: cpContext
default: '{cp-context}'
description: 'K8S context for omec control plane.'
- string:
name: dpContext
default: '{dp-context}'
description: 'K8S context for omec data plane.'
- string:
name: logSince
default: '{log-since}'
description: 'Only upload logs newer than a relative duration e.g. 1h'
concurrent: false
pipeline-scm:
script-path: 'Jenkinsfile-omec-archive-artifacts.groovy'
scm:
- git:
url: 'https://github.com/{github-organization}/omec-project-ci'
branches:
- 'master'