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

Support Acquire-By-Hash for index files #664

Merged
merged 15 commits into from
Nov 30, 2017

Conversation

sliverc
Copy link
Contributor

@sliverc sliverc commented Nov 2, 2017

Fixes #536

Description of the Change

This follows up on #551 beside small fixes adds following:

  • Add s3 and swift support
  • Add tests
  • Rename of option to -acquire-by-hash for consistency with other flags

Checklist

  • unit-test added (if change is algorithm)
  • functional test added/updated (if change is functional)
  • man page updated (if applicable)
  • bash completion updated (if applicable)
  • documentation updated
  • author name in AUTHORS

@sliverc
Copy link
Contributor Author

sliverc commented Nov 2, 2017

Added documentation in PR aptly-dev/www.aptly.info#55

@@ -499,7 +499,7 @@ _aptly()
"snapshot"|"repo")
if [[ $numargs -eq 0 ]]; then
if [[ "$cur" == -* ]]; then
COMPREPLY=($(compgen -W "-batch -force-overwrite -distribution= -component= -gpg-key= -keyring= -label= -origin= -notautomatic= -butautomaticupgrades= -passphrase= -passphrase-file= -secret-keyring= -skip-contents -skip-signing" -- ${cur}))
COMPREPLY=($(compgen -W "-batch -force-overwrite -distribution= -component= -gpg-key= -keyring= -label= -origin= -notautomatic= -butautomaticupgrades= -passphrase= -passphrase-file= -secret-keyring= -skip-contents -skip-signing -acquire-by-hash" -- ${cur}))
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please keep options sorted here, so that it's easier to find if something is there in the list or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Make sense. There were some other options which were not in order either so reordered whole list.

Copy link
Contributor

@smira smira left a comment

Choose a reason for hiding this comment

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

This looks like really awesome work, thanks!

I left some comments which are more or less small nits

hashs := []string{}
if file.acquireByHash {
hashs = append(hashs, "MD5Sum", "SHA1", "SHA256", "SHA512")
for _, hash := range hashs {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be straight for _, hash := range []string{"MD5Sum", "SHA1", ....} {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

if file.acquireByHash {
sums := file.parent.generatedFiles[file.relativePath+ext]

err = packageIndexByHash(file, ext, "SHA512", sums.SHA512)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can rewrite this in a loop similar line 107?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used map to accomplish this.


err = packageIndexByHash(file, ext, "SHA512", sums.SHA512)
if err != nil {
fmt.Printf("%s\n", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

We should return an error here? Unless we want to ignore some errors (I would prefer error to be returned)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree. Changed.

files/public.go Outdated

// FileExists returns true if path exists
func (storage *PublishedStorage) FileExists(path string) bool {
list, err := storage.Filelist(filepath.Dir(path))
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we use os.Lstat (https://godoc.org/os#Lstat) + os.IsNotExist (https://godoc.org/os#IsNotExist) here? Listing directory seems to be really resource-consuming for this simple task?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Definitely. Changed as suggested.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There were also some unit tests missing which I added now.

s3/public.go Outdated

params := &s3.CopyObjectInput{
Bucket: aws.String(storage.bucket),
CopySource: aws.String(src),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to do filepath.Join(storage.prefix, src) here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

s3/public.go Outdated
Key: aws.String(filepath.Join(storage.prefix, path)),
}
_, err := storage.s3.HeadObject(params)
return err == nil
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should distinguish "not found" error vs. some other AWS error (which would be an error, and it's better for FileExists to return bool, error here)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Make sense. Adjusted interface and also implemented difference between file existence and error in other storage types as well.

@sliverc sliverc force-pushed the acquire-by-hash branch 2 times, most recently from 1b9b9bf to 46cce5a Compare November 21, 2017 11:04
@sliverc
Copy link
Contributor Author

sliverc commented Nov 21, 2017

@smira Adjusted PR according to your comments. Let me know if there is anything else.

neolynx and others added 15 commits November 30, 2017 09:46
The added "aptly publish repo" option "-access-by-hash" publishes
the index files (Packages*, Sources*) also as hardlinked hashes.
Example:
 /dists/yakkety/main/binary-amd64/by-hash/SHA512/31833ec39acc...
The Release files indicate this with the option "Acquire-By-Hash: yes"

This is used by apt >= 1.2.0 and prevents the "Hash sum mismatch" race
condition between a server side "aptly publish repo" and "apt-get update"
on a client.
See: http://www.chiark.greenend.org.uk/~cjwatson/blog/no-more-hash-sum-mismatch-errors.html

This implementation uses symlinks in the by-hash/*/ directory for keeping
only two versions of the index files and deleting older files
automatically.

Note: this only works with aptly.FileSystemPublishedStorage

Closes: aptly-dev#536

Signed-off-by: André Roth <neolynx@gmail.com>
Signed-off-by: André Roth <neolynx@gmail.com>
This makes it easier maintainable.
Copy link
Contributor

@smira smira left a comment

Choose a reason for hiding this comment

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

thanks, this looks good to me!

I was a bit concerned at first with index and index.old symlinks, but they seem to work perfectly fine!

@smira smira merged commit 565fcf4 into aptly-dev:master Nov 30, 2017
@erickeller
Copy link

Great news... Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for Acquire-by-hash feature of APT 1.2.0
4 participants