# Buggy code
def gen_thin(cachedir, extra_mods="", overwrite=False, so_mods=""):
    """
    Generate the salt-thin tarball and print the location of the tarball
    Optional additional mods to include (e.g. mako) can be supplied as a comma
    delimited string.  Permits forcing an overwrite of the output file as well.

    CLI Example:

    .. code-block:: bash

        salt-run thin.generate
        salt-run thin.generate mako
        salt-run thin.generate mako,wempy 1
        salt-run thin.generate overwrite=1
    """
    thindir = os.path.join(cachedir, "thin")
    if not os.path.isdir(thindir):
        os.makedirs(thindir)
    thintar = os.path.join(thindir, "thin.tgz")
    thinver = os.path.join(thindir, "version")
    salt_call = os.path.join(thindir, "salt-call")
    with open(salt_call, "w+") as fp_:
        fp_.write(SALTCALL)
    if os.path.isfile(thintar):
        if overwrite or not os.path.isfile(thinver):
            os.remove(thintar)
        elif open(thinver).read() == salt.__version__:
            return thintar
    tops = [
        os.path.dirname(salt.__file__),
        os.path.dirname(jinja2.__file__),
        os.path.dirname(yaml.__file__),
        os.path.dirname(requests.__file__),
    ]
    if HAS_MSGPACK:
        tops.append(os.path.dirname(msgpack.__file__))

    if HAS_URLLIB3:
        tops.append(os.path.dirname(urllib3.__file__))

    if HAS_SIX:
        tops.append(six.__file__.replace(".pyc", ".py"))

    if HAS_CHARDET:
        tops.append(os.path.dirname(chardet.__file__))

    for mod in [m for m in extra_mods.split(",") if m]:
        if mod not in locals() and mod not in globals():
            try:
                locals()[mod] = __import__(mod)
                moddir, modname = os.path.split(locals()[mod].__file__)
                base, ext = os.path.splitext(modname)
                if base == "__init__":
                    tops.append(moddir)
                else:
                    tops.append(os.path.join(moddir, base + ".py"))
            except ImportError:
                # Not entirely sure this is the right thing, but the only
                # options seem to be 1) fail, 2) spew errors, or 3) pass.
                # Nothing else in here spits errors, and the markupsafe code
                # doesn't bail on import failure, so I followed that lead.
                # And of course, any other failure still S/T's.
                pass
    for mod in [m for m in so_mods.split(",") if m]:
        try:
            locals()[mod] = __import__(mod)
            tops.append(locals()[mod].__file__)
        except ImportError:
            pass  # As per comment above
    if HAS_MARKUPSAFE:
        tops.append(os.path.dirname(markupsafe.__file__))
    tfp = tarfile.open(thintar, "w:gz", dereference=True)
    start_dir = os.getcwd()
    tempdir = None
    for top in tops:
        base = os.path.basename(top)
        top_dirname = os.path.dirname(top)
        if os.path.isdir(top_dirname):
            os.chdir(top_dirname)
        else:
            # This is likely a compressed python .egg
            tempdir = tempfile.mkdtemp()
            egg = zipfile.ZipFile(top_dirname)
            egg.extractall(tempdir)
            top = os.path.join(tempdir, base)
            os.chdir(tempdir)
        if not os.path.isdir(top):
            # top is a single file module
            tfp.add(base)
            continue
        for root, dirs, files in os.walk(base):
            for name in files:
                if not name.endswith((".pyc", ".pyo")):
                    tfp.add(os.path.join(root, name))
        if tempdir is not None:
            shutil.rmtree(tempdir)
            tempdir = None
    os.chdir(thindir)
    tfp.add("salt-call")
    with open(thinver, "w+") as fp_:
        fp_.write(salt.__version__)
    os.chdir(os.path.dirname(thinver))
    tfp.add("version")
    os.chdir(start_dir)
    tfp.close()
    return thintar


# Traceback (IOError)
Process Process-8:
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python2.7/dist-packages/salt/client/ssh/__init__.py", line 315, in handle_routine
stdout, stderr, retcode = single.run()
File "/usr/lib/python2.7/dist-packages/salt/client/ssh/__init__.py", line 630, in run
stdout = self.run_wfunc()
File "/usr/lib/python2.7/dist-packages/salt/client/ssh/__init__.py", line 675, in run_wfunc
opts_pkg = pre_wrapper['test.opts_pkg']()
File "/usr/lib/python2.7/dist-packages/salt/client/ssh/wrapper/__init__.py", line 62, in caller
stdout, stderr, _ = single.cmd_block()
File "/usr/lib/python2.7/dist-packages/salt/client/ssh/__init__.py", line 818, in cmd_block
cmd_str = self._cmd_str()
File "/usr/lib/python2.7/dist-packages/salt/client/ssh/__init__.py", line 755, in _cmd_str
thin_sum = salt.utils.thin.thin_sum(cachedir, 'sha1')
File "/usr/lib/python2.7/dist-packages/salt/utils/thin.py", line 182, in thin_sum
thintar = gen_thin(cachedir)
File "/usr/lib/python2.7/dist-packages/salt/utils/thin.py", line 172, in gen_thin
tfp.add('version')
File "/usr/lib/python2.7/tarfile.py", line 1995, in add
self.addfile(tarinfo, f)
File "/usr/lib/python2.7/tarfile.py", line 2024, in addfile
copyfileobj(fileobj, self.fileobj, tarinfo.size)
File "/usr/lib/python2.7/tarfile.py", line 279, in copyfileobj
raise IOError("end of file reached")
IOError: end of file reached

Traceback (most recent call last):
File "./install.py", line 415, in <module>
for output in run():
File "./install.py", line 331, in run
for output in bootstrap('*'):
File "./install.py", line 181, in bootstrap
yield check_output(['salt-ssh', minion_id, 'state.sls', 'bootstrap'])
File "/usr/lib/python2.7/subprocess.py", line 573, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['salt-ssh', '*', 'state.sls', 'bootstrap']' returned non-zero exit status -15

# Fixed code
def gen_thin(cachedir, extra_mods="", overwrite=False, so_mods=""):
    """
    Generate the salt-thin tarball and print the location of the tarball
    Optional additional mods to include (e.g. mako) can be supplied as a comma
    delimited string.  Permits forcing an overwrite of the output file as well.

    CLI Example:

    .. code-block:: bash

        salt-run thin.generate
        salt-run thin.generate mako
        salt-run thin.generate mako,wempy 1
        salt-run thin.generate overwrite=1
    """
    thindir = os.path.join(cachedir, "thin")
    if not os.path.isdir(thindir):
        os.makedirs(thindir)
    thintar = os.path.join(thindir, "thin.tgz")
    thinver = os.path.join(thindir, "version")
    salt_call = os.path.join(thindir, "salt-call")
    with open(salt_call, "w+") as fp_:
        fp_.write(SALTCALL)
    if os.path.isfile(thintar):
        if overwrite or not os.path.isfile(thinver):
            try:
                os.remove(thintar)
            except OSError:
                pass
        elif open(thinver).read() == salt.__version__:
            return thintar
    tops = [
        os.path.dirname(salt.__file__),
        os.path.dirname(jinja2.__file__),
        os.path.dirname(yaml.__file__),
        os.path.dirname(requests.__file__),
    ]
    if HAS_MSGPACK:
        tops.append(os.path.dirname(msgpack.__file__))

    if HAS_URLLIB3:
        tops.append(os.path.dirname(urllib3.__file__))

    if HAS_SIX:
        tops.append(six.__file__.replace(".pyc", ".py"))

    if HAS_CHARDET:
        tops.append(os.path.dirname(chardet.__file__))

    for mod in [m for m in extra_mods.split(",") if m]:
        if mod not in locals() and mod not in globals():
            try:
                locals()[mod] = __import__(mod)
                moddir, modname = os.path.split(locals()[mod].__file__)
                base, ext = os.path.splitext(modname)
                if base == "__init__":
                    tops.append(moddir)
                else:
                    tops.append(os.path.join(moddir, base + ".py"))
            except ImportError:
                # Not entirely sure this is the right thing, but the only
                # options seem to be 1) fail, 2) spew errors, or 3) pass.
                # Nothing else in here spits errors, and the markupsafe code
                # doesn't bail on import failure, so I followed that lead.
                # And of course, any other failure still S/T's.
                pass
    for mod in [m for m in so_mods.split(",") if m]:
        try:
            locals()[mod] = __import__(mod)
            tops.append(locals()[mod].__file__)
        except ImportError:
            pass  # As per comment above
    if HAS_MARKUPSAFE:
        tops.append(os.path.dirname(markupsafe.__file__))
    tfp = tarfile.open(thintar, "w:gz", dereference=True)
    start_dir = os.getcwd()
    tempdir = None
    for top in tops:
        base = os.path.basename(top)
        top_dirname = os.path.dirname(top)
        if os.path.isdir(top_dirname):
            os.chdir(top_dirname)
        else:
            # This is likely a compressed python .egg
            tempdir = tempfile.mkdtemp()
            egg = zipfile.ZipFile(top_dirname)
            egg.extractall(tempdir)
            top = os.path.join(tempdir, base)
            os.chdir(tempdir)
        if not os.path.isdir(top):
            # top is a single file module
            tfp.add(base)
            continue
        for root, dirs, files in os.walk(base):
            for name in files:
                if not name.endswith((".pyc", ".pyo")):
                    tfp.add(os.path.join(root, name))
        if tempdir is not None:
            shutil.rmtree(tempdir)
            tempdir = None
    os.chdir(thindir)
    tfp.add("salt-call")
    with open(thinver, "w+") as fp_:
        fp_.write(salt.__version__)
    os.chdir(os.path.dirname(thinver))
    tfp.add("version")
    os.chdir(start_dir)
    tfp.close()
    return thintar