Skip to content

Commit 1378d7c

Browse files
committed
Added and adapted jinja2 templates for tracks with a build container.
1 parent c57e30d commit 1378d7c

File tree

12 files changed

+155
-30
lines changed

12 files changed

+155
-30
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ jobs:
160160
- name: Test deployment looping through tracks
161161
working-directory: test-ctf
162162
run: |
163-
IFS=" " read -r -a tracks <<< "$(python3 -c 'from ctf.utils import get_all_available_tracks,validate_track_can_be_deployed;print(str([t for t in get_all_available_tracks() if validate_track_can_be_deployed(t)]).strip("[]\x27").replace("\x27, \x27"," "))')"
163+
IFS=" " read -r -a tracks <<< "$(python3 -c 'from ctf.utils import get_all_available_tracks,validate_track_can_be_deployed;print(str([t.name for t in get_all_available_tracks() if validate_track_can_be_deployed(t)]).strip("[]\x27").replace("\x27, \x27"," "))')"
164164
165165
[ "${#tracks[@]}" -eq 0 ] && exit 1
166166

ctf/generate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def generate(
4949
track
5050
for track in get_all_available_tracks()
5151
if validate_track_can_be_deployed(track=track)
52-
and (not tracks or track in tracks)
52+
and (not tracks or track.name in tracks)
5353
)
5454

5555
if distinct_tracks:

ctf/new.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ def new(
3939
help="If directory already exists, delete it and create it again.",
4040
),
4141
] = False,
42+
with_build_container: Annotated[
43+
bool,
44+
typer.Option(
45+
"--with-build",
46+
help="If a build container is required.",
47+
),
48+
] = False,
4249
) -> None:
4350
LOG.info(msg=f"Creating a new track: {name}")
4451
if not re.match(pattern=r"^[a-z][a-z0-9\-]{0,61}[a-z0-9]$", string=name):
@@ -175,6 +182,7 @@ def new(
175182
"ipv6": ipv6_address,
176183
"ipv6_subnet": ipv6_subnet,
177184
"full_ipv6_address": full_ipv6_address,
185+
"with_build": with_build_container,
178186
}
179187
)
180188
with open(
@@ -212,7 +220,9 @@ def new(
212220
LOG.debug(msg=f"Directory {ansible_directory} created.")
213221

214222
track_template = env.get_template(name=os.path.join(template, "deploy.yaml.j2"))
215-
render = track_template.render(data={"name": name})
223+
render = track_template.render(
224+
data={"name": name, "with_build": with_build_container}
225+
)
216226
with open(
217227
file=(p := os.path.join(ansible_directory, "deploy.yaml")),
218228
mode="w",
@@ -222,8 +232,23 @@ def new(
222232

223233
LOG.debug(msg=f"Wrote {p}.")
224234

235+
if with_build_container:
236+
track_template = env.get_template(name=os.path.join("common", "build.yaml.j2"))
237+
render = track_template.render(
238+
data={"name": name, "with_build": with_build_container}
239+
)
240+
with open(
241+
file=(p := os.path.join(ansible_directory, "build.yaml")),
242+
mode="w",
243+
encoding="utf-8",
244+
) as f:
245+
f.write(render)
246+
LOG.debug(msg=f"Wrote {p}.")
247+
225248
track_template = env.get_template(name=os.path.join("common", "inventory.j2"))
226-
render = track_template.render(data={"name": name})
249+
render = track_template.render(
250+
data={"name": name, "with_build": with_build_container}
251+
)
227252
with open(
228253
file=(p := os.path.join(ansible_directory, "inventory")),
229254
mode="w",

ctf/templates/init/.deploy/cleanup.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
- name: Pre-deployment system cleanup
2-
hosts: all
2+
hosts: all,!build
33
order: shuffle
44
gather_facts: false
55
any_errors_fatal: true

ctf/templates/init/.deploy/common.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
- name: Pre-deployment Common
2-
hosts: all
2+
hosts: all,!build
33
order: shuffle
44
gather_facts: false
55
any_errors_fatal: true

ctf/templates/init/.deploy/common/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ variable "deploy" {
88
type = string
99
}
1010

11+
variable "build_container" {
12+
default = false
13+
type = bool
14+
}
15+
16+
1117
locals {
1218
track = yamldecode(file("${path.module}/../track.yaml"))
1319
}

ctf/templates/new/apache-php/deploy.yaml.j2

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Example on how to run stuff on all hosts of the track
44
- name: "Install Apache2 and PHP on each host"
5-
hosts: "*"
5+
hosts: all{% if data.with_build %},!build{% endif %}
66
vars_files:
77
- ../track.yaml
88
tasks:
@@ -16,7 +16,7 @@
1616
value: "{{ '{{ item.flag }}' }}"
1717
ansible.builtin.set_fact:
1818
track_flags: "{{ '{{ track_flags | default({}) | combine({key: value}) }}' }}"
19-
19+
2020
- name: Initial System Upgrade
2121
ansible.builtin.apt:
2222
update_cache: true
@@ -57,7 +57,7 @@
5757

5858
# Configure Apache to restart automatically on all hosts
5959
- name: "Configure Apache2 on each host and restart it"
60-
hosts: "*"
60+
hosts: all{% if data.with_build %},!build{% endif %}
6161
tasks:
6262
- name: Restart Apache2 on failure
6363
ansible.builtin.replace:
@@ -69,4 +69,13 @@
6969
ansible.builtin.service:
7070
name: apache2
7171
state: restarted
72-
72+
{% if data.with_build %}
73+
# When using a build container, the unarchive module can be used to install the content on the remote.
74+
- name: Unarchive the content of the build
75+
ansible.builtin.unarchive:
76+
src: /tmp/build.tar
77+
dest: /tmp/
78+
owner: root
79+
group: root
80+
mode: '0755'
81+
{% endif %}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
- name: "Build container"
2+
hosts: "build-container"
3+
vars_files:
4+
- ../track.yaml
5+
tasks:
6+
- name: "Load flags"
7+
loop: "{{ '{{ flags }}' }}"
8+
vars:
9+
key: "{{ '{{ (item.tags).discourse }}' }}"
10+
value: "{{ '{{ item.flag }}' }}"
11+
ansible.builtin.set_fact:
12+
track_flags: "{{ '{{ track_flags | default({}) | combine({key: value}) }}' }}"
13+
14+
- name: Initial System Upgrade
15+
ansible.builtin.apt:
16+
update_cache: true
17+
install_recommends: false
18+
upgrade: full
19+
20+
# Install tools to compile/build the track
21+
- name: Install GCC
22+
ansible.builtin.apt:
23+
name:
24+
- gcc
25+
state: present
26+
27+
# Copy the challenge on the container
28+
- name: Create main.c
29+
ansible.builtin.copy:
30+
dest: /tmp/main.c
31+
mode: '0644'
32+
owner: root
33+
group: root
34+
content: |
35+
#include <stdio.h>
36+
37+
int main() {
38+
printf("{{ '{{' }} track_flags.{{ data.name | replace("-","_") }}_flag_1 {{ '}}' }} (1/1)");
39+
return 0;
40+
}
41+
42+
# Compile the program
43+
- name: Build main program
44+
ansible.builtin.command: gcc /tmp/main.c -o /tmp/main
45+
changed_when: false
46+
47+
# Create a TAR archive with the compiled program
48+
- name: Create archive of build
49+
community.general.archive:
50+
path: /tmp/main
51+
dest: /tmp/build.tar
52+
format: tar
53+
mode: '0644'
54+
55+
# Extract the archive from the build container and save it on the local host
56+
- name: Fetch archive
57+
ansible.builtin.fetch:
58+
src: /tmp/build.tar
59+
dest: /tmp/
60+
flat: true

ctf/templates/new/common/inventory.j2

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ all:
1515
ansible_incus_project: {{ data.name }}
1616

1717
# Add variables if needed here.
18+
{% if data.with_build %}
19+
build:
20+
hosts:
21+
build-container:
22+
ansible_incus_host: build-container
23+
{% endif %}

ctf/templates/new/common/main.tf.j2

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,15 @@ resource "incus_instance" "this" {
105105
ignore_changes = [running]
106106
}
107107
}
108-
108+
{% if data.with_build %}
109109
# AUTOGENERATED - No need to change this section #
110110
resource "incus_instance" "build_container" {
111111
count = var.build_container ? 1 : 0
112112

113113
remote = var.incus_remote
114114
project = incus_project.this.name
115115

116-
name = "build_container"
116+
name = "build-container"
117117

118118
image = "images:ubuntu/24.04"
119119
profiles = ["default"]
@@ -132,12 +132,24 @@ resource "incus_instance" "build_container" {
132132
"name" = "eth0"
133133
}
134134
}
135+
136+
device {
137+
name = "root"
138+
type = "disk"
139+
140+
properties = {
141+
"pool" = "default"
142+
"path" = "/"
143+
# This limit should only be adjusted if you NEED more resources.
144+
"size" = "1GiB"
145+
}
146+
}
135147

136148
lifecycle {
137149
ignore_changes = [running]
138150
}
139151
}
140-
152+
{% endif %}
141153
# AUTOGENERATED - No need to change this section #
142154
resource "incus_network_zone_record" "this" {
143155
remote = var.incus_remote

0 commit comments

Comments
 (0)