Initial commit
[ta/rpmbuilder.git] / rpmbuilder / mockbuilder.py
1 # Copyright 2019 Nokia
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """ Handling of mock building environment """
16 import json
17 import logging
18 import os
19
20 from rpmbuilder.baseerror import RpmbuilderError
21 from rpmbuilder.version_control import VersionControlSystem
22
23
24 class Mockbuilder(object):
25
26     """ Mockbuilder handled mock building configuration """
27
28     def __init__(self):
29         self.logger = logging.getLogger(__name__)
30         self.roots = []
31
32
33 class LocalMockbuilder(Mockbuilder):
34
35     """ Mock configuration contains information of chroot used for building.
36     Configuration is taken from local file"""
37
38     def __init__(self, configfile):
39         super(LocalMockbuilder, self).__init__()
40
41         self.roots.append(os.path.basename(configfile.rstrip('/').rstrip('.cfg')))
42         self.configdir = os.path.dirname(os.path.abspath(configfile))
43
44     def get_configdir(self):
45         return self.configdir
46
47     def store_builder_status(self):
48         pass
49
50
51 class GitMockbuilder(Mockbuilder):
52
53     """ Mock configuration contains information of chroot used for building.
54     Configuration is taken from git"""
55
56     def __init__(self, workspace, conf):
57         super(GitMockbuilder, self).__init__()
58
59         self.mock_settings_dir = os.path.join(workspace, "mocksettings")
60         self.mock_settings_checkout_dir = os.path.join(self.mock_settings_dir,
61                                                        "checkout")
62
63         confsection = "mock"
64         self.roots = self.__list_from_csv(conf.get_string(confsection,
65                                                           "roots",
66                                                           mandatory=True))
67
68         self.vcs = VersionControlSystem(self.mock_settings_checkout_dir)
69
70         try:
71             self.vcs.update_git_project(conf.get_string(confsection,
72                                                         "url",
73                                                         mandatory=True),
74                                         conf.get_string(confsection,
75                                                         "ref",
76                                                         mandatory=True))
77         except:
78             self.logger.critical("Problems updating git clone")
79             raise
80
81     def get_configdir(self):
82         return os.path.join(self.mock_settings_checkout_dir, 'etc', 'mock')
83
84     def store_builder_status(self):
85         """ Save information of the builder checkout. This way we can
86         check if mock configuration has changed and all projects can be
87         rebuild """
88         statusfile = os.path.join(self.mock_settings_dir, 'status.txt')
89         self.logger.debug("Updating %s", statusfile)
90         projectstatus = {"sha": self.vcs.commitsha}
91         try:
92             with open(statusfile, 'w') as outfile:
93                 json.dump(projectstatus, outfile)
94         except:
95             self.logger.error("Could not create a status file")
96             raise
97
98     def check_builder_changed(self):
99         """
100         Check if there has been changes in the project
101         if project has not been compiled -> return = True
102         if project has GIT/VCS changes   -> return = True
103         if project has not changed       -> return = False
104         """
105         statusfile = os.path.join(self.mock_settings_dir, 'status.txt')
106
107         if os.path.isfile(statusfile):
108             with open(statusfile, 'r') as filep:
109                 previousprojectstatus = json.load(filep)
110             # Compare old values against new values
111             if previousprojectstatus['sha'] != self.vcs.commitsha:
112                 self.logger.debug("Mock configuration has changed")
113                 return True
114             else:
115                 self.logger.debug("Mock configuration has NO changes")
116             return False
117         else:
118             # No configuration means that project has not been compiled
119             pass
120         return True
121
122     @staticmethod
123     def __list_from_csv(csv):
124         """ Create a list of comma separated value list
125         For example foo,bar would be converted to ["foo","bar"] """
126         outlist = []
127         for entry in set(csv.split(',')):
128             outlist.append(entry.strip())
129         return outlist
130
131
132 class MockbuilderError(RpmbuilderError):
133
134     """ Exceptions originating from Builder and main level """
135     pass