1 import json
2 import os.path
3 import shutil
4 import time
5
6 from bunch import Bunch
7
8 from .createrepo import createrepo, createrepo_unsafe
9
10
12 """ Object to send data back to fronted
13
14 :param multiprocessing.Queue events: collects events for logging
15 :param multiprocessing.Lock lock: Global lock for backend
16 :param backend.callback.FrontendCallback frontent_callback:
17 object to post data back to frontend
18
19 :param destdir: filepath with build results
20
21 :param dict action: dict-like object with action task
22
23 Expected **action** keys:
24
25 - action_type: main field determining what action to apply
26 # TODO: describe actions
27
28 """
29
30 - def __init__(self, events, action, lock,
31 frontend_callback, destdir,
32 front_url, results_root_url):
33 super(Action, self).__init__()
34 self.frontend_callback = frontend_callback
35 self.destdir = destdir
36 self.data = action
37 self.events = events
38 self.lock = lock
39 self.front_url = front_url
40 self.results_root_url = results_root_url
41
43 return "<Action: {}>".format(self.data)
44
46 self.events.put({"when": time.time(), "who": "action", "what": what})
47
49 self.add_event("Action legal-flag: ignoring")
50
52 self.add_event("Action create repo")
53 data = json.loads(self.data["data"])
54 username = data["username"]
55 projectname = data["projectname"]
56 chroots = data["chroots"]
57
58 failure = False
59 for chroot in chroots:
60 self.add_event("Creating repo for: {}/{}/{}".format(username, projectname, chroot))
61
62 path = os.path.join(self.destdir, username, projectname, chroot)
63
64 errcode, _, err = createrepo_unsafe(path=path, lock=self.lock)
65 if errcode != 0 or err.strip():
66 self.add_event("Error making local repo: {0}".format(err))
67 failure = True
68
69 if failure:
70 result.result = ActionResult.FAILURE
71 else:
72 result.result = ActionResult.SUCCESS
73
75 self.add_event("Action rename")
76 old_path = os.path.normpath(os.path.join(
77 self.destdir, self.data["old_value"]))
78 new_path = os.path.normpath(os.path.join(
79 self.destdir, self.data["new_value"]))
80
81 if os.path.exists(old_path):
82 if not os.path.exists(new_path):
83 shutil.move(old_path, new_path)
84 result.result = ActionResult.SUCCESS
85 else:
86 result.message = "Destination directory already exist."
87 result.result = ActionResult.FAILURE
88 else:
89 result.result = ActionResult.SUCCESS
90 result.job_ended_on = time.time()
91
93 self.add_event("Action delete copr")
94 project = self.data["old_value"]
95 path = os.path.normpath(self.destdir + '/' + project)
96 if os.path.exists(path):
97 self.add_event("Removing copr {0}".format(path))
98 shutil.rmtree(path)
99
101 self.add_event("Action delete build")
102 project = self.data["old_value"]
103
104 ext_data = json.loads(self.data["data"])
105 username = ext_data["username"]
106 projectname = ext_data["projectname"]
107 chroots_requested = set(ext_data["chroots"])
108
109 package_name = os.path.basename(ext_data["pkgs"]).replace(".src.rpm", "")
110
111 if not package_name:
112 self.add_event("Bad package name {}, action data: {} ".format(package_name, ext_data))
113 return
114
115 path = os.path.join(self.destdir, project)
116
117 self.add_event("Deleting package {0}".format(package_name))
118 self.add_event("Copr path {0}".format(path))
119
120 try:
121 chroot_list = set(os.listdir(path))
122 except OSError:
123
124 chroot_list = set()
125
126 chroots_to_do = chroot_list.intersection(chroots_requested)
127 if not chroots_to_do:
128 self.add_event("Nothing to delete for delete action: package {}, {}"
129 .format(package_name, ext_data))
130 return
131
132 for chroot in chroots_to_do:
133 self.add_event("In chroot {0}".format(chroot))
134 altered = False
135
136 pkg_path = os.path.join(path, chroot, package_name)
137 if os.path.isdir(pkg_path):
138 self.add_event("Removing build {0}".format(pkg_path))
139 shutil.rmtree(pkg_path)
140 altered = True
141 else:
142 self.add_event("Package {0} dir not found in chroot {1}".format(package_name, chroot))
143
144 if altered:
145 self.add_event("Running createrepo")
146
147 result_base_url = "/".join(
148 [self.results_root_url, username, projectname, chroot])
149 _, _, err = createrepo(
150 path=os.path.join(path, chroot), lock=self.lock,
151 front_url=self.front_url, base_url=result_base_url,
152 username=username, projectname=projectname
153 )
154 if err.strip():
155 self.add_event(
156 "Error making local repo: {0}".format(err))
157
158 logs_to_remove = [
159 os.path.join(path, chroot, template.format(self.data['object_id']))
160 for template in ['build-{}.log', 'build-{}.rsync.log']
161 ]
162 for log_path in logs_to_remove:
163 if os.path.isfile(log_path):
164 self.add_event("Removing log {0}".format(log_path))
165 os.remove(log_path)
166
197
198
204
205
210