Skip to content
This repository was archived by the owner on Oct 15, 2020. It is now read-only.

Commit 08c86a5

Browse files
authored
Merge pull request #38 from OSAS/nikola_support
add Nikola builder support
2 parents 522fd74 + 551304f commit 08c86a5

File tree

12 files changed

+116
-45
lines changed

12 files changed

+116
-45
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Currently this role supports the following web generators:
66
* Ascii Binder (http://asciibinder.org/)
77
* [Jekyll](https://jekyllrb.com/)
88
* [Middleman](https://middlemanapp.com/)
9+
* [Nikola](https://getnikola.com/)
910
* Planet (using Planet Venus)
1011

1112
# Example
@@ -58,6 +59,13 @@ the time between automated rebuild attempts if nothing changed, expressed in hou
5859

5960
This feature is disabled on containers.
6061

62+
# Builder deployment specific parameters
63+
64+
Sometimes a builder deployment really needs to be adapted because there is no way to do so later in the build configuration.
65+
66+
- **nikola_theme**: theme name to install using Nikola's repository
67+
(the configuration file is not parsed, you need to maintain both parameters in sync)
68+
6169
# Debug the build
6270

6371
In order to debug a non working build, the easiest is to connect to the

molecule/_resources/Dockerfile.j2

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ FROM {{ item.registry.url }}/{{ item.image }}
66
FROM {{ item.image }}
77
{% endif %}
88

9+
# on Red Hat systems using dnf, Python 3 is already installed
10+
# the package is versioned and there is no 'python3' dependency package, so better do nothing
911
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get upgrade -y && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
10-
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python3-devel python3-dnf bash && dnf clean all; \
12+
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install sudo python3-devel python3-dnf bash && dnf clean all; \
1113
elif [ $(command -v yum) ]; then yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
1214
elif [ $(command -v zypper) ]; then zypper refresh && zypper update -y && zypper install -y python sudo bash python-xml && zypper clean -a; \
1315
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; fi

molecule/_resources/prepare.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- hostname
1111
- glibc-all-langpacks
1212
state: installed
13-
when: ansible_distribution == 'Fedora'
13+
when: ansible_distribution == 'Fedora' or (ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 8)
1414
# to ensure having a real FQDN
1515
# (dots are not allowed in LXD container names, thus sticking to short names)
1616
- name: set proper hostname

molecule/base_molecule.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ provisioner:
2727
aliases:
2828
# allow access via short DNS name
2929
- "{{ item.name }}"
30+
# used to switch the testing branch
31+
tests_is_container: False
3032
host_vars:
3133
ansible-test-builder:
3234
ansible-test-web:

molecule/nikola-el8/molecule.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
scenario:
3+
name: nikola-el8
4+
platforms:
5+
- name: ansible-test-builder
6+
# LXD
7+
source:
8+
alias: 'centos/8/amd64'
9+
# Docker
10+
image: 'centos:8'
11+
# this one is always the same
12+
- name: ansible-test-web
13+
# LXD
14+
source:
15+
alias: 'centos/8/amd64'
16+
# Docker
17+
image: 'centos:8'
18+
provisioner:
19+
inventory:
20+
host_vars:
21+
ansible-test-builder:
22+
builder: nikola
23+
# known working website
24+
git_url: https://pagure.io/koji-site.git
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../_resources/tests/test_default.py

molecule/planet-el7/molecule.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ provisioner:
2121
ansible-test-builder:
2222
builder: planet
2323
# known working website
24-
git_url: https://github.com/redhat-openstack/website.git
24+
git_url: https://gitlab.com/osas/ansible-role-web_builder_test_planet.git

tasks/main.yml

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
- "{{ ansible_distribution }}.yml"
77
- "{{ ansible_os_family }}.yml"
88

9+
- name: "Enable PowerTools RPM Repository"
10+
ini_file:
11+
path: /etc/yum.repos.d/CentOS-PowerTools.repo
12+
section: PowerTools
13+
option: enabled
14+
value: '1'
15+
when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 8
16+
917
- name: Install common and builder-specific packages
1018
package:
1119
name: "{{ package_list['common'] + package_list[builder] }}"
@@ -24,7 +32,7 @@
2432
checkout_dir: "/srv/builder/{{ builder_name }}"
2533

2634
- name: Deploy the build script
27-
copy:
35+
template:
2836
dest: /usr/local/bin/build_deploy.py
2937
src: build_deploy.py
3038
mode: 0755
@@ -95,6 +103,17 @@
95103
changed_when: False
96104
when: gemfile_st.stat.exists
97105

106+
# after workdir is setup as it might use it
107+
- name: "Extra builder setup"
108+
command: "{{ item }}"
109+
args:
110+
chdir: "{{ checkout_dir }}"
111+
become: yes
112+
become_user: '{{ builder_username }}'
113+
become_method: 'su'
114+
changed_when: False
115+
loop: "{{ builder_setup[builder] | default([]) }}"
116+
98117
- name: Clear RSYNC URL
99118
set_fact:
100119
rsync_url: "nosync"
@@ -122,9 +141,9 @@
122141

123142
- name: "Schedule build and sync"
124143
include_tasks: schedule_build_and_sync.yml
125-
when: ansible_env.container is undefined
144+
when: (tests_is_container is defined) | ternary(not tests_is_container, ansible_env.container is undefined)
126145

127146
- name: "Build now (container)"
128147
include_tasks: build.yml
129-
when: ansible_env.container is defined and builder_container_build_now|bool
148+
when: ((tests_is_container is defined) | ternary(tests_is_container, ansible_env.container is defined)) and builder_container_build_now|bool
130149

files/build_deploy.py renamed to templates/build_deploy.py

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/python
1+
#!/usr/bin/python{{ ((ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 8) or (ansible_os_family == "Debian" and ansible_distribution_major_version|int >= 10)) | ternary('3', '') }}
22
#
33
# Copyright (c) 2015 Michael Scherer <[email protected]>
44
#
@@ -80,6 +80,12 @@
8080
'build_command': ['/srv/builder/planet-venus/planet.py', '-v', 'planet.ini'],
8181
'build_subdir': 'build',
8282
'deploy_command': None
83+
},
84+
'nikola': {
85+
'build_env': {},
86+
'build_command': ['../.local/bin/nikola', 'build'],
87+
'build_subdir': 'output',
88+
'deploy_command': None
8389
}
8490
}
8591

@@ -96,47 +102,47 @@ def log_print(message):
96102

97103
def debug_print(message):
98104
if args.debug:
99-
print message
105+
print(message)
100106
log_print(message)
101107

102108

103109
def refresh_checkout(checkout_dir):
104110
os.chdir(checkout_dir)
105111
try:
106112
result = subprocess.check_output(['git', 'fetch', '-q'], stderr=subprocess.STDOUT)
107-
except subprocess.CalledProcessError, C:
113+
except subprocess.CalledProcessError as C:
108114
notify_error('setup', C.output)
109-
debug_print(result)
115+
debug_print(result.decode())
110116

111117

112118
def get_last_commit(checkout_dir):
113119
os.chdir(checkout_dir)
114120
try:
115121
r = subprocess.check_output(['git', 'ls-remote', '-q', '.',
116122
'refs/remotes/origin/%s' % config['git_version']])
117-
except subprocess.CalledProcessError, C:
123+
except subprocess.CalledProcessError as C:
118124
notify_error('setup', C.output)
119-
return r.split()[0]
125+
return r.decode().split()[0]
120126

121127

122128
def get_last_commit_submodule(checkout_dir, submodule):
123129
os.chdir("{}/{}/".format(checkout_dir, submodule))
124130
try:
125131
r = subprocess.check_output(['git', 'ls-remote', '-q', '.',
126132
'refs/remotes/origin/HEAD'])
127-
except subprocess.CalledProcessError, C:
133+
except subprocess.CalledProcessError as C:
128134
notify_error('setup', C.output)
129-
return r.split()[0]
135+
return r.decode().split()[0]
130136

131137

132138
def get_submodules_checkout(checkout_dir):
133139
os.chdir(checkout_dir)
134140
result = []
135141
try:
136142
submodule_status = subprocess.check_output(['git', 'submodule', 'status'])
137-
except subprocess.CalledProcessError, C:
143+
except subprocess.CalledProcessError as C:
138144
notify_error('setup', C.output)
139-
for s in submodule_status.split('\n'):
145+
for s in submodule_status.decode().split('\n'):
140146
# there is a empty line at the end...
141147
if s:
142148
result.append(s.split()[1])
@@ -145,10 +151,10 @@ def get_submodules_checkout(checkout_dir):
145151

146152
def load_config(config_file):
147153
if not os.path.exists(config_file):
148-
print "Error %s, do not exist" % config_file
154+
print("Error %s, do not exist" % config_file)
149155
sys.exit(1)
150156
if not os.path.isfile(config_file):
151-
print "Error %s is not a file" % config_file
157+
print("Error %s is not a file" % config_file)
152158
sys.exit(1)
153159

154160
with open(config_file) as f:
@@ -161,14 +167,14 @@ def has_submodules(checkout_dir):
161167
os.chdir(checkout_dir)
162168
try:
163169
r = subprocess.check_output(['git', 'submodule', 'status'])
164-
except subprocess.CalledProcessError, C:
170+
except subprocess.CalledProcessError as C:
165171
notify_error('setup', C.output)
166-
return len(r) > 0
172+
return len(r.decode()) > 0
167173

168174

169175
# TODO complete that
170176
def notify_error(stage, error):
171-
print error
177+
print(error)
172178
sys.exit(3)
173179

174180

@@ -189,20 +195,20 @@ def do_rsync(source):
189195
'--omit-dir-times',
190196
source,
191197
config['remote']], stderr=subprocess.STDOUT)
192-
except subprocess.CalledProcessError, C:
198+
except subprocess.CalledProcessError as C:
193199
notify_error('setup', C.output)
194-
return r
200+
return r.decode()
195201

196202

197203

198204
if not args.config_file:
199-
print "This script take only 1 single argument, the config file"
205+
print("This script take only 1 single argument, the config file")
200206
sys.exit(1)
201207

202208
config = load_config(args.config_file)
203209

204210
if 'name' not in config:
205-
print "Incorrect config file: {}".format(args.config_file)
211+
print("Incorrect config file: {}".format(args.config_file))
206212
sys.exit(1)
207213

208214
name = config['name']
@@ -216,7 +222,7 @@ def do_rsync(source):
216222

217223
# TODO try/except, show a better error message
218224
fd = os.open(lock_file, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
219-
os.write(fd, str(os.getpid()))
225+
os.write(fd, str(os.getpid()).encode())
220226
os.close(fd)
221227
atexit.register(os.unlink, lock_file)
222228

@@ -229,7 +235,7 @@ def do_rsync(source):
229235
checkout_dir = os.path.expanduser("~/%s" % name)
230236
if not os.path.isdir(checkout_dir):
231237
os.unlink(lock_file)
232-
print "Checkout not existing, exiting"
238+
print("Checkout not existing, exiting")
233239
sys.exit(2)
234240

235241
refresh_checkout(checkout_dir)
@@ -286,21 +292,21 @@ def do_rsync(source):
286292
if not args.no_refresh:
287293
try:
288294
result = subprocess.check_output(['git', 'stash'], stderr=subprocess.STDOUT)
289-
debug_print(result)
295+
debug_print(result.decode())
290296
result = subprocess.check_output(['git', 'stash', 'clear'], stderr=subprocess.STDOUT)
291-
debug_print(result)
297+
debug_print(result.decode())
292298
result = subprocess.check_output(['git', 'pull', '--rebase'], stderr=subprocess.STDOUT)
293-
debug_print(result)
294-
except subprocess.CalledProcessError, C:
299+
debug_print(result.decode())
300+
except subprocess.CalledProcessError as C:
295301
notify_error('setup', C.output)
296302

297303
if has_submodules(checkout_dir):
298304
try:
299305
result = subprocess.check_output(['git', 'submodule', 'init'], stderr=subprocess.STDOUT)
300-
debug_print(result)
306+
debug_print(result.decode())
301307
result = subprocess.check_output(['git', 'submodule', 'sync'], stderr=subprocess.STDOUT)
302-
debug_print(result)
303-
except subprocess.CalledProcessError, C:
308+
debug_print(result.decode())
309+
except subprocess.CalledProcessError as C:
304310
notify_error('setup', C.output)
305311

306312
build_subdir = builder_info[config['builder']]['build_subdir']
@@ -309,7 +315,7 @@ def do_rsync(source):
309315
# ensure build directory exist or creating the sync log would fail
310316
try:
311317
# TODO: use exist_ok instead of all this crap when switching to Python 3
312-
os.makedirs(build_dir, mode=0775)
318+
os.makedirs(build_dir, mode=0o775)
313319
except OSError as exc:
314320
if exc.errno == errno.EEXIST and os.path.isdir(build_dir):
315321
pass
@@ -329,15 +335,15 @@ def do_rsync(source):
329335
# don't use embedded libraries to build Nokogiri
330336
os.environ['NOKOGIRI_USE_SYSTEM_LIBRARIES'] = '1'
331337
result = subprocess.check_output(['bundle', 'install'], stderr=subprocess.STDOUT)
332-
debug_print(result)
333-
except subprocess.CalledProcessError, C:
338+
debug_print(result.decode())
339+
except subprocess.CalledProcessError as C:
334340
log_print(C.output)
335341
if config['remote']:
336342
# copy log in build dir and sync it to make it available to users
337343
shutil.copy2(log_file, sync_log_path)
338344
try:
339345
do_rsync(sync_log_path)
340-
except subprocess.CalledProcessError, C:
346+
except subprocess.CalledProcessError:
341347
pass
342348
notify_error('install', C.output)
343349

@@ -349,15 +355,15 @@ def do_rsync(source):
349355
command = builder_info[config['builder']]['build_command']
350356
syslog.syslog("Build of {}: {}".format(name, ' '.join(command)))
351357
result = subprocess.check_output(command, stderr=subprocess.STDOUT)
352-
debug_print(result)
353-
except subprocess.CalledProcessError, C:
358+
debug_print(result.decode())
359+
except subprocess.CalledProcessError as C:
354360
log_print(C.output)
355361
if config['remote']:
356362
# copy log in build dir and sync it to make it available to users
357363
shutil.copy2(log_file, sync_log_path)
358364
try:
359365
do_rsync(sync_log_path)
360-
except subprocess.CalledProcessError, C:
366+
except subprocess.CalledProcessError:
361367
pass
362368
notify_error('build', C.output)
363369

@@ -372,11 +378,11 @@ def do_rsync(source):
372378
else:
373379
command = builder_info[config['builder']]['deploy_command']
374380
if command:
375-
result = subprocess.check_output(command)
381+
result = subprocess.check_output(command).decode()
376382
else:
377383
result = "No deployment done: no Rsync settings provided and this builder has no reployment method defined"
378384
debug_print(result)
379-
except subprocess.CalledProcessError, C:
385+
except subprocess.CalledProcessError as C:
380386
notify_error('deploy', C.output)
381387
syslog.syslog("Build of {}: finish sync".format(name))
382388
else:
@@ -389,4 +395,4 @@ def do_rsync(source):
389395
status['submodule_commits'] = current_submodule_commits
390396

391397
with open(status_file, 'w+') as f:
392-
f.write(yaml.dump(status, default_flow_style=False))
398+
f.write(yaml.safe_dump(status, default_flow_style=False))

vars/Debian.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ package_list:
2727
ascii_binder: []
2828
planet:
2929
- planet-venus
30+
nikola:
31+
- python3-pip
3032

0 commit comments

Comments
 (0)