Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect zipped symlinks #1140

Merged
merged 73 commits into from
Jul 26, 2019
Merged

Respect zipped symlinks #1140

merged 73 commits into from
Jul 26, 2019

Conversation

bubba-h57
Copy link
Contributor

Issue #878 :

Description of challenge:
SAM CLI currently used the Lib/zipfile.py from the Python Standard Library. Unfortunately, that library has not been kept up to date with the .ZIP File Format Specification and while it does handle basic archival CRUD, there are a number of features that have become standard and which it does not support.

The greatest interest to us is that of properly handling symbolic links. It can neither archive them properly (see #477) nor can it extract them properly. This is particularly important now that we are compiling libraries for custom layers. Given the limited file space available to Lambda Functions, having /libs/*.so files all copied instead of symlinked exponentially increases the uncompressed layer size.

Lambda itself handles the archived symlinks properly; however, attempting to test the same layers with sam local fails. This forces fat layers if the developer desires to use 'sam local'

Description of changes:
The unzip() function in samcli/local/lambdafn/zip.py is modified to identify and properly handle any symlinks. The Standard zipfile Library continues to do all of the heavy work with a wrapper around it to handle the identification and extraction of the zipfiles. Regular files and directories continue to be extracted in precisely the same manner as before. All changes are documented with appropriate docblocks.

tests/unit/local/lambdafn/test_zip.py had to be modified in order to insert a symlink into the test archive as well as testing that the symlink was properly extracted. I did not see any integration nor functional tests that needed modification.

Checklist:

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

sanathkr and others added 30 commits November 29, 2018 12:44
chore: Version bump SAM CLI to 0.14.1 (#1082)
@bubba-h57
Copy link
Contributor Author

@sanathkr Rebased and ready. Thanks for reviewing it!

Copy link
Contributor

@jfuss jfuss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bubba-h57 This looks good over all. Just two small comments.

Additional question:

A response regarding whether the ZipInfo defines a symlink or not.
"""

return (file_info.external_attr >> 28) == 0xA
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be using the S_IFLNK constant from above?

Why not use stat. S_IFLNK here instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not looking at a file on the filesystem. It is looking at a number of bytes in the file_info entry, the External Attributes for the file. See The zip format's external file attribute If you want to dig into it. But the short answer is because it isn't a file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. You made a constant S_IFLNK = 0xA above. Can you either remove it the constant or replace the 0xA here with S_IFLNK. Otherwise, it looks like an unused constant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ that was with regard to pythons stat.S_ISLNK() ... I have no good excuse for not comparing to the S_IFLNK = 0xA constant defined directly above the function. :-)


# If the link already exists, delete it or symlink() fails
if os.path.lexists(link_name):
os.remove(link_name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this have any (negative) side effects? I can't think of any at the moment but asking the question to spark a discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it fairly extensively and can not think of any negative side effects that might pop up. The unzip intends to overwrite anything that is there regardless ... we will simply delete it prior to writing.

@jfuss jfuss self-assigned this Jul 25, 2019
@bubba-h57
Copy link
Contributor Author

We did indeed test it to solve #878 ... that issue was the whole point of interest for us. :-)

@jfuss
Copy link
Contributor

jfuss commented Jul 25, 2019

We did indeed test it to solve #878 ... that issue was the whole point of interest for us. :-)

WOOT! I just wanted to make sure. If you didn't, I was going to pull down and verify (mainly why I was asking).

@bubba-h57
Copy link
Contributor Author

Well, I'm all for you testing it also. It has been a while since I looked it.

@jfuss jfuss changed the base branch from develop to candidate/release/20 July 26, 2019 15:10
@jfuss jfuss merged commit ad9a171 into aws:candidate/release/20 Jul 26, 2019
jfuss added a commit that referenced this pull request Aug 7, 2019
@jfuss
Copy link
Contributor

jfuss commented Aug 7, 2019

I ended up needing to revert this. Details can be found here. We will need to revisit the implementation and either way for the Py2.7 to be depreciated or update this to not work on Py2.7 in windows.

jfuss added a commit to jfuss/aws-sam-cli that referenced this pull request Apr 15, 2020
This reverts commit 360d90a.

This commit originally reverted aws#1140 due to os.symlink not being
available on windows in Python2.7 stdlib, details here: aws#1315 (comment). We recently removed Python2.7 support in aws#1416, so this commit
is a revert of the revert, with some additional black formating to make `make pr`
pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants