# Buggy code
def _smartos_zone_pkgsrc_data():
    """
    SmartOS zone pkgsrc information
    """
    # Provides:
    #   pkgsrcversion
    #   pkgsrcpath

    grains = {
        "pkgsrcversion": "Unknown",
        "pkgsrcpath": "Unknown",
    }

    pkgsrcversion = re.compile("^release:\\s(.+)")
    if os.path.isfile("/etc/pkgsrc_version"):
        with salt.utils.files.fopen("/etc/pkgsrc_version", "r") as fp_:
            for line in fp_:
                line = salt.utils.stringutils.to_unicode(line)
                match = pkgsrcversion.match(line)
                if match:
                    grains["pkgsrcversion"] = match.group(1)

    pkgsrcpath = re.compile("PKG_PATH=(.+)")
    if os.path.isfile("/opt/local/etc/pkg_install.conf"):
        with salt.utils.files.fopen("/opt/local/etc/pkg_install.conf", "r") as fp_:
            for line in fp_:
                line = salt.utils.stringutils.to_unicode(line)
                match = pkgsrcpath.match(line)
                if match:
                    grains["pkgsrcpath"] = match.group(1)

    return grains


# Traceback (ValueError)
# salt-call grains.items
[WARNING ] /opt/tools/lib/python3.7/site-packages/salt/loader.py:772: DeprecationWarning: dist() and linux_distribution() functions are deprecated in Python 3.5
ret = funcs[key]()

[WARNING ] /opt/tools/lib/python3.7/site-packages/salt/utils/path.py:265: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
if not isinstance(exes, collections.Iterable):

[CRITICAL] Failed to load grains defined in grain file mdata.mdata in function <function mdata at 0x3a658f8>, error:
Traceback (most recent call last):
File "/opt/tools/lib/python3.7/site-packages/salt/loader.py", line 798, in grains
ret = funcs[key](**kwargs)
File "/opt/tools/lib/python3.7/site-packages/salt/grains/mdata.py", line 160, in mdata
grains = salt.utils.dictupdate.update(grains, _user_mdata(mdata_list, mdata_get), merge_lists=True)
File "/opt/tools/lib/python3.7/site-packages/salt/grains/mdata.py", line 66, in _user_mdata
mdata_value = __salt__['cmd.run']('{0} {1}'.format(mdata_get, mdata_grain), ignore_retcode=True)
File "/opt/tools/lib/python3.7/site-packages/salt/modules/cmdmod.py", line 1167, in run
**kwargs)
File "/opt/tools/lib/python3.7/site-packages/salt/modules/cmdmod.py", line 633, in _run
cmd = salt.utils.args.shlex_split(cmd)
File "/opt/tools/lib/python3.7/site-packages/salt/utils/args.py", line 295, in shlex_split
shlex.split(salt.utils.stringutils.to_str(s), **kwargs)
File "/opt/tools/lib/python3.7/shlex.py", line 305, in split
return list(lex)
File "/opt/tools/lib/python3.7/shlex.py", line 295, in __next__
token = self.get_token()
File "/opt/tools/lib/python3.7/shlex.py", line 105, in get_token
raw = self.read_token()
File "/opt/tools/lib/python3.7/shlex.py", line 187, in read_token
raise ValueError("No closing quotation")
ValueError: No closing quotation
local:
----------
cpu_flags:
- fsgsbase
- avx2
- fma
- bmi2
- bmi1
- rdrand
- f16c
- vmx
- avx
- xsave
- pclmulqdq
- aes
- movbe
- sse4.2
- sse4.1
- ssse3
- amd_lzcnt
- popcnt
- tscp
- cx16
- sse3
- sse2
- sse
- fxsr
- mmx
- cmov
- amd_sysc
- cx8
- tsc
- fpu
cpu_model:
Intel(r) Xeon(r) CPU E5-2670 v3 @ 2.30GHz
cpuarch:
amd64
gid:
0
gpus:
groupname:
root
host:
smartos2
hwaddr_interfaces:
----------
e1000g0:
00:50:56:b7:b9:58
zone_net0:
02:08:20:41:2a:70
imageversion:
Unknown
kernel:
SunOS
kernelrelease:
5.11
kernelversion:
joyent_20190703T233036Z
locale_info:
----------
defaultencoding:
UTF-8
defaultlanguage:
el_GR
detectedencoding:
UTF-8

master:
salt
mem_total:
16383
num_cpus:
4
num_gpus:
0
os:
SmartOS
os_family:
Solaris
osarch:
amd64
osfinger:
SmartOS-2019
osfullname:
SmartOS
osmajorrelease:
2019
osrelease:
2019.07.03
osrelease_info:
- 2019
- 7
- 3
osrelease_stamp:
20190703T233036Z
path:
/opt/tools/sbin:/opt/tools/bin:/usr/bin:/usr/sbin:/smartdc/bin:/opt/smartdc/bin:/opt/local/bin:/opt/local/sbin:/opt/tools/bin:/opt/tools/sbin:/opt/smartdc/agents/bin
pid:
15009
pkgin_repositories:
pkgsrcpath:
Unknown
pkgsrcversion:
Unknown
ps:
/usr/ucb/ps auxwww
pythonexecutable:
/opt/tools/bin/python3.7
pythonpath:
- /opt/tools/bin
- /opt/tools/lib/python37.zip
- /opt/tools/lib/python3.7
- /opt/tools/lib/python3.7/lib-dynload
- /opt/tools/lib/python3.7/site-packages
pythonversion:
- 3
- 7
- 3
- final
- 0
saltpath:
/opt/tools/lib/python3.7/site-packages/salt
saltversion:
2019.2.0
saltversioninfo:
- 2019
- 2
- 0
- 0
shell:
/usr/bin/bash
swap_total:
30297
uid:
0
username:
root
virtual:
VMware
zfs_feature_flags:
True
zfs_support:
True
zmqversion:
4.3.1
zoneid:
0
1
zonename:
global
zpool:
----------
zones:
154618822656

# Fixed code
def _smartos_zone_pkgsrc_data():
    """
    SmartOS zone pkgsrc information
    """
    # Provides:
    #   pkgsrcversion
    #   pkgsrcpath

    grains = {
        "pkgsrcversion": "Unknown",
        "pkgsrcpath": "Unknown",
    }

    # NOTE: we are specifically interested in the SmartOS pkgsrc version and path
    #       - PKG_PATH MAY be different on non-SmartOS systems, but they will not
    #         use this grains module.
    #       - A sysadmin with advanced needs COULD create a 'spin' with a totally
    #         different URL. But at that point the value would be meaning less in
    #         the context of the pkgsrcversion grain as it will not followed the
    #         SmartOS pkgsrc versioning. So 'Unknown' would be appropriate.
    pkgsrcpath = re.compile("PKG_PATH=(.+)")
    pkgsrcversion = re.compile(
        "^https?://pkgsrc.joyent.com/packages/SmartOS/(.+)/(.+)/All$"
    )
    pkg_install_paths = [
        "/opt/local/etc/pkg_install.conf",
        "/opt/tools/etc/pkg_install.conf",
    ]
    for pkg_install in pkg_install_paths:
        if os.path.isfile(pkg_install):
            with salt.utils.files.fopen(pkg_install, "r") as fp_:
                for line in fp_:
                    line = salt.utils.stringutils.to_unicode(line)
                    match_pkgsrcpath = pkgsrcpath.match(line)
                    if match_pkgsrcpath:
                        grains["pkgsrcpath"] = match_pkgsrcpath.group(1)
                        match_pkgsrcversion = pkgsrcversion.match(
                            match_pkgsrcpath.group(1)
                        )
                        if match_pkgsrcversion:
                            grains["pkgsrcversion"] = match_pkgsrcversion.group(1)
                        break

    return grains