-
Notifications
You must be signed in to change notification settings - Fork 165
/
cmd-tag
executable file
·145 lines (113 loc) · 4.34 KB
/
cmd-tag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python3
# NOTE: PYTHONUNBUFFERED is set in the entrypoint for unbuffered output
#
# Allows users to operate on the tags in `builds.json`
#
# Examples:
#
# $ coreos-assembler tag update --tag smoketested --build 47.152
# $ coreos-assembler tag delete --tag beta
# $ coreos-assembler tag list
#
import argparse
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from cosalib.builds import Builds
from cosalib.cmdlib import fatal, rfc3339_time
def main():
"""Main entry point"""
args = parse_args()
args.func(args)
def parse_args():
"""Parse args and dispatch"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="cmd", title="Tag actions")
subparsers.required = True
delete = subparsers.add_parser("delete",
help="Delete a tag from the metadata")
delete.add_argument("--tag", help="Tag to delete from metadata")
delete.add_argument("--all", help="Delete all tags",
action="store_true")
delete.set_defaults(func=cmd_delete)
list_tags = subparsers.add_parser("list", help="List available tags in "
"the metadata")
list_tags.set_defaults(func=cmd_list)
update = subparsers.add_parser("update", help="Update existing tag or "
"create a new tag")
update.add_argument("--tag", help="Tag to be updated", required=True)
update.add_argument("--description", help="Message to associate with tag")
update.add_argument("--build", help="Build to update tag with")
update.add_argument("--force", help="Force the update of a tag",
action="store_true")
update.set_defaults(func=cmd_update)
return parser.parse_args()
def available_tags(build_data):
"""Returns the available tag names from build metadata"""
return [t.get("name") for t in build_data.get("tags", {})]
def cmd_list(args):
"""List available tags in build metadata"""
builds = Builds()
build_data = builds.raw()
avail_tags = available_tags(build_data)
if not avail_tags:
print("No tags found")
return
for tag in build_data["tags"]:
print(f"name: {tag['name']}\n"
f"created: {tag['created']}\n"
f"target: {tag['target']}\n", end='')
if 'description' in tag:
print(f"description:\n\t{tag['description']}\n", end='')
print()
def cmd_update(args):
"""Create or update a tag to new build ID"""
builds = Builds()
if args.build is None:
args.build = builds.get_latest()
build_data = builds.raw()
avail_tags = available_tags(build_data)
if "tags" not in build_data:
build_data["tags"] = []
# if the build doesn't exist, check for the force flag and bail out
# if it is not used.
if not builds.has(args.build):
if not args.force:
fatal("Cannot operate on a tag with a build that does not exist")
print(f"INFO: Operating on a tag ({args.tag}) with a build "
f"({args.build}) that does not exist")
# we've got a build (either forced or not), so time to make/update a tag
created = rfc3339_time()
new_tag = {
"name": args.tag,
"created": created,
"target": args.build,
}
if args.description:
new_tag['description'] = args.description
if args.tag not in avail_tags:
build_data["tags"].append(new_tag)
else:
build_data["tags"] = [new_tag if t.get("name") == args.tag
else t for t in build_data["tags"]]
builds.flush()
def cmd_delete(args):
"""Delete a tag from build metadata"""
# To delete a tag, iterate through existing tags list, and
# drop the entry we want
builds = Builds()
build_data = builds.raw()
if args.all:
if "tags" in build_data:
del build_data["tags"]
elif args.tag:
avail_tags = available_tags(build_data)
if args.tag not in avail_tags:
fatal("Cannot delete a tag that does not exist")
build_data["tags"] = [t for t in build_data["tags"]
if t["name"] != args.tag]
else:
fatal("Either --tag or --all required")
builds.flush()
if __name__ == "__main__":
sys.exit(main())