def get_os_codename_package(package, fatal=True):
    '''Derive OpenStack release codename from an installed package.'''

    if snap_install_requested():
        cmd = ['snap', 'list', package]
        try:
            out = subprocess.check_output(cmd)
            if six.PY3:
                out = out.decode('UTF-8')
        except subprocess.CalledProcessError:
            return None
        lines = out.split('\n')
        for line in lines:
            if package in line:
                # Second item in list is Version
                return line.split()[1]

    import apt_pkg as apt

    cache = apt_cache()

    try:
        pkg = cache[package]
    except Exception:
        if not fatal:
            return None
        # the package is unknown to the current apt cache.
        e = 'Could not determine version of package with no installation '\
            'candidate: %s' % package
        error_out(e)

    if not pkg.current_ver:
        if not fatal:
            return None
        # package is known, but no version is currently installed.
        e = 'Could not determine version of uninstalled package: %s' % package
        error_out(e)

    vers = apt.upstream_version(pkg.current_ver.ver_str)
    if 'swift' in pkg.name:
        # Fully x.y.z match for swift versions
        match = re.match(r'^(\d+)\.(\d+)\.(\d+)', vers)
    else:
        # x.y match only for 20XX.X
        # and ignore patch level for other packages
        match = re.match(r'^(\d+)\.(\d+)', vers)

    if match:
        vers = match.group(0)

    # Generate a major version number for newer semantic
    # versions of openstack projects
    major_vers = vers.split('.')[0]
    # >= Liberty independent project versions
    if (package in PACKAGE_CODENAMES and
            major_vers in PACKAGE_CODENAMES[package]):
        return PACKAGE_CODENAMES[package][major_vers]
    else:
        # < Liberty co-ordinated project versions
        try:
            if 'swift' in pkg.name:
                return get_swift_codename(vers)
            else:
                return OPENSTACK_CODENAMES[vers]
        except KeyError:
            if not fatal:
                return None
            e = 'Could not determine OpenStack codename for version %s' % vers
            error_out(e)
Derive OpenStack release codename from an installed package.