All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
To: Paul Eggleton <paul.eggleton@linux.intel.com>
Cc: openembedded-core@lists.openembedded.org
Subject: Re: [PATCH v2 3/3] import: new plugin to import the devtool workspace
Date: Mon, 12 Jun 2017 10:27:41 -0500	[thread overview]
Message-ID: <1497281261.26945.197.camel@linux.intel.com> (raw)
In-Reply-To: <3141634.Z718jrWpIV@peggleto-mobl.ger.corp.intel.com>

On Mon, 2017-06-12 at 16:19 +0200, Paul Eggleton wrote:
> Hi Leo,
> 
> A few comments below.
> 

Thanks Paul. Too late to provided a v3 before M1, so I will work on the
changes during M2.

Leo

> 
> On Friday, 2 June 2017 7:13:01 PM CEST leonardo.sandoval.gonzalez@linux.intel.com wrote:
> > From: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
> > 
> > Takes a tar archive created by 'devtool export' and export it (untar) to
> > workspace. By default, the whole tar archive is imported, thus there is no
> > way to limit what is imported.
> > 
> > https://bugzilla.yoctoproject.org/show_bug.cgi?id=10510
> > 
> > [YOCTO #10510]
> > 
> > Signed-off-by: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
> > ---
> >  scripts/lib/devtool/import.py | 130 ++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 130 insertions(+)
> >  create mode 100644 scripts/lib/devtool/import.py
> > 
> > diff --git a/scripts/lib/devtool/import.py b/scripts/lib/devtool/import.py
> > new file mode 100644
> > index 0000000000..5b85571669
> > --- /dev/null
> > +++ b/scripts/lib/devtool/import.py
> > @@ -0,0 +1,130 @@
> > +# Development tool - import command plugin
> > +#
> > +# Copyright (C) 2014-2017 Intel Corporation
> > +#
> > +# This program is free software; you can redistribute it and/or modify
> > +# it under the terms of the GNU General Public License version 2 as
> > +# published by the Free Software Foundation.
> > +#
> > +# This program is distributed in the hope that it will be useful,
> > +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > +# GNU General Public License for more details.
> > +#
> > +# You should have received a copy of the GNU General Public License along
> > +# with this program; if not, write to the Free Software Foundation, Inc.,
> > +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> > +"""Devtool import plugin"""
> > +
> > +import os
> > +import tarfile
> > +import logging
> > +import re
> > +from devtool import standard, setup_tinfoil
> > +from devtool import export
> > +
> > +import oeqa.utils.ftools as ftools
> 
> So, this is importing something from oeqa to use outside of the QA scripts.
> Aside from that structural oddity, I have to be honest and say I'd rather we
> did it the replacement in specific code here rather than creating and using
> a generic function (especially seeing as we don't already have one) - then
> we avoid the need to open the file and process all lines multiple times.
> 
> 
> > +import json
> > +
> > +logger = logging.getLogger('devtool')
> > +
> > +def devimport(args, config, basepath, workspace):
> > +    """Entry point for the devtool 'import' subcommand"""
> > +
> > +    def get_pn(name):
> > +        dirpath, recipe = os.path.split(name)
> > +        pn = ""
> > +        for sep in "_ .".split():
> > +            if sep in recipe:
> > +                pn = recipe.split(sep)[0]
> > +                break
> > +        return pn
> 
> This function is a little worrying. Recipe names can legally have dots
> in the PN part of the name. See below for a recommended alternative.
> 
> > +    
> > +    # match exported workspace folders
> > +    prog = re.compile('recipes|appends|sources')
> > +
> > +    if not os.path.exists(args.file):
> > +        logger.error('Tar archive %s does not exist. Export your workspace using "devtool export"')
> > +        return 1
> > +
> > +    # get current recipes
> > +    current_recipes = []
> > +    try:
> > +        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
> 
> The setup_tinfoil() here should be outside of the try...finally or if it fails
> to start it will still try to shut it down.
> 
> 
> > +        current_recipes = [recipe[1] for recipe in tinfoil.cooker.recipecaches[''].pkg_fn.items()]
> > +    finally:
> > +        tinfoil.shutdown()
> > +
> > +    imported = []
> > +    with tarfile.open(args.file) as tar:
> > +
> > +        # get exported metadata so values containing paths can be automatically replaced it
> > +        export_workspace_path = export_workspace = None
> > +        try:
> > +            metadata = tar.getmember(export.metadata)
> > +            tar.extract(metadata)
> > +            with open(metadata.name) as fdm:
> > +                export_workspace_path, export_workspace = json.load(fdm)
> > +            os.unlink(metadata.name)
> > +        except KeyError as ke:
> > +            logger.warn('The export metadata file created by "devtool export" was not found')
> > +            logger.warn('Manual editing is needed to correct paths on imported recipes/appends')
> 
> We should just fail if the metadata file isn't there - we don't need to
> support users importing any random tarball; if the metadata file
> isn't there we can safely assume that it wasn't exported with
> devtool export.
> 
> > +
> > +        members = [member for member in tar.getmembers() if member.name != export.metadata]
> > +        for member in members:
> > +            # make sure imported bbappend has its corresponding recipe (bb)
> > +            if member.name.startswith('appends'):
> > +                bbappend = get_pn(member.name)
> > +                if bbappend:
> > +                    if bbappend not in current_recipes:
> > +                        # check that the recipe is not in the tar archive being imported
> > +                        if bbappend not in export_workspace:
> > +                            logger.warn('No recipe to append %s, skipping' % bbappend)
> > +                            continue
> > +                else:
> > +                    logger.warn('bbappend name %s could not be detected' % member.name)
> > +                    continue
> 
> This isn't the right way to check this - PN isn't guaranteed to be the same
> as the name part of the filename, for one. It's much safer to iterate over
> tinfoil.cooker.recipecaches[''].pkg_fn (keys, i.e. filenames, not PN values)
> and see if the bbappend matches the item, breaking out on first match.
> Remember that a bbappend might be the exact same name as the bb file or
> it might use a % wildcard. (You could cheat and replace this % with a * and
> then use fnmatch.fnmatch() to make this a bit easier). 
> 
> Given the moderate expense of computing this we should probably do it
> once as part of the initial check and store it in a dict so we can use it later
> (I see get_pn() is called again later on).
> 
> > +            # extract file from tar
> > +            path = os.path.join(config.workspace_path, member.name)
> > +            if os.path.exists(path):
> > +                if args.overwrite:
> > +                    try:
> > +                        tar.extract(member, path=config.workspace_path)
> > +                    except PermissionError as pe:
> > +                        logger.warn(pe)
> 
> If a recipe is already in someone's workspace, is this going to leave the
> user with a mix of files extracted from the tarball and whatever happens to
> already be in the source tree? If so, that could be problematic. I think I
> would first check if the recipe's source tree exists at all and if so, either
> skip it with a warning or overwrite it entirely dependent on whether -o
> has been specified.
> 
> 
> > +                else:
> > +                    logger.warn('File already present. Use --overwrite/-o to overwrite it: %s' % member.name)
> > +            else:
> > +                tar.extract(member, path=config.workspace_path)
> > +
> > +            if member.name.startswith('appends'):
> > +                recipe = get_pn(member.name)
> > +
> > +                # Update EXTERNARLSRC
> 
> Typo - EXTERNALSRC.
> 
> > +                if export_workspace_path:
> > +                    # appends created by 'devtool modify' just need to update the workspace
> > +                    ftools.replace_from_file(path, export_workspace_path, config.workspace_path)
> > +
> > +                    # appends created by 'devtool add' need replacement of exported source tree
> > +                    exported_srctree = export_workspace[recipe]['srctree']
> > +                    if exported_srctree:
> > +                        ftools.replace_from_file(path, exported_srctree, os.path.join(config.workspace_path, 'sources', recipe))
> > +
> > +                # update .devtool_md5 file
> > +                standard._add_md5(config, recipe, path)
> > +                if recipe not in imported:
> > +                    imported.append(recipe)
> > +
> > +    logger.info('Imported recipes into workspace %s: %s' % (config.workspace_path, ' '.join(imported)))
> > +    return 0
> > +
> > +def register_commands(subparsers, context):
> > +    """Register devtool import subcommands"""
> > +    parser = subparsers.add_parser('import',
> > +                                   help='Import tar archive into workspace',
> > +                                   description='Import previously created tar archive into the workspace',
> 
> We should be specific - 'Import exported tar archive into workspace' and
> 'Import tar archive previously created by "devtool export" into workspace'.
> 
> > +                                   group='advanced')
> > +    parser.add_argument('file', metavar='FILE', help='Name of the tar archive to import')
> > +    parser.add_argument('--overwrite', '-o', action="store_true", help='Overwrite previous export tar archive')
> 
> We're not writing out a tar archive so this should be "Overwrite files when
> extracting" or similar.
> 
> Cheers,
> Paul
> 




  reply	other threads:[~2017-06-12 15:18 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-25 21:31 [PATCH 0/2] Two new devtool plugins: export and import leonardo.sandoval.gonzalez
2017-05-25 21:31 ` [PATCH 1/2] export: new plugin to export the devtool workspace leonardo.sandoval.gonzalez
2017-05-29 22:23   ` Paul Eggleton
2017-05-25 21:31 ` [PATCH 2/2] import: new plugin to import " leonardo.sandoval.gonzalez
2017-05-29 22:39   ` Paul Eggleton
2017-06-02 17:12 ` [PATCH v2 0/3] Two new devtool plugins: export and import leonardo.sandoval.gonzalez
2017-06-02 17:12   ` [PATCH v2 1/3] export: new plugin to export the devtool workspace leonardo.sandoval.gonzalez
2017-06-12 13:43     ` Paul Eggleton
2017-06-02 17:13   ` [PATCH v2 2/3] ftools: new function to replace strings inside a text file leonardo.sandoval.gonzalez
2017-06-02 17:13   ` [PATCH v2 3/3] import: new plugin to import the devtool workspace leonardo.sandoval.gonzalez
2017-06-12 14:19     ` Paul Eggleton
2017-06-12 15:27       ` Leonardo Sandoval [this message]
2017-06-20 18:30   ` [PATCH v3 0/3] Two new devtool plugins: export and import leonardo.sandoval.gonzalez
2017-06-20 18:30     ` [PATCH v3 1/3] export: new plugin to export the devtool workspace leonardo.sandoval.gonzalez
2017-06-20 18:30     ` [PATCH v3 2/3] devtool: function to replace strings inside a text file leonardo.sandoval.gonzalez
2017-06-20 18:30     ` [PATCH v3 3/3] import: new plugin to import the devtool workspace leonardo.sandoval.gonzalez
2017-06-22  8:48       ` Paul Eggleton
2017-06-29 16:40     ` [PATCH v4 0/4] Two new devtool plugins: export and import leonardo.sandoval.gonzalez
2017-06-29 16:40       ` [PATCH v4 1/4] export: new plugin to export the devtool workspace leonardo.sandoval.gonzalez
2017-06-29 16:40       ` [PATCH v4 2/4] devtool: function to replace strings inside a text file leonardo.sandoval.gonzalez
2017-06-29 16:40       ` [PATCH v4 3/4] standard: append md5 tag only if not already present leonardo.sandoval.gonzalez
2017-06-29 16:40       ` [PATCH v4 4/4] import: new plugin to import the devtool workspace leonardo.sandoval.gonzalez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1497281261.26945.197.camel@linux.intel.com \
    --to=leonardo.sandoval.gonzalez@linux.intel.com \
    --cc=openembedded-core@lists.openembedded.org \
    --cc=paul.eggleton@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.