Example #1
0
def step_history_info(ctx, spec=""):
    def pkgs_split(pkgs):
        return pkgs.split(",")

    actions = ['Install', 'Erase', 'Upgrade', 'Upgraded', 'Reinstall', 'Downgrade']
    keys = ['Command Line', 'Return-Code'] + actions

    table = table_utils.parse_kv_table(ctx, ['Key', 'Value'], keys)
    step_i_run_command(ctx, 'dnf history info ' + spec)

    text = getattr(ctx.cmd_result, 'stdout')
    lines = text.split('\n')
    assert text and lines, 'No output'

    brpmdb = None
    erpmdb = None
    cmdline = None
    g_cmdline = table['Command Line'] if 'Command Line' in table else None
    retcode = None
    g_retcode = table['Return-Code'] if 'Return-Code' in table else None

    for line in lines:
        if 'Begin rpmdb' in line:
            brpmdb = line.split(':')

        if 'End rpmdb' in line:
            erpmdb = line.split(':')

        if brpmdb and erpmdb:
            assert len(brpmdb) == len(erpmdb) == 3, 'Unexpected rpmdb version format'
            erpmdb = None

        if 'Return-Code' in line and g_retcode:
            retcode = line.split(':')
            assert len(retcode) == 2, 'Unexpected Return-Code format'
            rc = retcode[1].strip()
            assert rc == g_retcode, 'Return-Code "{}" not matched by "{}"'.format(rc, g_retcode)

        if 'Command Line' in line and g_cmdline:
            cmdline = line.split(':')
            assert len(cmdline) == 2, 'Unexpected Command Line format'
            cmd = cmdline[1].strip()
            assert cmd == g_cmdline, 'Command Line "{}" not matched by "{}"'.format(cmd, g_cmdline)

    assert brpmdb, 'Begin rpmdb version not found'

    if g_cmdline:
        assert cmdline, 'Command line not found'

    if g_retcode:
        assert retcode, 'Return-Code not found'

    for key in actions:
        if key in table:
            pkgs = pkgs_split(table[key])
            for line in lines:
                for pkg in pkgs:
                    if pkg in line and key in line:
                        pkgs.remove(pkg)
            assert not pkgs, '"{}" not matched as "{}"'.format(pkgs[0], key)
def step_history_info(ctx, spec=""):
    def pkgs_split(pkgs):
        return pkgs.split(",")

    actions = ['Install', 'Removed', 'Upgrade', 'Upgraded', 'Reinstall', 'Downgrade']
    keys = ['Command Line', 'Return-Code'] + actions

    table = table_utils.parse_kv_table(ctx, ['Key', 'Value'], keys)
    step_i_run_command(ctx, 'dnf history info ' + spec)

    text = getattr(ctx.cmd_result, 'stdout')
    lines = text.split('\n')
    assert text and lines, 'No output'

    brpmdb = None
    erpmdb = None
    cmdline = None
    g_cmdline = table['Command Line'] if 'Command Line' in table else None
    retcode = None
    g_retcode = table['Return-Code'] if 'Return-Code' in table else None

    for line in lines:
        if 'Begin rpmdb' in line:
            brpmdb = line.split(':')

        if 'End rpmdb' in line:
            erpmdb = line.split(':')

        if brpmdb and erpmdb:
            assert len(brpmdb) == len(erpmdb) == 3, 'Unexpected rpmdb version format'
            erpmdb = None

        if 'Return-Code' in line and g_retcode:
            retcode = line.split(':')
            assert len(retcode) == 2, 'Unexpected Return-Code format'
            rc = retcode[1].strip()
            assert rc == g_retcode, 'Return-Code "{}" not matched by "{}"'.format(rc, g_retcode)

        if 'Command Line' in line and g_cmdline:
            cmdline = line.split(':')
            assert len(cmdline) == 2, 'Unexpected Command Line format'
            cmd = cmdline[1].strip()
            assert cmd == g_cmdline, 'Command Line "{}" not matched by "{}"'.format(cmd, g_cmdline)

    assert brpmdb, 'Begin rpmdb version not found'

    if g_cmdline:
        assert cmdline, 'Command line not found'

    if g_retcode:
        assert retcode, 'Return-Code not found'

    for key in actions:
        if key in table:
            pkgs = pkgs_split(table[key])
            for line in lines:
                for pkg in pkgs:
                    if pkg in line and key in line:
                        pkgs.remove(pkg)
            assert not pkgs, '"{}" not matched as "{}"'.format(pkgs[0], key)
Example #3
0
def step_userinstalled_match(ctx):
    def pkgs_split(pkgs):
        for pkg in pkgs.split(","):
            yield pkg.strip()
    keys = ['Match', 'Not match']
    table = table_utils.parse_kv_table(ctx, ['Action', 'Packages'], keys)
    step_i_run_command(ctx, 'dnf history userinstalled')
    text = getattr(ctx.cmd_result, 'stdout')

    match = table[keys[0]] if keys[0] in table else None
    notmatch = table[keys[1]] if keys[1] in table else None

    if match:
        for m in pkgs_split(match):  # should be matched
            assert m in text, 'Package {} not matched as userinstalled'.format(m)
    if notmatch:
        for n in pkgs_split(notmatch):  # should not be matched
            assert n not in text, 'Package {} matched as userinstalled'.format(m)
def step_userinstalled_match(ctx):
    def pkgs_split(pkgs):
        for pkg in pkgs.split(","):
            yield pkg.strip()
    keys = ['Match', 'Not match']
    table = table_utils.parse_kv_table(ctx, ['Action', 'Packages'], keys)
    step_i_run_command(ctx, 'dnf history userinstalled')
    text = getattr(ctx.cmd_result, 'stdout')

    match = table[keys[0]] if keys[0] in table else None
    notmatch = table[keys[1]] if keys[1] in table else None

    if match:
        for m in pkgs_split(match):  # should be matched
            assert m in text, 'Package {} not matched as userinstalled'.format(m)
    if notmatch:
        for n in pkgs_split(notmatch):  # should not be matched
            assert n not in text, 'Package {} matched as userinstalled'.format(m)
Example #5
0
def step_rpmdb_changes_are(ctx):
    """
    Compare saved by :ref:`When I save rpmdb` and current rpmdb's.

    Requires table with following headers:

    ======= ==========
     State   Packages 
    ======= ==========

    *State* is state of package

    ============ ============== ============= ===============================
       State      rpmdb before   rpmdb after        Additional comments      
    ============ ============== ============= ===============================
    installed    Not installed  Installed     Package has been installed     
    removed      Installed      Not installed Package has been removed       
    absent       Not installed  Not installed Package has not been installed 
    unchanged    Installed      Installed     Package was not changed        
    reinstalled  Installed      Installed     Same packages was reinstalled  
    updated      Installed      Installed     Package has been updated       
    downgraded   Installed      Installed     Package has been downgraded    
    ============ ============== ============= ===============================

    For each *State* you can specify multiple *Packages* which are separated
    by comma.

    Examples:

    .. code-block:: gherkin

       Scenario: Detect reinstalled package
          Given saved rpmdb
           When I successfully run "dnf -y reinstall util-linux"
           Then rpmdb changes are
             | State       | Packages   |
             | reinstalled | util-linux |

    .. _automatic rules:

    **Automatic rules which are additionally applied**:

      - Packages except listed in table must not appear/disappear
      - Packages except listed in table classified as *unchanged*
    """
    ctx.assertion.assertIsNotNone(ctx.rpmdb, "Save rpmdb before comparison")
    table = table_utils.parse_kv_table(ctx, HEADINGS_RPMDB, rpm_utils.State)
    ctx.wipe_rpmdb = True
    rpmdb = rpm_utils.get_rpmdb()
    problems = []

    def unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post):
        problems.append("Package {pkg!r} was supposed to be "
                        "{expected_state!r}, but has been {state!r} "
                        "({pkg_pre!r} -> {pkg_post!r})".format(
                            pkg=pkg, state=state.value,
                            expected_state=expected_state.value,
                            pkg_pre=rpm_utils.hdr2nevra(pkg_pre),
                            pkg_post=rpm_utils.hdr2nevra(pkg_post)))

    def pkgs_split(pkgs):
        for pkg in pkgs.split(","):
            yield pkg.strip()
    # Let's check what user has requested in table
    for expected_state, packages in table.items():
        for pkg in pkgs_split(packages):
            pkg_pre = rpm_utils.find_pkg(ctx.rpmdb, pkg)
            if pkg_pre:
                ctx.rpmdb.remove(pkg_pre)
            pkg_post = rpm_utils.find_pkg(rpmdb, pkg)
            if pkg_post:
                rpmdb.remove(pkg_post)
            state = rpm_utils.analyze_state(pkg_pre, pkg_post)
            if state != expected_state:
                unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post)

    # Let's check if NEVRAs are still same
    def rpmdb2nevra(rpmdb):
        for hdr in rpmdb:
            yield rpm_utils.hdr2nevra(hdr)
    six.assertCountEqual(ctx.assertion,
                         rpmdb2nevra(ctx.rpmdb),
                         rpmdb2nevra(rpmdb))

    # Even if we have same NEVRAs packages can be different or reinstalled
    for pkg_pre, pkg_post in zip(ctx.rpmdb, rpmdb):
        state = rpm_utils.analyze_state(pkg_pre, pkg_post)
        expected_state = rpm_utils.State.unchanged
        # At this point pkg_pre and pkg_post should have same name
        pkg = pkg_pre["name"].decode()
        if state != expected_state:
            unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post)

    assert not problems, "\n{!s}".format("\n".join(problems))
Example #6
0
def step_rpmdb_changes_are(ctx):
    """
    Compare saved by :ref:`When I save rpmdb` and current rpmdb's.

    Requires table with following headers:

    ======= ==========
     State   Packages 
    ======= ==========

    *State* is state of package

    ============ ============== ============= ===============================
       State      rpmdb before   rpmdb after        Additional comments      
    ============ ============== ============= ===============================
    installed    Not installed  Installed     Package has been installed     
    removed      Installed      Not installed Package has been removed       
    absent       Not installed  Not installed Package has not been installed 
    unchanged    Installed      Installed     Package was not changed        
    reinstalled  Installed      Installed     Same packages was reinstalled  
    updated      Installed      Installed     Package has been updated       
    downgraded   Installed      Installed     Package has been downgraded    
    ============ ============== ============= ===============================

    For each *State* you can specify multiple *Packages* which are separated
    by comma.

    Examples:

    .. code-block:: gherkin

       Scenario: Detect reinstalled package
          Given saved rpmdb
           When I successfully run "dnf -y reinstall util-linux"
           Then rpmdb changes are
             | State       | Packages   |
             | reinstalled | util-linux |

    .. _automatic rules:

    **Automatic rules which are additionally applied**:

      - Packages except listed in table must not appear/disappear
      - Packages except listed in table classified as *unchanged*
    """
    ctx.assertion.assertIsNotNone(ctx.rpmdb, "Save rpmdb before comparison")
    table = table_utils.parse_kv_table(ctx, HEADINGS_RPMDB, rpm_utils.State)
    ctx.wipe_rpmdb = True
    rpmdb = rpm_utils.get_rpmdb()
    problems = []

    def unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post):
        problems.append("Package {pkg!r} was supposed to be "
                        "{expected_state!r}, but has been {state!r} "
                        "({pkg_pre!r} -> {pkg_post!r})".format(
                            pkg=pkg,
                            state=state.value,
                            expected_state=expected_state.value,
                            pkg_pre=rpm_utils.hdr2nevra(pkg_pre),
                            pkg_post=rpm_utils.hdr2nevra(pkg_post)))

    def pkgs_split(pkgs):
        for pkg in pkgs.split(","):
            yield pkg.strip()

    # Let's check what user has requested in table
    for expected_state, packages in table.items():
        for pkg in pkgs_split(packages):
            pkg_pre = rpm_utils.find_pkg(ctx.rpmdb, pkg)
            if pkg_pre:
                ctx.rpmdb.remove(pkg_pre)
            pkg_post = rpm_utils.find_pkg(rpmdb, pkg)
            if pkg_post:
                rpmdb.remove(pkg_post)
            state = rpm_utils.analyze_state(pkg_pre, pkg_post)
            if state != expected_state:
                unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post)

    # Let's check if NEVRAs are still same
    def rpmdb2nevra(rpmdb):
        for hdr in rpmdb:
            yield rpm_utils.hdr2nevra(hdr)

    six.assertCountEqual(ctx.assertion, rpmdb2nevra(ctx.rpmdb),
                         rpmdb2nevra(rpmdb))

    # Even if we have same NEVRAs packages can be different or reinstalled
    for pkg_pre, pkg_post in zip(ctx.rpmdb, rpmdb):
        state = rpm_utils.analyze_state(pkg_pre, pkg_post)
        expected_state = rpm_utils.State.unchanged
        # At this point pkg_pre and pkg_post should have same name
        pkg = pkg_pre["name"].decode()
        if state != expected_state:
            unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post)

    assert not problems, "\n{!s}".format("\n".join(problems))
Example #7
0
def step_rpmdb_changes_are(ctx):
    """
    Compare saved by :ref:`When I save rpmdb` and current rpmdb's.

    Requires table with following headers:

    ======= ==========
     State   Packages 
    ======= ==========

    *State* is state of package

    ============ ============== ============= ===============================
       State      rpmdb before   rpmdb after        Additional comments      
    ============ ============== ============= ===============================
    installed    Not installed  Installed     Package has been installed     
    removed      Installed      Not installed Package has been removed       
    absent       Not installed  Not installed Package has not been installed 
    unchanged    Installed      Installed     Package was not changed        
    reinstalled  Installed      Installed     Same packages was reinstalled  
    updated      Installed      Installed     Package has been updated       
    downgraded   Installed      Installed     Package has been downgraded    
    ignored          -              -         Package will be ignored        
    ============ ============== ============= ===============================

    For each *State* you can specify multiple *Packages* which are separated
    by comma.

    For the *ignored* state you can use Unix shell-style wildcard to cover
    multiple package names. Packages with state explicitely stated won't be
    ignored even if they matches pattern.

    Examples:

    .. code-block:: gherkin

       Scenario: Detect reinstalled package
           When I save rpmdb
            And I successfully run "dnf -y reinstall util-linux"
           Then rpmdb changes are
             | State       | Packages   |
             | reinstalled | util-linux |

    .. code-block:: gherkin

       Scenario: Detect exact version
           When I save rpmdb
            And I successfully run "dnf -y update util-linux"
           Then rpmdb changes are
             | State   | Packages          |
             | updated | util-linux/2.29.0 |

    .. _automatic rules:

    **Automatic rules which are additionally applied**:

      - Packages except listed in table must not appear/disappear
      - Packages except listed in table classified as *unchanged*
    """
    ctx.assertion.assertIsNotNone(ctx.rpmdb, "Save rpmdb before comparison")
    table = table_utils.parse_kv_table(ctx, HEADINGS_RPMDB, rpm_utils.State)
    ctx.wipe_rpmdb = True
    rpmdb = rpm_utils.get_rpmdb()
    problems = []

    def unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post):
        problems.append("Package {pkg!r} was supposed to be "
                        "{expected_state!r}, but has been {state!r} "
                        "({pkg_pre!r} -> {pkg_post!r})".format(
                            pkg=pkg,
                            state=state.value,
                            expected_state=expected_state.value,
                            pkg_pre=rpm_utils.hdr2nevra(pkg_pre),
                            pkg_post=rpm_utils.hdr2nevra(pkg_post)))

    def pkgs_split(pkgs):
        for pkg in pkgs.split(","):
            yield pkg.strip()

    # Let's check what user has requested in table
    ignore_list = ""
    for expected_state, packages in table.items():
        if expected_state == rpm_utils.State.ignored:
            ignore_list = packages
        else:
            for pkg in pkgs_split(packages):
                pkg_pre = rpm_utils.find_pkg(ctx.rpmdb, pkg, only_by_name=True)
                if pkg_pre:
                    ctx.rpmdb.remove(pkg_pre)
                pkg_post = rpm_utils.find_pkg(rpmdb, pkg)
                if pkg_post:
                    rpmdb.remove(pkg_post)
                state = rpm_utils.analyze_state(pkg_pre, pkg_post)
                if state != expected_state:
                    if state == State.unchanged and expected_state == State.reinstalled:
                        # workaround for unchanged rpmdb timestamp
                        text = getattr(ctx.cmd_result, 'stdout')
                        if "Reinstalling     : {}".format(pkg) in text:
                            continue
                    unexpected_state(pkg, state, expected_state, pkg_pre,
                                     pkg_post)

    # Now exclude packages matching regexp pattern in the ignore_list
    def filter_rpmdb(pkgs, filters):  # remove packages matching any filter
        remove = []
        for pkg in pkgs:
            for f in filters:
                if f and fnmatch.fnmatchcase(pkg.name, f):
                    remove.append(pkg)
                    break  # no need to process additional filters
        for pkg in remove:
            pkgs.remove(pkg)

    filter_rpmdb(rpmdb, list(pkgs_split(ignore_list)))
    filter_rpmdb(ctx.rpmdb, list(pkgs_split(ignore_list)))

    # Let's check if NEVRAs are still same
    def rpmdb2nevra(rpmdb):
        for hdr in rpmdb:
            yield rpm_utils.hdr2nevra(hdr)

    six.assertCountEqual(ctx.assertion, rpmdb2nevra(ctx.rpmdb),
                         rpmdb2nevra(rpmdb))

    # Even if we have same NEVRAs packages can be different or reinstalled
    for pkg_pre, pkg_post in zip(ctx.rpmdb, rpmdb):
        state = rpm_utils.analyze_state(pkg_pre, pkg_post)
        expected_state = rpm_utils.State.unchanged
        # At this point pkg_pre and pkg_post should have same name
        pkg = pkg_pre["name"].decode()
        if state != expected_state:
            unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post)

    assert not problems, "\n{!s}".format("\n".join(problems))
def step_rpmdb_changes_are(ctx):
    """
    Compare saved by :ref:`When I save rpmdb` and current rpmdb's.

    Requires table with following headers:

    ======= ==========
     State   Packages 
    ======= ==========

    *State* is state of package

    ============ ============== ============= ===============================
       State      rpmdb before   rpmdb after        Additional comments      
    ============ ============== ============= ===============================
    installed    Not installed  Installed     Package has been installed     
    removed      Installed      Not installed Package has been removed       
    absent       Not installed  Not installed Package has not been installed 
    unchanged    Installed      Installed     Package was not changed        
    reinstalled  Installed      Installed     Same packages was reinstalled  
    updated      Installed      Installed     Package has been updated       
    downgraded   Installed      Installed     Package has been downgraded    
    ignored          -              -         Package will be ignored        
    ============ ============== ============= ===============================

    For each *State* you can specify multiple *Packages* which are separated
    by comma.

    For the *ignored* state you can use Unix shell-style wildcard to cover
    multiple package names. Packages with state explicitely stated won't be
    ignored even if they matches pattern.

    Examples:

    .. code-block:: gherkin

       Scenario: Detect reinstalled package
           When I save rpmdb
            And I successfully run "dnf -y reinstall util-linux"
           Then rpmdb changes are
             | State       | Packages   |
             | reinstalled | util-linux |

    .. code-block:: gherkin

       Scenario: Detect exact version
           When I save rpmdb
            And I successfully run "dnf -y update util-linux"
           Then rpmdb changes are
             | State   | Packages          |
             | updated | util-linux/2.29.0 |

    .. _automatic rules:

    **Automatic rules which are additionally applied**:

      - Packages except listed in table must not appear/disappear
      - Packages except listed in table classified as *unchanged*
    """
    ctx.assertion.assertIsNotNone(ctx.rpmdb, "Save rpmdb before comparison")
    table = table_utils.parse_kv_table(ctx, HEADINGS_RPMDB, rpm_utils.State)
    ctx.wipe_rpmdb = True
    rpmdb = rpm_utils.get_rpmdb()
    problems = []

    def unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post):
        problems.append("Package {pkg!r} was supposed to be "
                        "{expected_state!r}, but has been {state!r} "
                        "({pkg_pre!r} -> {pkg_post!r})".format(
                            pkg=pkg, state=state.value,
                            expected_state=expected_state.value,
                            pkg_pre=rpm_utils.hdr2nevra(pkg_pre),
                            pkg_post=rpm_utils.hdr2nevra(pkg_post)))

    def pkgs_split(pkgs):
        for pkg in pkgs.split(","):
            yield pkg.strip()
    # Let's check what user has requested in table
    ignore_list = ""
    for expected_state, packages in table.items():
        if expected_state == rpm_utils.State.ignored:
            ignore_list = packages
        else:
            for pkg in pkgs_split(packages):
                pkg_pre = rpm_utils.find_pkg(ctx.rpmdb, pkg, only_by_name=True)
                if pkg_pre and rpm_utils.is_installonly_pkg(pkg_pre): # installonly package should match NVR
                    pkg_pre = rpm_utils.find_pkg(ctx.rpmdb, pkg, only_by_name=False)
                if pkg_pre:
                    ctx.rpmdb.remove(pkg_pre)
                pkg_post = rpm_utils.find_pkg(rpmdb, pkg)
                if pkg_post:
                    rpmdb.remove(pkg_post)
                state = rpm_utils.analyze_state(pkg_pre, pkg_post)
                if state != expected_state:
                    if state == State.unchanged and expected_state == State.reinstalled:
                        # workaround for unchanged rpmdb timestamp
                        text = getattr(ctx.cmd_result, 'stdout')
                        if "Reinstalling     : {}".format(pkg) in text:
                            continue
                    unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post)

    # Now exclude packages matching regexp pattern in the ignore_list
    def filter_rpmdb(pkgs, filters):  # remove packages matching any filter
        remove = []
        for pkg in pkgs:
            for f in filters:
                if f and fnmatch.fnmatchcase(pkg.name, f):
                    remove.append(pkg)
                    break  # no need to process additional filters
        for pkg in remove:
            pkgs.remove(pkg)
    filter_rpmdb(rpmdb, list(pkgs_split(ignore_list)))
    filter_rpmdb(ctx.rpmdb, list(pkgs_split(ignore_list)))

    # Let's check if NEVRAs are still same
    def rpmdb2nevra(rpmdb):
        for hdr in rpmdb:
            yield rpm_utils.hdr2nevra(hdr)
    six.assertCountEqual(ctx.assertion,
                         rpmdb2nevra(ctx.rpmdb),
                         rpmdb2nevra(rpmdb))

    # Even if we have same NEVRAs packages can be different or reinstalled
    for pkg_pre, pkg_post in zip(ctx.rpmdb, rpmdb):
        state = rpm_utils.analyze_state(pkg_pre, pkg_post)
        expected_state = rpm_utils.State.unchanged
        # At this point pkg_pre and pkg_post should have same name
        pkg = pkg_pre["name"].decode()
        if state != expected_state:
            unexpected_state(pkg, state, expected_state, pkg_pre, pkg_post)

    assert not problems, "\n{!s}".format("\n".join(problems))
def step_gpg_key(ctx, name_real):
    """
    Generates for the root user GPG key with a given identity,
    a.k.a. the Name-Real attribute.

    GPG key attributes can be optionally specified using the table with
    following headers:

    ======= =========
      Tag     Value  
    ======= =========

    Supported GPG key attrubutes are:

    ============= ===============
        Tag       Default value  
    ============= ===============
    Key-Type      RSA            
    Key-Length    2048           
    Subkey-Type   <not present>  
    Subkey-Length <not present>  
    Name-Comment  No Comment     
    Name-Email    dnf@noreply    
    Expire-Date   0              
    =============================

    .. note::
       GPG key configuration is saved in a file /root/${Name-Real}.keyconf
       respective public key is exported to a file /root/${Name-Real}.pubkey

    Examples:

    .. code-block:: gherkin

       Feature: Package signatures

         Scenario: Setup repository with signed packages
           Given GPG key "James Bond"
             And GPG key "James Bond" imported in rpm database
             And repository "TestRepo" with packages signed by "James Bond"
               | Package | Tag | Value |
               | TestA   |     |       |
    """

    if ctx.table:  # additional GPG key configuration listed in the table
        GPGKEY_HEADINGS = ['Tag', 'Value']
        GPGKEY_TAGS = ['Key-Type', 'Key-Length', 'Subkey-Type', 'Subkey-Length', 'Name-Comment', 'Name-Email', 'Expire-Date']
        gpgkey_conf_table = table_utils.parse_kv_table(ctx, GPGKEY_HEADINGS, GPGKEY_TAGS)
    else:  # no table present
        gpgkey_conf_table = {}
    template = JINJA_ENV.from_string(GPGKEY_CONF_TMPL)
    settings = {k.lower().replace('-', '_'): v for k, v in gpgkey_conf_table.items()}
    gpgkey_conf = template.render(name_real=name_real, **settings)
    # write gpgkey configuration to a file
    fpath = GPGKEY_FILEPATH_TMPL.format(name_real, "keyconf")
    with open(fpath, 'w') as fw:
        fw.write(gpgkey_conf)
    # generate the GPG key
    gpgbin = which("gpg2")
    cmd = "{!s} --batch --gen-key '{!s}'".format(gpgbin, fpath)
    step_i_successfully_run_command(ctx, cmd)
    # export the public key
    cmd = "{!s} --export --armor '{!s}'".format(gpgbin, name_real)
    step_i_successfully_run_command(ctx, cmd)
    fpath = GPGKEY_FILEPATH_TMPL.format(name_real, "pubkey")
    with open(fpath, 'w') as fw:
        fw.write(ctx.cmd_result.stdout)
Example #10
0
def step_gpg_key(ctx, name_real):
    """
    Generates for the root user GPG key with a given identity,
    a.k.a. the Name-Real attribute.

    GPG key attributes can be optionally specified using the table with
    following headers:

    ======= =========
      Tag     Value  
    ======= =========

    Supported GPG key attrubutes are:

    ============= ===============
        Tag       Default value  
    ============= ===============
    Key-Type      RSA            
    Key-Length    2048           
    Subkey-Type   <not present>  
    Subkey-Length <not present>  
    Name-Comment  No Comment     
    Name-Email    dnf@noreply    
    Expire-Date   0              
    =============================

    .. note::
       GPG key configuration is saved in a file /root/${Name-Real}.keyconf
       respective public key is exported to a file /root/${Name-Real}.pubkey

    Examples:

    .. code-block:: gherkin

       Feature: Package signatures

         Scenario: Setup repository with signed packages
           Given GPG key "James Bond"
             And GPG key "James Bond" imported in rpm database
             And repository "TestRepo" with packages signed by "James Bond"
               | Package | Tag | Value |
               | TestA   |     |       |
    """

    if ctx.table:  # additional GPG key configuration listed in the table
        GPGKEY_HEADINGS = ['Tag', 'Value']
        GPGKEY_TAGS = [
            'Key-Type', 'Key-Length', 'Subkey-Type', 'Subkey-Length',
            'Name-Comment', 'Name-Email', 'Expire-Date'
        ]
        gpgkey_conf_table = table_utils.parse_kv_table(ctx, GPGKEY_HEADINGS,
                                                       GPGKEY_TAGS)
    else:  # no table present
        gpgkey_conf_table = {}
    template = JINJA_ENV.from_string(GPGKEY_CONF_TMPL)
    settings = {
        k.lower().replace('-', '_'): v
        for k, v in gpgkey_conf_table.items()
    }
    gpgkey_conf = template.render(name_real=name_real, **settings)
    # write gpgkey configuration to a file
    fpath = GPGKEY_FILEPATH_TMPL.format(name_real, "keyconf")
    with open(fpath, 'w') as fw:
        fw.write(gpgkey_conf)
    # generate the GPG key
    gpgbin = which("gpg2")
    cmd = "{!s} --batch --gen-key '{!s}'".format(gpgbin, fpath)
    step_i_successfully_run_command(ctx, cmd)
    # export the public key
    cmd = "{!s} --export --armor '{!s}'".format(gpgbin, name_real)
    step_i_successfully_run_command(ctx, cmd)
    fpath = GPGKEY_FILEPATH_TMPL.format(name_real, "pubkey")
    with open(fpath, 'w') as fw:
        fw.write(ctx.cmd_result.stdout)