Skip to content

Commit f6ff7d8

Browse files
authored
Merge pull request #11 from ggatward/chunked-publish
Add batched publish/promotion option
2 parents 5193aa6 + f5f3617 commit f6ff7d8

7 files changed

Lines changed: 128 additions & 80 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
44
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
55

66
## [Unreleased]
7+
### Added
8+
- Allow limiting of Publish and Promotion to specified number of CV's at once.
9+
710

811
## [1.1.0] - 2017-10-23
912
### Added

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,12 @@ optional arguments:
185185
-s SINCE, --since SINCE
186186
Export content since YYYY-MM-DD HH:MM:SS
187187
-l, --last Display time of last export
188-
-n, --nogpg Skip GPG checking
188+
-L, --list List all successfully completed exports
189+
--nogpg Skip GPG checking
189190
-r, --repodata Include repodata for repos with no incremental content
190191
-p, --puppetforge Include puppet-forge-server format Puppet Forge repo
192+
--notar Do not archive the extracted content
193+
--forcexport Force export from an import-only (Disconnected) Satellite
191194
192195
```
193196

@@ -367,12 +370,17 @@ the WebUI or Hammer CLI.
367370
The defaults are configured in the main config.yml file in a YAML block like this:
368371
```
369372
publish:
373+
batch: 10
370374
content_views:
371375
- RHEL Server
372376
- RHEL Workstation
373377
```
374378
This configuration will publish only the two listed content views.
375379

380+
The batch: parameter can be used to limit the number of content views that will be published at
381+
once, to aid in performance tuning.
382+
383+
376384

377385
```
378386
usage: publish_content_view.py [-h] [-o ORG] [-a] [-d]
@@ -416,13 +424,14 @@ the WebUI or Hammer CLI.
416424
The defaults are configured in the main config.yml file in a YAML block like this:
417425
```
418426
promotion:
427+
batch: 10
419428
lifecycle1:
420429
name: Quality
421430
content_views:
422431
- RHEL Server
423432
- RHEL Workstation
424433
425-
lifecyclec2:
434+
lifecycle2:
426435
name: Desktop QA
427436
content_views:
428437
- RHEL Workstation
@@ -432,6 +441,9 @@ use of the config.yml definition is strongly recommended to avoid views being
432441
promoted into the wrong lifecycle stream. This is more likely to be an
433442
issue promoting views from the Library, as this is shared by all environments.
434443

444+
The batch: parameter can be used to limit the number of content views that will be promoted at
445+
once, to aid in performance tuning.
446+
435447
```
436448
usage: promote_content_view.py [-h] -e ENV [-o ORG] [-a] [-d]
437449

config/config.yml.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ import:
1919
syncbatch: 50
2020

2121
publish:
22+
batch: 10
2223
content_views:
2324
- RHEL Server
2425
- RHEL Workstation
2526

2627
promotion:
28+
batch: 10
2729
lifecycle1:
2830
name: Quality
2931
content_views:

helpers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@
5151
SYNCBATCH = CONFIG['import']['syncbatch']
5252
else:
5353
SYNCBATCH = 255
54+
if 'batch' in CONFIG['publish']:
55+
PUBLISHBATCH = CONFIG['publish']['batch']
56+
else:
57+
PUBLISHBATCH = 255
58+
if 'batch' in CONFIG['promotion']:
59+
PROMOTEBATCH = CONFIG['promotion']['batch']
60+
else:
61+
PROMOTEBATCH = 255
5462
if 'hostname' in CONFIG['puppet-forge-server']:
5563
PFSERVER = CONFIG['puppet-forge-server']['hostname']
5664

man/sat6_scripts.8

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ This determines whether this satellite can export or import content.
6969
.B " proxy: proxy.example.com:8080"
7070
.RS
7171
Definition of HTTP proxy to use in support of the
72-
.I download_manifest
73-
script.
72+
.I download_manifest
73+
script.
7474
.br
7575
If no proxy is required this parameter can be omitted from the config file completely.
7676
.RE
@@ -102,13 +102,18 @@ Directory to export content to, used by
102102
.B import:
103103
.br
104104
.B " dir: /var/sat-content"
105+
.br
106+
.B " syncbatch: 10"
105107
.RS
106108
Directory to read import content from, used by
107109
.IR sat_import .
110+
The syncbatch: parameter defines the maximum number of repositories to sync at once, for performance tuning.
108111
.RE
109112

110113
.B publish:
111114
.br
115+
.B " batch: 10"
116+
.br
112117
.B " content_views:"
113118
.br
114119
.B " - RHEL Server"
@@ -117,14 +122,18 @@ Directory to read import content from, used by
117122
.RS
118123
List of content views to publish, one per line. Used by
119124
.IR publish_content_views .
125+
The batch: keyword specifies the maximum number of content views to publish in a batch, for performance tuning.
120126
.RE
121127

122128
.B promotion:
123129
.br
130+
.B " batch: 10"
131+
.br
124132
.B " lifecycle1:"
125133
.RS
126134
Lifecycle environment definition. There can be multiple lifecycles defined, however
127135
the names must be unique. Increment the number for each defined environment.
136+
The batch: keyword specifies the maximum number of content views to promote in a batch, for performance tuning.
128137
.RE
129138

130139
.B " name: Quality"

promote_content_views.py

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def get_cv(org_id, target_env, env_list, prior_list, promote_list):
109109

110110

111111
# Promote a content view version
112-
def promote(target_env, ver_list, ver_descr, ver_version, env_list, prior_list, dry_run):
112+
def promote(target_env, ver_list, ver_descr, ver_version, env_list, prior_list, dry_run, quiet):
113113
"""Promote Content View"""
114114
target_env_id = env_list[target_env]
115115
source_env_id = prior_list[target_env_id]
@@ -133,41 +133,51 @@ def promote(target_env, ver_list, ver_descr, ver_version, env_list, prior_list,
133133
helpers.log_msg(msg, 'WARNING')
134134
sys.exit(1)
135135

136-
for cvid in ver_list.keys():
137-
138-
# Check if there is a publish/promote already running on this content view
139-
locked = helpers.check_running_publish(cvid, ver_descr[cvid])
140-
141-
if not locked:
142-
msg = "Promoting '" + str(ver_descr[cvid]) + "' Version " + str(ver_version[cvid]) +\
143-
" from " + prior_env + " to " + str(target_env)
144-
helpers.log_msg(msg, 'INFO')
145-
print helpers.HEADER + msg + helpers.ENDC
146-
147-
if not dry_run and not locked:
148-
try:
149-
task_id = helpers.post_json(
150-
helpers.KATELLO_API + "content_view_versions/" + str(ver_list[cvid]) +\
151-
"/promote/", json.dumps(
152-
{
153-
"environment_id": target_env_id
154-
}
155-
))["id"]
156-
except Warning:
157-
msg = "Failed to initiate promotion of " + str(ver_descr[cvid])
158-
helpers.log_msg(msg, 'WARNING')
159-
else:
160-
task_list.append(task_id)
161-
ref_list[task_id] = ver_descr[cvid]
136+
# Break repos to promote into batches as configured in config.yml
137+
cvchunks = [ ver_list.keys()[i:i+helpers.PROMOTEBATCH] for i in range(0, len(ver_list), helpers.PROMOTEBATCH) ]
138+
139+
# Loop through the smaller subsets of repo id's
140+
for chunk in cvchunks:
141+
for cvid in chunk:
142+
143+
# Check if there is a publish/promote already running on this content view
144+
locked = helpers.check_running_publish(cvid, ver_descr[cvid])
145+
146+
if not locked:
147+
msg = "Promoting '" + str(ver_descr[cvid]) + "' Version " + str(ver_version[cvid]) +\
148+
" from " + prior_env + " to " + str(target_env)
149+
helpers.log_msg(msg, 'INFO')
150+
print helpers.HEADER + msg + helpers.ENDC
151+
152+
if not dry_run and not locked:
153+
try:
154+
task_id = helpers.post_json(
155+
helpers.KATELLO_API + "content_view_versions/" + str(ver_list[cvid]) +\
156+
"/promote/", json.dumps(
157+
{
158+
"environment_id": target_env_id
159+
}
160+
))["id"]
161+
except Warning:
162+
msg = "Failed to initiate promotion of " + str(ver_descr[cvid])
163+
helpers.log_msg(msg, 'WARNING')
164+
else:
165+
task_list.append(task_id)
166+
ref_list[task_id] = ver_descr[cvid]
167+
168+
# Exit in the case of a dry-run
169+
if dry_run:
170+
msg = "Dry run - not actually performing promotion"
171+
helpers.log_msg(msg, 'WARNING')
172+
else:
173+
# Monitor the status of the promotion tasks
174+
helpers.watch_tasks(task_list, ref_list, task_name, quiet)
162175

163176
# Exit in the case of a dry-run
164177
if dry_run:
165-
msg = "Dry run - not actually performing promotion"
166-
helpers.log_msg(msg, 'WARNING')
167178
sys.exit(2)
168-
169-
170-
return task_list, ref_list, task_name
179+
else:
180+
return
171181

172182

173183
def main(args):
@@ -183,7 +193,6 @@ def main(args):
183193
global vardir
184194
dir = os.path.dirname(__file__)
185195
vardir = os.path.join(dir, 'var')
186-
# confdir = os.path.join(dir, 'config')
187196

188197
# Check for sane input
189198
parser = argparse.ArgumentParser(
@@ -242,6 +251,8 @@ def main(args):
242251
promote_list = []
243252
if not args.all:
244253
for x in helpers.CONFIG['promotion']:
254+
if x == 'batch':
255+
continue
245256
if helpers.CONFIG['promotion'][x]['name'] == target_env:
246257
promote_list = helpers.CONFIG['promotion'][x]['content_views']
247258

@@ -264,16 +275,12 @@ def main(args):
264275
promote_list)
265276

266277
# Promote to the given environment. Returns a list of task IDs.
267-
(task_list, ref_list, task_name) = promote(target_env, ver_list, ver_descr, ver_version,
268-
env_list, prior_list, dry_run)
278+
promote(target_env, ver_list, ver_descr, ver_version, env_list, prior_list, dry_run, args.quiet)
269279

270280
# Add/Update the promotion history dictionary so we can check when we last promoted
271281
phistory[target_env] = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d')
272282
pickle.dump(phistory, open(vardir + '/promotions.pkl', 'wb'))
273283

274-
# Monitor the status of the promotion tasks
275-
helpers.watch_tasks(task_list, ref_list, task_name, args.quiet)
276-
277284
# Exit cleanly
278285
sys.exit(0)
279286

publish_content_views.py

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def get_cv(org_id, publish_list):
5353
return ver_list, ver_descr, ver_version
5454

5555

56-
def publish(ver_list, ver_descr, ver_version, dry_run, runuser):
56+
def publish(ver_list, ver_descr, ver_version, dry_run, runuser, quiet):
5757
"""Publish Content View"""
5858

5959
# Set the task name to be displayed in the task monitoring stage
@@ -69,43 +69,53 @@ def publish(ver_list, ver_descr, ver_version, dry_run, runuser):
6969
helpers.log_msg(msg, 'ERROR')
7070
sys.exit(1)
7171

72-
for cvid in ver_list.keys():
73-
74-
# Check if there is a publish/promote already running on this content view
75-
locked = helpers.check_running_publish(ver_list[cvid], ver_descr[cvid])
76-
77-
if not locked:
78-
msg = "Publishing '" + str(ver_descr[cvid]) + "' Version " + str(ver_version[cvid]) + ".0"
79-
helpers.log_msg(msg, 'INFO')
80-
print helpers.HEADER + msg + helpers.ENDC
81-
82-
# Set up the description that will be added to the published version
83-
description = "Published by " + runuser + "\n via API script"
84-
85-
if not dry_run and not locked:
86-
try:
87-
task_id = helpers.post_json(
88-
helpers.KATELLO_API + "content_views/" + str(ver_list[cvid]) +\
89-
"/publish", json.dumps(
90-
{
91-
"description": description
92-
}
93-
))["id"]
94-
except Warning:
95-
msg = "Failed to initiate publication of " + str(ver_descr[cvid])
96-
helpers.log_msg(msg, 'WARNING')
97-
else:
98-
task_list.append(task_id)
99-
ref_list[task_id] = ver_descr[cvid]
72+
# Break repos to publish into batches as configured in config.yml
73+
cvchunks = [ ver_list.keys()[i:i+helpers.PUBLISHBATCH] for i in range(0, len(ver_list), helpers.PUBLISHBATCH) ]
74+
75+
# Loop through the smaller subsets of repo id's
76+
for chunk in cvchunks:
77+
for cvid in chunk:
78+
79+
# Check if there is a publish/promote already running on this content view
80+
locked = helpers.check_running_publish(ver_list[cvid], ver_descr[cvid])
81+
82+
if not locked:
83+
msg = "Publishing '" + str(ver_descr[cvid]) + "' Version " + str(ver_version[cvid]) + ".0"
84+
helpers.log_msg(msg, 'INFO')
85+
print helpers.HEADER + msg + helpers.ENDC
86+
87+
# Set up the description that will be added to the published version
88+
description = "Published by " + runuser + "\n via API script"
89+
90+
if not dry_run and not locked:
91+
try:
92+
task_id = helpers.post_json(
93+
helpers.KATELLO_API + "content_views/" + str(ver_list[cvid]) +\
94+
"/publish", json.dumps(
95+
{
96+
"description": description
97+
}
98+
))["id"]
99+
except Warning:
100+
msg = "Failed to initiate publication of " + str(ver_descr[cvid])
101+
helpers.log_msg(msg, 'WARNING')
102+
else:
103+
task_list.append(task_id)
104+
ref_list[task_id] = ver_descr[cvid]
105+
106+
# Notify user in the case of a dry-run
107+
if dry_run:
108+
msg = "Dry run - not actually performing publish"
109+
helpers.log_msg(msg, 'WARNING')
110+
else:
111+
# Wait for the tasks to finish
112+
helpers.watch_tasks(task_list, ref_list, task_name, quiet)
100113

101114
# Exit in the case of a dry-run
102115
if dry_run:
103-
msg = "Dry run - not actually performing publish"
104-
helpers.log_msg(msg, 'WARNING')
105116
sys.exit(2)
106-
107-
108-
return task_list, ref_list, task_name
117+
else:
118+
return
109119

110120

111121
def main(args):
@@ -191,15 +201,12 @@ def main(args):
191201
(ver_list, ver_descr, ver_version) = get_cv(org_id, publish_list)
192202

193203
# Publish the content views. Returns a list of task IDs.
194-
(task_list, ref_list, task_name) = publish(ver_list, ver_descr, ver_version, dry_run, runuser)
204+
publish(ver_list, ver_descr, ver_version, dry_run, runuser, args.quiet)
195205

196206
# Add/Update the promotion history dictionary so we can check when we last promoted
197207
phistory['Library'] = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d')
198208
pickle.dump(phistory, open(vardir + '/promotions.pkl', 'wb'))
199209

200-
# Monitor the status of the publish tasks
201-
helpers.watch_tasks(task_list, ref_list, task_name, args.quiet)
202-
203210
# Exit cleanly
204211
sys.exit(0)
205212

0 commit comments

Comments
 (0)