Skip to content

Commit bf65db3

Browse files
committed
Switch Buildkite from pipeline upload to API
* Add script for CRUDding Buildkite pipelines from yaml files * Add opx-build and github pipelines * Add Pipfile Signed-off-by: Tyler Heucke <[email protected]>
1 parent b07fa84 commit bf65db3

File tree

6 files changed

+333
-33
lines changed

6 files changed

+333
-33
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
.mypy_cache
2+
.venv/

Pipfile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[[source]]
2+
3+
url = "https://pypi.python.org/simple"
4+
verify_ssl = true
5+
name = "pypi"
6+
7+
8+
[packages]
9+
10+
requests = "*"
11+
PyYAML = "*"
12+
13+
14+
[dev-packages]
15+
16+
17+
18+
[requires]
19+
20+
python_version = "3.6"

Pipfile.lock

+77
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/buildkite

+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#!/usr/bin/env python3.6
2+
"""CRUD for Buildkite pipelines. Reads from YAML files."""
3+
4+
import argparse
5+
import errno
6+
import logging
7+
import json
8+
import os
9+
import sys
10+
11+
from pathlib import Path
12+
13+
import requests
14+
import yaml
15+
16+
L = logging.getLogger('Buildkite')
17+
L.addHandler(logging.NullHandler())
18+
19+
API = 'https://api.buildkite.com/v2/organizations/opx/pipelines'
20+
21+
DEBIAN_REPOS = [
22+
'SAI',
23+
'opx-alarm',
24+
'opx-base-model',
25+
'opx-common-utils',
26+
'opx-cps',
27+
'opx-db-sql',
28+
'opx-logging',
29+
'opx-nas-acl',
30+
'opx-nas-common',
31+
'opx-nas-daemon',
32+
'opx-nas-interface',
33+
'opx-nas-l2',
34+
'opx-nas-l3',
35+
'opx-nas-linux',
36+
'opx-nas-ndi',
37+
'opx-nas-ndi-api',
38+
'opx-nas-qos',
39+
'opx-northbound',
40+
'opx-pas',
41+
'opx-platform-config',
42+
'opx-sai-vm',
43+
'opx-sdi-sys',
44+
'opx-snmp',
45+
'opx-tmpctl',
46+
'opx-tools',
47+
]
48+
49+
50+
ALL_REPOS = DEBIAN_REPOS + [
51+
'continuous-integration',
52+
'github',
53+
'opx-build',
54+
'opx-core',
55+
'opx-docs',
56+
'opx-manifest',
57+
'opx-northbound',
58+
'opx-onie-installer',
59+
'opx-test',
60+
'rootfs',
61+
'tools_opx-py',
62+
]
63+
64+
65+
def fatal(msg: str) -> None:
66+
"""Aborts."""
67+
L.error(msg)
68+
sys.exit(1)
69+
70+
71+
class Pipeline:
72+
"""Represents a Buildkite pipeline."""
73+
def __init__(self, name: str) -> None:
74+
self.name = name
75+
self.file = Path(f'buildkite/{name}.yaml')
76+
77+
if not self.file.exists():
78+
if name in DEBIAN_REPOS:
79+
self.file = Path('buildkite/opx-debian.yaml')
80+
else:
81+
raise FileNotFoundError(errno.ENOENT,
82+
os.strerror(errno.ENOENT),
83+
str(self.file))
84+
85+
def exists(self) -> bool:
86+
"""Returns True if Buildkite says the pipeline exists."""
87+
L.debug(f'checking if {self.name} pipeline exists')
88+
return requests.get(f'{API}/{self.name}').status_code == 200
89+
90+
def create(self) -> str:
91+
"""Creates pipeline if it doesn't already exist.
92+
93+
Pipeline configuration is converted to json and pushed.
94+
"""
95+
if self.exists():
96+
fatal(f'Pipeline {self.name} already exists')
97+
else:
98+
L.info(f'Running create on {self.name} with {self.file}')
99+
100+
pipeline = yaml.safe_load(self.file.open().read())
101+
res = requests.post(f'{API}', json=pipeline)
102+
res.raise_for_status()
103+
return json.dumps(res.json(), indent=4, sort_keys=True)
104+
105+
def read(self) -> str:
106+
"""Retrieves current pipeline configuration from Buildkite."""
107+
if not self.exists():
108+
fatal(f'Pipeline {self.name} does not exist')
109+
else:
110+
L.info(f'Running read on {self.name}')
111+
112+
res = requests.get(f'{API}/{self.name}')
113+
res.raise_for_status()
114+
return json.dumps(res.json(), indent=4, sort_keys=True)
115+
116+
def update(self) -> str:
117+
"""Updates pipeline if it already exists.
118+
119+
Pipeline configuration is converted to json and pushed.
120+
"""
121+
if not self.exists():
122+
fatal(f'Pipeline {self.name} does not exist')
123+
else:
124+
L.info(f'Running update on {self.name} with {self.file}')
125+
126+
pipeline = yaml.safe_load(self.file.open().read())
127+
res = requests.patch(f'{API}/{self.name}', json=pipeline)
128+
res.raise_for_status()
129+
return json.dumps(res.json(), indent=4, sort_keys=True)
130+
131+
def delete(self) -> str:
132+
"""Deletes pipeline if it already exists."""
133+
if not self.exists():
134+
fatal(f'Pipeline {self.name} does not exist')
135+
else:
136+
L.info(f'Running delete on {self.name}')
137+
138+
res = requests.delete(f'{API}/{self.name}')
139+
res.raise_for_status()
140+
return 'deleted'
141+
142+
143+
def main():
144+
"""Entrypoint."""
145+
parser = argparse.ArgumentParser(description=__doc__)
146+
147+
parser.add_argument(
148+
'-v', '--verbose',
149+
help='log debug messages',
150+
action='store_const',
151+
dest='loglevel',
152+
const=logging.DEBUG,
153+
default=logging.INFO,
154+
)
155+
156+
parser.add_argument(
157+
'action',
158+
help='action to perform',
159+
choices=['create', 'read', 'update', 'delete'],
160+
)
161+
162+
parser.add_argument(
163+
'name',
164+
help='name of pipeline',
165+
)
166+
167+
args = parser.parse_args()
168+
logging.basicConfig(level=args.loglevel)
169+
L.debug(str(args))
170+
171+
print(getattr(Pipeline(args.name), args.action)())
172+
173+
174+
if __name__ == '__main__':
175+
main()

buildkite/github.yaml

+34-33
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
1+
name: github
2+
description: OpenSwitch GitHub organization
3+
repository: "https://github.com/open-switch/github"
4+
skip_queued_branch_builds: true
5+
skip_queued_branch_builds_filter: "!master"
6+
provider_settings:
7+
build_pull_request_forks: true
8+
build_pull_requests: true
9+
build_tags: false
10+
prefix_pull_request_fork_branch_names: true
11+
publish_commit_status: true
12+
publish_commit_status_per_step: false
13+
pull_request_branch_filter_enabled: false
14+
skip_pull_request_builds_for_existing_commits: true
15+
trigger_mode: "code"
16+
env:
17+
TF: "'docker run -it -w /tf -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e TF_VAR_github_access_token'"
118
steps:
2-
- label: ":terraform: plan"
3-
command:
4-
- terraform init -input=false
5-
- terraform plan -input=false -out=tfplan
19+
- name: ":terraform: plan"
20+
type: script
21+
agent_query_rules: [ "queue=deploy" ]
622
artifact_paths: tfplan
7-
plugins:
8-
docker#v1.1.1:
9-
image: hashicorp/terraform
10-
environment:
11-
- AWS_ACCESS_KEY_ID
12-
- AWS_SECRET_ACCESS_KEY
13-
- TF_VAR_github_access_token
14-
agents:
15-
queue: deploy
1623
concurrency: 1
17-
concurrency_group: terraform/github
18-
19-
- wait
20-
21-
- label: ':terraform: apply'
22-
branches: 'master'
23-
command:
24-
- buildkite-agent artifact download tfplan .
25-
- terraform init -input=false
26-
- terraform apply -input=false tfplan
27-
plugins:
28-
docker#v1.1.1:
29-
image: hashicorp/terraform
30-
environment:
31-
- AWS_ACCESS_KEY_ID
32-
- AWS_SECRET_ACCESS_KEY
33-
- TF_VAR_github_access_token
34-
agents:
35-
queue: deploy
24+
concurrency_group: "terraform/github"
25+
command: |
26+
$TF -v $(pwd):/tf hashicorp/terraform init -input=false
27+
$TF -v $(pwd):/tf hashicorp/terraform plan -input=false -out=tfplan
28+
- type: waiter
29+
- name: ":terraform: apply"
30+
type: script
31+
branch_configuration: "master"
32+
agent_query_rules: [ "queue=deploy" ]
3633
concurrency: 1
37-
concurrency_group: terraform/github
34+
concurrency_group: "terraform/github"
35+
command: |
36+
buildkite-agent artifact download tfplan .
37+
$TF -v $(pwd):/tf hashicorp/terraform init -input=false
38+
$TF -v $(pwd):/tf hashicorp/terraform apply -input=false tfplan

buildkite/opx-build.yaml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: opx-build
2+
description: OpenSwitch build tools and environment
3+
repository: "https://github.com/open-switch/opx-build"
4+
skip_queued_branch_builds: true
5+
skip_queued_branch_builds_filter: "!master"
6+
provider_settings:
7+
build_pull_request_forks: true
8+
build_pull_requests: true
9+
build_tags: false
10+
prefix_pull_request_fork_branch_names: true
11+
publish_commit_status: true
12+
publish_commit_status_per_step: false
13+
pull_request_branch_filter_enabled: false
14+
skip_pull_request_builds_for_existing_commits: true
15+
trigger_mode: "code"
16+
steps:
17+
- name: ":docker: opxhub/build"
18+
type: script
19+
command: ./docker_build.sh
20+
- type: waiter
21+
- name: ":docker: push"
22+
type: script
23+
branch_configuration: "master"
24+
command: |
25+
docker push opxhub/build:$(git log -1 --pretty=%h)
26+
docker push opxhub/build:latest

0 commit comments

Comments
 (0)