首页 > 代码库 > saltstack在解压zip文件时保留原始修改时间的方法

saltstack在解压zip文件时保留原始修改时间的方法

  saltstack在使用archive.unzip功能时,会将压缩包中文件的“修改时间”替换为当前解压的系统时间,为了能够保留文件原来的“修改时间”,需要对salt-manion的源码中archive.py文件的unzip方法进行修改:

文件位置:

  windows    C:/salt/bin/Lib/site-packages/salt/modules/archive.py

  linux:    /user/lib/python2.7/site-packages/salt/modules/archive.py

修改思路:

  解压的原理是遍历每个压缩包的文件并存放在给定目录,所以我们在遍历的时候要从元信息中获取原来文件的修改时间old_modify_time,并将解压后文件的修改时间改为modify_time。

  修改unzip方法为如下:(注意这次的修改只适用于我的应用场景,读者可以根据自己的需求个性化定制,原理都一样)

def unzip(zip_file,
          dest,
          excludes=None,
          options=None,
          template=None,
          runas=None,
          trim_output=False,
          password=None,
          extract_perms=True):

    if not excludes:
        excludes = []
    if runas:
        euid = os.geteuid()
        egid = os.getegid()
        uinfo = __salt__[user.info](runas)
        if not uinfo:
            raise SaltInvocationError(
                "User ‘{0}‘ does not exist".format(runas)
            )

    zip_file, dest = _render_filenames(zip_file, dest, None, template)

    if runas and (euid != uinfo[uid] or egid != uinfo[gid]):
        # Change the egid first, as changing it after the euid will fail
        # if the runas user is non-privileged.
        os.setegid(uinfo[gid])
        os.seteuid(uinfo[uid])

    try:
        exc = None
        # Define cleaned_files here so that an exception will not prevent this
        # variable from being defined and cause a NameError in the return
        # statement at the end of the function.
        cleaned_files = []
        with contextlib.closing(zipfile.ZipFile(zip_file, "r")) as zfile:
            # 旧方法修改文件的修改时间
            if True:
                files = zfile.namelist()
                cleaned_files.extend([x for x in files if x not in excludes])
                for file in zfile.infolist():
                    d = file.date_time#修改时间元信息
                    gettime = "%s/%s/%s %s:%s" % (d[0], d[1], d[2], d[3], d[4])
                    zfile.extract(file, dest, password)#解压
                    filep = os.path.join(dest, file.filename)
                    print "recover:%s modify time" % filep
                    timearry = time.mktime(time.strptime(gettime, ‘%Y/%m/%d %H:%M‘))
                    os.utime(filep, (timearry, timearry))#替换时间
            else:
                files = zfile.namelist()

                if isinstance(excludes, string_types):
                    excludes = [x.strip() for x in excludes.split(,)]
                elif isinstance(excludes, (float, integer_types)):
                    excludes = [str(excludes)]

                cleaned_files.extend([x for x in files if x not in excludes])
                for target in cleaned_files:
                    if target not in excludes:
                        if salt.utils.is_windows() is False:
                            info = zfile.getinfo(target)
                            # Check if zipped file is a symbolic link
                            if stat.S_ISLNK(info.external_attr >> 16):
                                source = zfile.read(target)
                                os.symlink(source, os.path.join(dest, target))
                                continue
                        zfile.extract(target, dest, password)

                        modify_date = zfile.getinfo(target).date_time
                        gettime = "%s/%s/%s %s:%s" % (modify_date[0], modify_date[1], modify_date[2], modify_date[3], modify_date[4])
                        file_path = os.path.join(dest, target)
                        timearry = time.mktime(time.strptime(gettime, %Y/%m/%d %H:%M))
                        os.utime(file_path, (timearry, timearry))

                        if extract_perms:
                            perm = zfile.getinfo(target).external_attr >> 16
                            if perm == 0:
                                umask_ = os.umask(0)
                                os.umask(umask_)
                                if target.endswith(/):
                                    perm = 0o777 & ~umask_
                                else:
                                    perm = 0o666 & ~umask_
                            os.chmod(os.path.join(dest, target), perm)
    except Exception as exc:
        pass
    finally:
        # Restore the euid/egid
        if runas:
            os.seteuid(euid)
            os.setegid(egid)
        if exc is not None:
            # Wait to raise the exception until euid/egid are restored to avoid
            # permission errors in writing to minion log.
            raise CommandExecutionError(
                Exception encountered unpacking zipfile: {0}.format(exc)
            )

    return _trim_files(cleaned_files, trim_output)

 

saltstack在解压zip文件时保留原始修改时间的方法