summaryrefslogtreecommitdiffstats
path: root/scripts/lib
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-08-05 15:48:00 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-09-03 23:45:54 +0100
commite616beba1c85e31246d1c798191b194d168b3489 (patch)
tree5b9d19e7c4a7caeb72f1bb9da4a2b221cfb1da96 /scripts/lib
parentf2854c67ce963211f27223bd1194420621694bc2 (diff)
downloadpoky-e616beba1c85e31246d1c798191b194d168b3489.tar.gz
scripts: ensure tinfoil is shut down correctly
We should always shut down tinfoil when we're finished with it, either by explicitly calling the shutdown() method or by using it as a context manager ("with ..."). (From OE-Core rev: 5ec6d9ef309b841cdcbf1d14ac678d106d5d888a) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib')
-rw-r--r--scripts/lib/devtool/build_image.py124
-rw-r--r--scripts/lib/devtool/deploy.py141
-rw-r--r--scripts/lib/devtool/runqemu.py8
-rw-r--r--scripts/lib/devtool/standard.py355
-rw-r--r--scripts/lib/devtool/upgrade.py85
5 files changed, 369 insertions, 344 deletions
diff --git a/scripts/lib/devtool/build_image.py b/scripts/lib/devtool/build_image.py
index 14c646a066..ae75511dc7 100644
--- a/scripts/lib/devtool/build_image.py
+++ b/scripts/lib/devtool/build_image.py
@@ -86,70 +86,76 @@ def build_image_task(config, basepath, workspace, image, add_packages=None, task
86 raise 86 raise
87 87
88 tinfoil = setup_tinfoil(basepath=basepath) 88 tinfoil = setup_tinfoil(basepath=basepath)
89 rd = parse_recipe(config, tinfoil, image, True)
90 if not rd:
91 # Error already shown
92 return (1, None)
93 if not bb.data.inherits_class('image', rd):
94 raise TargetNotImageError()
95
96 # Get the actual filename used and strip the .bb and full path
97 target_basename = rd.getVar('FILE', True)
98 target_basename = os.path.splitext(os.path.basename(target_basename))[0]
99 config.set('SDK', 'target_basename', target_basename)
100 config.write()
101
102 appendfile = os.path.join(config.workspace_path, 'appends',
103 '%s.bbappend' % target_basename)
104
105 outputdir = None
106 try: 89 try:
107 if workspace or add_packages: 90 rd = parse_recipe(config, tinfoil, image, True)
108 if add_packages: 91 if not rd:
109 packages = add_packages 92 # Error already shown
110 else: 93 return (1, None)
111 packages = _get_packages(tinfoil, workspace, config) 94 if not bb.data.inherits_class('image', rd):
112 else: 95 raise TargetNotImageError()
113 packages = None 96
114 if not task: 97 # Get the actual filename used and strip the .bb and full path
115 if not packages and not add_packages and workspace: 98 target_basename = rd.getVar('FILE', True)
116 logger.warning('No recipes in workspace, building image %s unmodified', image) 99 target_basename = os.path.splitext(os.path.basename(target_basename))[0]
117 elif not packages: 100 config.set('SDK', 'target_basename', target_basename)
118 logger.warning('No packages to add, building image %s unmodified', image) 101 config.write()
119
120 if packages or extra_append:
121 bb.utils.mkdirhier(os.path.dirname(appendfile))
122 with open(appendfile, 'w') as afile:
123 if packages:
124 # include packages from workspace recipes into the image
125 afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages))
126 if not task:
127 logger.info('Building image %s with the following '
128 'additional packages: %s', image, ' '.join(packages))
129 if extra_append:
130 for line in extra_append:
131 afile.write('%s\n' % line)
132
133 if task in ['populate_sdk', 'populate_sdk_ext']:
134 outputdir = rd.getVar('SDK_DEPLOY', True)
135 else:
136 outputdir = rd.getVar('DEPLOY_DIR_IMAGE', True)
137
138 tinfoil.shutdown()
139 102
140 options = '' 103 appendfile = os.path.join(config.workspace_path, 'appends',
141 if task: 104 '%s.bbappend' % target_basename)
142 options += '-c %s' % task
143 105
144 # run bitbake to build image (or specified task) 106 outputdir = None
145 try: 107 try:
146 exec_build_env_command(config.init_path, basepath, 108 if workspace or add_packages:
147 'bitbake %s %s' % (options, image), watch=True) 109 if add_packages:
148 except ExecutionError as err: 110 packages = add_packages
149 return (err.exitcode, None) 111 else:
112 packages = _get_packages(tinfoil, workspace, config)
113 else:
114 packages = None
115 if not task:
116 if not packages and not add_packages and workspace:
117 logger.warning('No recipes in workspace, building image %s unmodified', image)
118 elif not packages:
119 logger.warning('No packages to add, building image %s unmodified', image)
120
121 if packages or extra_append:
122 bb.utils.mkdirhier(os.path.dirname(appendfile))
123 with open(appendfile, 'w') as afile:
124 if packages:
125 # include packages from workspace recipes into the image
126 afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages))
127 if not task:
128 logger.info('Building image %s with the following '
129 'additional packages: %s', image, ' '.join(packages))
130 if extra_append:
131 for line in extra_append:
132 afile.write('%s\n' % line)
133
134 if task in ['populate_sdk', 'populate_sdk_ext']:
135 outputdir = rd.getVar('SDK_DEPLOY', True)
136 else:
137 outputdir = rd.getVar('DEPLOY_DIR_IMAGE', True)
138
139 tmp_tinfoil = tinfoil
140 tinfoil = None
141 tmp_tinfoil.shutdown()
142
143 options = ''
144 if task:
145 options += '-c %s' % task
146
147 # run bitbake to build image (or specified task)
148 try:
149 exec_build_env_command(config.init_path, basepath,
150 'bitbake %s %s' % (options, image), watch=True)
151 except ExecutionError as err:
152 return (err.exitcode, None)
153 finally:
154 if os.path.isfile(appendfile):
155 os.unlink(appendfile)
150 finally: 156 finally:
151 if os.path.isfile(appendfile): 157 if tinfoil:
152 os.unlink(appendfile) 158 tinfoil.shutdown()
153 return (0, outputdir) 159 return (0, outputdir)
154 160
155 161
diff --git a/scripts/lib/devtool/deploy.py b/scripts/lib/devtool/deploy.py
index 66644ccb6a..fb84f2dd08 100644
--- a/scripts/lib/devtool/deploy.py
+++ b/scripts/lib/devtool/deploy.py
@@ -155,83 +155,86 @@ def deploy(args, config, basepath, workspace):
155 155
156 tinfoil = setup_tinfoil(basepath=basepath) 156 tinfoil = setup_tinfoil(basepath=basepath)
157 try: 157 try:
158 rd = oe.recipeutils.parse_recipe_simple(tinfoil.cooker, args.recipename, tinfoil.config_data) 158 try:
159 except Exception as e: 159 rd = oe.recipeutils.parse_recipe_simple(tinfoil.cooker, args.recipename, tinfoil.config_data)
160 raise DevtoolError('Exception parsing recipe %s: %s' % 160 except Exception as e:
161 (args.recipename, e)) 161 raise DevtoolError('Exception parsing recipe %s: %s' %
162 recipe_outdir = rd.getVar('D', True) 162 (args.recipename, e))
163 if not os.path.exists(recipe_outdir) or not os.listdir(recipe_outdir): 163 recipe_outdir = rd.getVar('D', True)
164 raise DevtoolError('No files to deploy - have you built the %s ' 164 if not os.path.exists(recipe_outdir) or not os.listdir(recipe_outdir):
165 'recipe? If so, the install step has not installed ' 165 raise DevtoolError('No files to deploy - have you built the %s '
166 'any files.' % args.recipename) 166 'recipe? If so, the install step has not installed '
167 'any files.' % args.recipename)
167 168
168 filelist = [] 169 filelist = []
169 ftotalsize = 0 170 ftotalsize = 0
170 for root, _, files in os.walk(recipe_outdir): 171 for root, _, files in os.walk(recipe_outdir):
171 for fn in files: 172 for fn in files:
172 # Get the size in kiB (since we'll be comparing it to the output of du -k) 173 # Get the size in kiB (since we'll be comparing it to the output of du -k)
173 # MUST use lstat() here not stat() or getfilesize() since we don't want to 174 # MUST use lstat() here not stat() or getfilesize() since we don't want to
174 # dereference symlinks 175 # dereference symlinks
175 fsize = int(math.ceil(float(os.lstat(os.path.join(root, fn)).st_size)/1024)) 176 fsize = int(math.ceil(float(os.lstat(os.path.join(root, fn)).st_size)/1024))
176 ftotalsize += fsize 177 ftotalsize += fsize
177 # The path as it would appear on the target 178 # The path as it would appear on the target
178 fpath = os.path.join(destdir, os.path.relpath(root, recipe_outdir), fn) 179 fpath = os.path.join(destdir, os.path.relpath(root, recipe_outdir), fn)
179 filelist.append((fpath, fsize)) 180 filelist.append((fpath, fsize))
180 181
181 if args.dry_run: 182 if args.dry_run:
182 print('Files to be deployed for %s on target %s:' % (args.recipename, args.target)) 183 print('Files to be deployed for %s on target %s:' % (args.recipename, args.target))
183 for item, _ in filelist: 184 for item, _ in filelist:
184 print(' %s' % item) 185 print(' %s' % item)
185 return 0 186 return 0
186 187
187 188
188 extraoptions = '' 189 extraoptions = ''
189 if args.no_host_check: 190 if args.no_host_check:
190 extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' 191 extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
191 if not args.show_status: 192 if not args.show_status:
192 extraoptions += ' -q' 193 extraoptions += ' -q'
193 194
194 # In order to delete previously deployed files and have the manifest file on 195 # In order to delete previously deployed files and have the manifest file on
195 # the target, we write out a shell script and then copy it to the target 196 # the target, we write out a shell script and then copy it to the target
196 # so we can then run it (piping tar output to it). 197 # so we can then run it (piping tar output to it).
197 # (We cannot use scp here, because it doesn't preserve symlinks.) 198 # (We cannot use scp here, because it doesn't preserve symlinks.)
198 tmpdir = tempfile.mkdtemp(prefix='devtool') 199 tmpdir = tempfile.mkdtemp(prefix='devtool')
199 try: 200 try:
200 tmpscript = '/tmp/devtool_deploy.sh' 201 tmpscript = '/tmp/devtool_deploy.sh'
201 tmpfilelist = os.path.join(os.path.dirname(tmpscript), 'devtool_deploy.list') 202 tmpfilelist = os.path.join(os.path.dirname(tmpscript), 'devtool_deploy.list')
202 shellscript = _prepare_remote_script(deploy=True, 203 shellscript = _prepare_remote_script(deploy=True,
203 verbose=args.show_status, 204 verbose=args.show_status,
204 nopreserve=args.no_preserve, 205 nopreserve=args.no_preserve,
205 nocheckspace=args.no_check_space) 206 nocheckspace=args.no_check_space)
206 # Write out the script to a file 207 # Write out the script to a file
207 with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f: 208 with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f:
208 f.write(shellscript) 209 f.write(shellscript)
209 # Write out the file list 210 # Write out the file list
210 with open(os.path.join(tmpdir, os.path.basename(tmpfilelist)), 'w') as f: 211 with open(os.path.join(tmpdir, os.path.basename(tmpfilelist)), 'w') as f:
211 f.write('%d\n' % ftotalsize) 212 f.write('%d\n' % ftotalsize)
212 for fpath, fsize in filelist: 213 for fpath, fsize in filelist:
213 f.write('%s %d\n' % (fpath, fsize)) 214 f.write('%s %d\n' % (fpath, fsize))
214 # Copy them to the target 215 # Copy them to the target
215 ret = subprocess.call("scp %s %s/* %s:%s" % (extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True) 216 ret = subprocess.call("scp %s %s/* %s:%s" % (extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True)
216 if ret != 0: 217 if ret != 0:
217 raise DevtoolError('Failed to copy script to %s - rerun with -s to ' 218 raise DevtoolError('Failed to copy script to %s - rerun with -s to '
218 'get a complete error message' % args.target) 219 'get a complete error message' % args.target)
219 finally: 220 finally:
220 shutil.rmtree(tmpdir) 221 shutil.rmtree(tmpdir)
221 222
222 # Now run the script 223 # Now run the script
223 ret = exec_fakeroot(rd, 'tar cf - . | ssh %s %s \'sh %s %s %s %s\'' % (extraoptions, args.target, tmpscript, args.recipename, destdir, tmpfilelist), cwd=recipe_outdir, shell=True) 224 ret = exec_fakeroot(rd, 'tar cf - . | ssh %s %s \'sh %s %s %s %s\'' % (extraoptions, args.target, tmpscript, args.recipename, destdir, tmpfilelist), cwd=recipe_outdir, shell=True)
224 if ret != 0: 225 if ret != 0:
225 raise DevtoolError('Deploy failed - rerun with -s to get a complete ' 226 raise DevtoolError('Deploy failed - rerun with -s to get a complete '
226 'error message') 227 'error message')
227 228
228 logger.info('Successfully deployed %s' % recipe_outdir) 229 logger.info('Successfully deployed %s' % recipe_outdir)
229 230
230 files_list = [] 231 files_list = []
231 for root, _, files in os.walk(recipe_outdir): 232 for root, _, files in os.walk(recipe_outdir):
232 for filename in files: 233 for filename in files:
233 filename = os.path.relpath(os.path.join(root, filename), recipe_outdir) 234 filename = os.path.relpath(os.path.join(root, filename), recipe_outdir)
234 files_list.append(os.path.join(destdir, filename)) 235 files_list.append(os.path.join(destdir, filename))
236 finally:
237 tinfoil.shutdown()
235 238
236 return 0 239 return 0
237 240
diff --git a/scripts/lib/devtool/runqemu.py b/scripts/lib/devtool/runqemu.py
index daee7fbbe3..303abcae4f 100644
--- a/scripts/lib/devtool/runqemu.py
+++ b/scripts/lib/devtool/runqemu.py
@@ -30,9 +30,11 @@ def runqemu(args, config, basepath, workspace):
30 """Entry point for the devtool 'runqemu' subcommand""" 30 """Entry point for the devtool 'runqemu' subcommand"""
31 31
32 tinfoil = setup_tinfoil(config_only=True, basepath=basepath) 32 tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
33 machine = tinfoil.config_data.getVar('MACHINE', True) 33 try:
34 bindir_native = tinfoil.config_data.getVar('STAGING_BINDIR_NATIVE', True) 34 machine = tinfoil.config_data.getVar('MACHINE', True)
35 tinfoil.shutdown() 35 bindir_native = tinfoil.config_data.getVar('STAGING_BINDIR_NATIVE', True)
36 finally:
37 tinfoil.shutdown()
36 38
37 if not glob.glob(os.path.join(bindir_native, 'qemu-system-*')): 39 if not glob.glob(os.path.join(bindir_native, 'qemu-system-*')):
38 raise DevtoolError('QEMU is not available within this SDK') 40 raise DevtoolError('QEMU is not available within this SDK')
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 0d5a42197b..98451da441 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -213,54 +213,56 @@ def add(args, config, basepath, workspace):
213 _add_md5(config, recipename, os.path.join(recipedir, fn)) 213 _add_md5(config, recipename, os.path.join(recipedir, fn))
214 214
215 tinfoil = setup_tinfoil(config_only=True, basepath=basepath) 215 tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
216 rd = oe.recipeutils.parse_recipe(tinfoil.cooker, recipefile, None) 216 try:
217 if not rd: 217 rd = oe.recipeutils.parse_recipe(tinfoil.cooker, recipefile, None)
218 return 1 218 if not rd:
219 219 return 1
220 if args.fetchuri and not args.no_git:
221 setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data)
222
223 initial_rev = None
224 if os.path.exists(os.path.join(srctree, '.git')):
225 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
226 initial_rev = stdout.rstrip()
227
228 if args.src_subdir:
229 srctree = os.path.join(srctree, args.src_subdir)
230
231 bb.utils.mkdirhier(os.path.dirname(appendfile))
232 with open(appendfile, 'w') as f:
233 f.write('inherit externalsrc\n')
234 f.write('EXTERNALSRC = "%s"\n' % srctree)
235
236 b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
237 if b_is_s:
238 f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree)
239 if initial_rev:
240 f.write('\n# initial_rev: %s\n' % initial_rev)
241
242 if args.binary:
243 f.write('do_install_append() {\n')
244 f.write(' rm -rf ${D}/.git\n')
245 f.write(' rm -f ${D}/singletask.lock\n')
246 f.write('}\n')
247
248 if bb.data.inherits_class('npm', rd):
249 f.write('do_install_append() {\n')
250 f.write(' # Remove files added to source dir by devtool/externalsrc\n')
251 f.write(' rm -f ${NPM_INSTALLDIR}/singletask.lock\n')
252 f.write(' rm -rf ${NPM_INSTALLDIR}/.git\n')
253 f.write(' rm -rf ${NPM_INSTALLDIR}/oe-local-files\n')
254 f.write(' for symlink in ${EXTERNALSRC_SYMLINKS} ; do\n')
255 f.write(' rm -f ${NPM_INSTALLDIR}/${symlink%%:*}\n')
256 f.write(' done\n')
257 f.write('}\n')
258 220
259 _add_md5(config, recipename, appendfile) 221 if args.fetchuri and not args.no_git:
222 setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data)
260 223
261 logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile) 224 initial_rev = None
225 if os.path.exists(os.path.join(srctree, '.git')):
226 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
227 initial_rev = stdout.rstrip()
228
229 if args.src_subdir:
230 srctree = os.path.join(srctree, args.src_subdir)
231
232 bb.utils.mkdirhier(os.path.dirname(appendfile))
233 with open(appendfile, 'w') as f:
234 f.write('inherit externalsrc\n')
235 f.write('EXTERNALSRC = "%s"\n' % srctree)
236
237 b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
238 if b_is_s:
239 f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree)
240 if initial_rev:
241 f.write('\n# initial_rev: %s\n' % initial_rev)
242
243 if args.binary:
244 f.write('do_install_append() {\n')
245 f.write(' rm -rf ${D}/.git\n')
246 f.write(' rm -f ${D}/singletask.lock\n')
247 f.write('}\n')
248
249 if bb.data.inherits_class('npm', rd):
250 f.write('do_install_append() {\n')
251 f.write(' # Remove files added to source dir by devtool/externalsrc\n')
252 f.write(' rm -f ${NPM_INSTALLDIR}/singletask.lock\n')
253 f.write(' rm -rf ${NPM_INSTALLDIR}/.git\n')
254 f.write(' rm -rf ${NPM_INSTALLDIR}/oe-local-files\n')
255 f.write(' for symlink in ${EXTERNALSRC_SYMLINKS} ; do\n')
256 f.write(' rm -f ${NPM_INSTALLDIR}/${symlink%%:*}\n')
257 f.write(' done\n')
258 f.write('}\n')
259
260 _add_md5(config, recipename, appendfile)
261
262 logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile)
262 263
263 tinfoil.shutdown() 264 finally:
265 tinfoil.shutdown()
264 266
265 return 0 267 return 0
266 268
@@ -352,19 +354,21 @@ def extract(args, config, basepath, workspace):
352 if not tinfoil: 354 if not tinfoil:
353 # Error already shown 355 # Error already shown
354 return 1 356 return 1
357 try:
358 rd = parse_recipe(config, tinfoil, args.recipename, True)
359 if not rd:
360 return 1
355 361
356 rd = parse_recipe(config, tinfoil, args.recipename, True) 362 srctree = os.path.abspath(args.srctree)
357 if not rd: 363 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, rd)
358 return 1 364 logger.info('Source tree extracted to %s' % srctree)
359
360 srctree = os.path.abspath(args.srctree)
361 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, False, rd)
362 logger.info('Source tree extracted to %s' % srctree)
363 365
364 if initial_rev: 366 if initial_rev:
365 return 0 367 return 0
366 else: 368 else:
367 return 1 369 return 1
370 finally:
371 tinfoil.shutdown()
368 372
369def sync(args, config, basepath, workspace): 373def sync(args, config, basepath, workspace):
370 """Entry point for the devtool 'sync' subcommand""" 374 """Entry point for the devtool 'sync' subcommand"""
@@ -374,19 +378,21 @@ def sync(args, config, basepath, workspace):
374 if not tinfoil: 378 if not tinfoil:
375 # Error already shown 379 # Error already shown
376 return 1 380 return 1
381 try:
382 rd = parse_recipe(config, tinfoil, args.recipename, True)
383 if not rd:
384 return 1
377 385
378 rd = parse_recipe(config, tinfoil, args.recipename, True) 386 srctree = os.path.abspath(args.srctree)
379 if not rd: 387 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, True, rd)
380 return 1 388 logger.info('Source tree %s synchronized' % srctree)
381
382 srctree = os.path.abspath(args.srctree)
383 initial_rev = _extract_source(srctree, args.keep_temp, args.branch, True, rd)
384 logger.info('Source tree %s synchronized' % srctree)
385 389
386 if initial_rev: 390 if initial_rev:
387 return 0 391 return 0
388 else: 392 else:
389 return 1 393 return 1
394 finally:
395 tinfoil.shutdown()
390 396
391class BbTaskExecutor(object): 397class BbTaskExecutor(object):
392 """Class for executing bitbake tasks for a recipe 398 """Class for executing bitbake tasks for a recipe
@@ -715,109 +721,111 @@ def modify(args, config, basepath, workspace):
715 args.recipename) 721 args.recipename)
716 722
717 tinfoil = setup_tinfoil(basepath=basepath) 723 tinfoil = setup_tinfoil(basepath=basepath)
718 rd = parse_recipe(config, tinfoil, args.recipename, True) 724 try:
719 if not rd: 725 rd = parse_recipe(config, tinfoil, args.recipename, True)
720 return 1 726 if not rd:
721
722 pn = rd.getVar('PN', True)
723 if pn != args.recipename:
724 logger.info('Mapping %s to %s' % (args.recipename, pn))
725 if pn in workspace:
726 raise DevtoolError("recipe %s is already in your workspace" %
727 pn)
728
729 if args.srctree:
730 srctree = os.path.abspath(args.srctree)
731 else:
732 srctree = get_default_srctree(config, pn)
733
734 if args.no_extract and not os.path.isdir(srctree):
735 raise DevtoolError("--no-extract specified and source path %s does "
736 "not exist or is not a directory" %
737 srctree)
738 if not args.no_extract:
739 tinfoil = _prep_extract_operation(config, basepath, pn, tinfoil)
740 if not tinfoil:
741 # Error already shown
742 return 1 727 return 1
743 728
744 recipefile = rd.getVar('FILE', True) 729 pn = rd.getVar('PN', True)
745 appendfile = recipe_to_append(recipefile, config, args.wildcard) 730 if pn != args.recipename:
746 if os.path.exists(appendfile): 731 logger.info('Mapping %s to %s' % (args.recipename, pn))
747 raise DevtoolError("Another variant of recipe %s is already in your " 732 if pn in workspace:
748 "workspace (only one variant of a recipe can " 733 raise DevtoolError("recipe %s is already in your workspace" %
749 "currently be worked on at once)" 734 pn)
750 % pn)
751
752 _check_compatible_recipe(pn, rd)
753 735
754 initial_rev = None 736 if args.srctree:
755 commits = [] 737 srctree = os.path.abspath(args.srctree)
756 if not args.no_extract: 738 else:
757 initial_rev = _extract_source(srctree, False, args.branch, False, rd) 739 srctree = get_default_srctree(config, pn)
758 if not initial_rev: 740
759 return 1 741 if args.no_extract and not os.path.isdir(srctree):
760 logger.info('Source tree extracted to %s' % srctree) 742 raise DevtoolError("--no-extract specified and source path %s does "
761 # Get list of commits since this revision 743 "not exist or is not a directory" %
762 (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree) 744 srctree)
763 commits = stdout.split() 745 if not args.no_extract:
764 else: 746 tinfoil = _prep_extract_operation(config, basepath, pn, tinfoil)
765 if os.path.exists(os.path.join(srctree, '.git')): 747 if not tinfoil:
766 # Check if it's a tree previously extracted by us 748 # Error already shown
767 try: 749 return 1
768 (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree) 750
769 except bb.process.ExecutionError: 751 recipefile = rd.getVar('FILE', True)
770 stdout = '' 752 appendfile = recipe_to_append(recipefile, config, args.wildcard)
771 for line in stdout.splitlines(): 753 if os.path.exists(appendfile):
772 if line.startswith('*'): 754 raise DevtoolError("Another variant of recipe %s is already in your "
773 (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree) 755 "workspace (only one variant of a recipe can "
774 initial_rev = stdout.rstrip() 756 "currently be worked on at once)"
757 % pn)
758
759 _check_compatible_recipe(pn, rd)
760
761 initial_rev = None
762 commits = []
763 if not args.no_extract:
764 initial_rev = _extract_source(srctree, False, args.branch, False, rd)
775 if not initial_rev: 765 if not initial_rev:
776 # Otherwise, just grab the head revision 766 return 1
777 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree) 767 logger.info('Source tree extracted to %s' % srctree)
778 initial_rev = stdout.rstrip() 768 # Get list of commits since this revision
779 769 (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree)
780 # Check that recipe isn't using a shared workdir 770 commits = stdout.split()
781 s = os.path.abspath(rd.getVar('S', True)) 771 else:
782 workdir = os.path.abspath(rd.getVar('WORKDIR', True)) 772 if os.path.exists(os.path.join(srctree, '.git')):
783 if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir: 773 # Check if it's a tree previously extracted by us
784 # Handle if S is set to a subdirectory of the source 774 try:
785 srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1] 775 (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree)
786 srctree = os.path.join(srctree, srcsubdir) 776 except bb.process.ExecutionError:
787 777 stdout = ''
788 bb.utils.mkdirhier(os.path.dirname(appendfile)) 778 for line in stdout.splitlines():
789 with open(appendfile, 'w') as f: 779 if line.startswith('*'):
790 f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n') 780 (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree)
791 # Local files can be modified/tracked in separate subdir under srctree 781 initial_rev = stdout.rstrip()
792 # Mostly useful for packages with S != WORKDIR 782 if not initial_rev:
793 f.write('FILESPATH_prepend := "%s:"\n' % 783 # Otherwise, just grab the head revision
794 os.path.join(srctree, 'oe-local-files')) 784 (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
795 785 initial_rev = stdout.rstrip()
796 f.write('\ninherit externalsrc\n')
797 f.write('# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n')
798 f.write('EXTERNALSRC_pn-%s = "%s"\n' % (pn, srctree))
799
800 b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
801 if b_is_s:
802 f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (pn, srctree))
803
804 if bb.data.inherits_class('kernel', rd):
805 f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout '
806 'do_fetch do_unpack do_patch do_kernel_configme do_kernel_configcheck"\n')
807 f.write('\ndo_configure_append() {\n'
808 ' cp ${B}/.config ${S}/.config.baseline\n'
809 ' ln -sfT ${B}/.config ${S}/.config.new\n'
810 '}\n')
811 if initial_rev:
812 f.write('\n# initial_rev: %s\n' % initial_rev)
813 for commit in commits:
814 f.write('# commit: %s\n' % commit)
815
816 _add_md5(config, pn, appendfile)
817 786
818 logger.info('Recipe %s now set up to build from %s' % (pn, srctree)) 787 # Check that recipe isn't using a shared workdir
788 s = os.path.abspath(rd.getVar('S', True))
789 workdir = os.path.abspath(rd.getVar('WORKDIR', True))
790 if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir:
791 # Handle if S is set to a subdirectory of the source
792 srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1]
793 srctree = os.path.join(srctree, srcsubdir)
794
795 bb.utils.mkdirhier(os.path.dirname(appendfile))
796 with open(appendfile, 'w') as f:
797 f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n')
798 # Local files can be modified/tracked in separate subdir under srctree
799 # Mostly useful for packages with S != WORKDIR
800 f.write('FILESPATH_prepend := "%s:"\n' %
801 os.path.join(srctree, 'oe-local-files'))
802
803 f.write('\ninherit externalsrc\n')
804 f.write('# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n')
805 f.write('EXTERNALSRC_pn-%s = "%s"\n' % (pn, srctree))
806
807 b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
808 if b_is_s:
809 f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (pn, srctree))
810
811 if bb.data.inherits_class('kernel', rd):
812 f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout '
813 'do_fetch do_unpack do_patch do_kernel_configme do_kernel_configcheck"\n')
814 f.write('\ndo_configure_append() {\n'
815 ' cp ${B}/.config ${S}/.config.baseline\n'
816 ' ln -sfT ${B}/.config ${S}/.config.new\n'
817 '}\n')
818 if initial_rev:
819 f.write('\n# initial_rev: %s\n' % initial_rev)
820 for commit in commits:
821 f.write('# commit: %s\n' % commit)
822
823 _add_md5(config, pn, appendfile)
824
825 logger.info('Recipe %s now set up to build from %s' % (pn, srctree))
819 826
820 tinfoil.shutdown() 827 finally:
828 tinfoil.shutdown()
821 829
822 return 0 830 return 0
823 831
@@ -1290,17 +1298,20 @@ def update_recipe(args, config, basepath, workspace):
1290 'destination layer "%s"' % args.append) 1298 'destination layer "%s"' % args.append)
1291 1299
1292 tinfoil = setup_tinfoil(basepath=basepath, tracking=True) 1300 tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
1301 try:
1293 1302
1294 rd = parse_recipe(config, tinfoil, args.recipename, True) 1303 rd = parse_recipe(config, tinfoil, args.recipename, True)
1295 if not rd: 1304 if not rd:
1296 return 1 1305 return 1
1297 1306
1298 updated = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev) 1307 updated = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev)
1299 1308
1300 if updated: 1309 if updated:
1301 rf = rd.getVar('FILE', True) 1310 rf = rd.getVar('FILE', True)
1302 if rf.startswith(config.workspace_path): 1311 if rf.startswith(config.workspace_path):
1303 logger.warn('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf) 1312 logger.warn('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf)
1313 finally:
1314 tinfoil.shutdown()
1304 1315
1305 return 0 1316 return 0
1306 1317
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index a5063f57a9..a4239f1cd2 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -336,48 +336,51 @@ def upgrade(args, config, basepath, workspace):
336 raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename) 336 raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename)
337 337
338 tinfoil = setup_tinfoil(basepath=basepath, tracking=True) 338 tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
339 rd = parse_recipe(config, tinfoil, args.recipename, True)
340 if not rd:
341 return 1
342
343 pn = rd.getVar('PN', True)
344 if pn != args.recipename:
345 logger.info('Mapping %s to %s' % (args.recipename, pn))
346 if pn in workspace:
347 raise DevtoolError("recipe %s is already in your workspace" % pn)
348
349 if args.srctree:
350 srctree = os.path.abspath(args.srctree)
351 else:
352 srctree = standard.get_default_srctree(config, pn)
353
354 standard._check_compatible_recipe(pn, rd)
355 old_srcrev = rd.getVar('SRCREV', True)
356 if old_srcrev == 'INVALID':
357 old_srcrev = None
358 if old_srcrev and not args.srcrev:
359 raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading")
360 if rd.getVar('PV', True) == args.version and old_srcrev == args.srcrev:
361 raise DevtoolError("Current and upgrade versions are the same version")
362
363 rf = None
364 try: 339 try:
365 rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, rd) 340 rd = parse_recipe(config, tinfoil, args.recipename, True)
366 rev2, md5, sha256 = _extract_new_source(args.version, srctree, args.no_patch, 341 if not rd:
367 args.srcrev, args.branch, args.keep_temp, 342 return 1
368 tinfoil, rd) 343
369 rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, args.srcbranch, config.workspace_path, tinfoil, rd) 344 pn = rd.getVar('PN', True)
370 except bb.process.CmdError as e: 345 if pn != args.recipename:
371 _upgrade_error(e, rf, srctree) 346 logger.info('Mapping %s to %s' % (args.recipename, pn))
372 except DevtoolError as e: 347 if pn in workspace:
373 _upgrade_error(e, rf, srctree) 348 raise DevtoolError("recipe %s is already in your workspace" % pn)
374 standard._add_md5(config, pn, os.path.dirname(rf)) 349
375 350 if args.srctree:
376 af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2, 351 srctree = os.path.abspath(args.srctree)
377 copied, config.workspace_path, rd) 352 else:
378 standard._add_md5(config, pn, af) 353 srctree = standard.get_default_srctree(config, pn)
379 logger.info('Upgraded source extracted to %s' % srctree) 354
380 logger.info('New recipe is %s' % rf) 355 standard._check_compatible_recipe(pn, rd)
356 old_srcrev = rd.getVar('SRCREV', True)
357 if old_srcrev == 'INVALID':
358 old_srcrev = None
359 if old_srcrev and not args.srcrev:
360 raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading")
361 if rd.getVar('PV', True) == args.version and old_srcrev == args.srcrev:
362 raise DevtoolError("Current and upgrade versions are the same version")
363
364 rf = None
365 try:
366 rev1 = standard._extract_source(srctree, False, 'devtool-orig', False, rd)
367 rev2, md5, sha256 = _extract_new_source(args.version, srctree, args.no_patch,
368 args.srcrev, args.branch, args.keep_temp,
369 tinfoil, rd)
370 rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, args.srcbranch, config.workspace_path, tinfoil, rd)
371 except bb.process.CmdError as e:
372 _upgrade_error(e, rf, srctree)
373 except DevtoolError as e:
374 _upgrade_error(e, rf, srctree)
375 standard._add_md5(config, pn, os.path.dirname(rf))
376
377 af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2,
378 copied, config.workspace_path, rd)
379 standard._add_md5(config, pn, af)
380 logger.info('Upgraded source extracted to %s' % srctree)
381 logger.info('New recipe is %s' % rf)
382 finally:
383 tinfoil.shutdown()
381 return 0 384 return 0
382 385
383def register_commands(subparsers, context): 386def register_commands(subparsers, context):