blob: 1a9c863769e247b216f28eb2d7f3dbee97c8d920 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001"""
2BitBake 'Fetch' clearcase implementation
3
4The clearcase fetcher is used to retrieve files from a ClearCase repository.
5
6Usage in the recipe:
7
8 SRC_URI = "ccrc://cc.example.org/ccrc;vob=/example_vob;module=/example_module"
9 SRCREV = "EXAMPLE_CLEARCASE_TAG"
10 PV = "${@d.getVar("SRCREV", False).replace("/", "+")}"
11
12The fetcher uses the rcleartool or cleartool remote client, depending on which one is available.
13
14Supported SRC_URI options are:
15
16- vob
17 (required) The name of the clearcase VOB (with prepending "/")
18
19- module
20 The module in the selected VOB (with prepending "/")
21
22 The module and vob parameters are combined to create
23 the following load rule in the view config spec:
24 load <vob><module>
25
26- proto
27 http or https
28
29Related variables:
30
31 CCASE_CUSTOM_CONFIG_SPEC
32 Write a config spec to this variable in your recipe to use it instead
33 of the default config spec generated by this fetcher.
34 Please note that the SRCREV loses its functionality if you specify
35 this variable. SRCREV is still used to label the archive after a fetch,
36 but it doesn't define what's fetched.
37
38User credentials:
39 cleartool:
40 The login of cleartool is handled by the system. No special steps needed.
41
42 rcleartool:
43 In order to use rcleartool with authenticated users an `rcleartool login` is
44 necessary before using the fetcher.
45"""
46# Copyright (C) 2014 Siemens AG
47#
Brad Bishopc342db32019-05-15 21:57:59 -040048# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050049#
50
51import os
Patrick Williamsc124f4f2015-09-15 14:41:29 -050052import shutil
53import bb
Patrick Williamsc124f4f2015-09-15 14:41:29 -050054from bb.fetch2 import FetchMethod
55from bb.fetch2 import FetchError
Brad Bishop96ff1982019-08-19 13:50:42 -040056from bb.fetch2 import MissingParameterError
57from bb.fetch2 import ParameterError
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058from bb.fetch2 import runfetchcmd
59from bb.fetch2 import logger
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060
61class ClearCase(FetchMethod):
62 """Class to fetch urls via 'clearcase'"""
63 def init(self, d):
64 pass
65
66 def supports(self, ud, d):
67 """
68 Check to see if a given url can be fetched with Clearcase.
69 """
70 return ud.type in ['ccrc']
71
72 def debug(self, msg):
Andrew Geisslerd1e89492021-02-12 15:35:20 -060073 logger.debug("ClearCase: %s", msg)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050074
75 def urldata_init(self, ud, d):
76 """
77 init ClearCase specific variable within url data
78 """
79 ud.proto = "https"
80 if 'protocol' in ud.parm:
81 ud.proto = ud.parm['protocol']
82 if not ud.proto in ('http', 'https'):
Brad Bishop96ff1982019-08-19 13:50:42 -040083 raise ParameterError("Invalid protocol type", ud.url)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050084
85 ud.vob = ''
86 if 'vob' in ud.parm:
87 ud.vob = ud.parm['vob']
88 else:
89 msg = ud.url+": vob must be defined so the fetcher knows what to get."
90 raise MissingParameterError('vob', msg)
91
92 if 'module' in ud.parm:
93 ud.module = ud.parm['module']
94 else:
95 ud.module = ""
96
Brad Bishopd5ae7d92018-06-14 09:52:03 -070097 ud.basecmd = d.getVar("FETCHCMD_ccrc") or "/usr/bin/env cleartool || rcleartool"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050098
Brad Bishop6e60e8b2018-02-01 10:27:11 -050099 if d.getVar("SRCREV") == "INVALID":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100 raise FetchError("Set a valid SRCREV for the clearcase fetcher in your recipe, e.g. SRCREV = \"/main/LATEST\" or any other label of your choice.")
101
102 ud.label = d.getVar("SRCREV", False)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500103 ud.customspec = d.getVar("CCASE_CUSTOM_CONFIG_SPEC")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104
105 ud.server = "%s://%s%s" % (ud.proto, ud.host, ud.path)
106
107 ud.identifier = "clearcase-%s%s-%s" % ( ud.vob.replace("/", ""),
108 ud.module.replace("/", "."),
109 ud.label.replace("/", "."))
110
111 ud.viewname = "%s-view%s" % (ud.identifier, d.getVar("DATETIME", d, True))
112 ud.csname = "%s-config-spec" % (ud.identifier)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500113 ud.ccasedir = os.path.join(d.getVar("DL_DIR"), ud.type)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500114 ud.viewdir = os.path.join(ud.ccasedir, ud.viewname)
115 ud.configspecfile = os.path.join(ud.ccasedir, ud.csname)
116 ud.localfile = "%s.tar.gz" % (ud.identifier)
117
118 self.debug("host = %s" % ud.host)
119 self.debug("path = %s" % ud.path)
120 self.debug("server = %s" % ud.server)
121 self.debug("proto = %s" % ud.proto)
122 self.debug("type = %s" % ud.type)
123 self.debug("vob = %s" % ud.vob)
124 self.debug("module = %s" % ud.module)
125 self.debug("basecmd = %s" % ud.basecmd)
126 self.debug("label = %s" % ud.label)
127 self.debug("ccasedir = %s" % ud.ccasedir)
128 self.debug("viewdir = %s" % ud.viewdir)
129 self.debug("viewname = %s" % ud.viewname)
130 self.debug("configspecfile = %s" % ud.configspecfile)
131 self.debug("localfile = %s" % ud.localfile)
132
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500133 ud.localfile = os.path.join(d.getVar("DL_DIR"), ud.localfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500134
135 def _build_ccase_command(self, ud, command):
136 """
137 Build up a commandline based on ud
138 command is: mkview, setcs, rmview
139 """
140 options = []
141
142 if "rcleartool" in ud.basecmd:
143 options.append("-server %s" % ud.server)
144
145 basecmd = "%s %s" % (ud.basecmd, command)
146
Brad Bishop6dbb3162019-11-25 09:41:34 -0500147 if command == 'mkview':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500148 if not "rcleartool" in ud.basecmd:
149 # Cleartool needs a -snapshot view
150 options.append("-snapshot")
151 options.append("-tag %s" % ud.viewname)
152 options.append(ud.viewdir)
153
Brad Bishop6dbb3162019-11-25 09:41:34 -0500154 elif command == 'rmview':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155 options.append("-force")
156 options.append("%s" % ud.viewdir)
157
Brad Bishop6dbb3162019-11-25 09:41:34 -0500158 elif command == 'setcs':
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159 options.append("-overwrite")
160 options.append(ud.configspecfile)
161
162 else:
163 raise FetchError("Invalid ccase command %s" % command)
164
165 ccasecmd = "%s %s" % (basecmd, " ".join(options))
166 self.debug("ccasecmd = %s" % ccasecmd)
167 return ccasecmd
168
169 def _write_configspec(self, ud, d):
170 """
171 Create config spec file (ud.configspecfile) for ccase view
172 """
173 config_spec = ""
174 custom_config_spec = d.getVar("CCASE_CUSTOM_CONFIG_SPEC", d)
175 if custom_config_spec is not None:
176 for line in custom_config_spec.split("\\n"):
177 config_spec += line+"\n"
178 bb.warn("A custom config spec has been set, SRCREV is only relevant for the tarball name.")
179 else:
180 config_spec += "element * CHECKEDOUT\n"
181 config_spec += "element * %s\n" % ud.label
182 config_spec += "load %s%s\n" % (ud.vob, ud.module)
183
184 logger.info("Using config spec: \n%s" % config_spec)
185
186 with open(ud.configspecfile, 'w') as f:
187 f.write(config_spec)
188
189 def _remove_view(self, ud, d):
190 if os.path.exists(ud.viewdir):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500191 cmd = self._build_ccase_command(ud, 'rmview');
192 logger.info("cleaning up [VOB=%s label=%s view=%s]", ud.vob, ud.label, ud.viewname)
193 bb.fetch2.check_network_access(d, cmd, ud.url)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600194 output = runfetchcmd(cmd, d, workdir=ud.ccasedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500195 logger.info("rmview output: %s", output)
196
197 def need_update(self, ud, d):
198 if ("LATEST" in ud.label) or (ud.customspec and "LATEST" in ud.customspec):
199 ud.identifier += "-%s" % d.getVar("DATETIME",d, True)
200 return True
201 if os.path.exists(ud.localpath):
202 return False
203 return True
204
205 def supports_srcrev(self):
206 return True
207
208 def sortable_revision(self, ud, d, name):
209 return False, ud.identifier
210
211 def download(self, ud, d):
212 """Fetch url"""
213
214 # Make a fresh view
215 bb.utils.mkdirhier(ud.ccasedir)
216 self._write_configspec(ud, d)
217 cmd = self._build_ccase_command(ud, 'mkview')
218 logger.info("creating view [VOB=%s label=%s view=%s]", ud.vob, ud.label, ud.viewname)
219 bb.fetch2.check_network_access(d, cmd, ud.url)
220 try:
221 runfetchcmd(cmd, d)
222 except FetchError as e:
223 if "CRCLI2008E" in e.msg:
224 raise FetchError("%s\n%s\n" % (e.msg, "Call `rcleartool login` in your console to authenticate to the clearcase server before running bitbake."))
225 else:
226 raise e
227
228 # Set configspec: Setting the configspec effectively fetches the files as defined in the configspec
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500229 cmd = self._build_ccase_command(ud, 'setcs');
230 logger.info("fetching data [VOB=%s label=%s view=%s]", ud.vob, ud.label, ud.viewname)
231 bb.fetch2.check_network_access(d, cmd, ud.url)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600232 output = runfetchcmd(cmd, d, workdir=ud.viewdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233 logger.info("%s", output)
234
235 # Copy the configspec to the viewdir so we have it in our source tarball later
236 shutil.copyfile(ud.configspecfile, os.path.join(ud.viewdir, ud.csname))
237
238 # Clean clearcase meta-data before tar
239
Andrew Geissler82c905d2020-04-13 13:39:40 -0500240 runfetchcmd('tar -czf "%s" .' % (ud.localpath), d, cleanup = [ud.localpath], workdir = ud.viewdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500241
242 # Clean up so we can create a new view next time
243 self.clean(ud, d);
244
245 def clean(self, ud, d):
246 self._remove_view(ud, d)
247 bb.utils.remove(ud.configspecfile)