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

Add support to mirror non package installer files #680

Merged
merged 9 commits into from
Sep 27, 2018

Conversation

sliverc
Copy link
Contributor

@sliverc sliverc commented Nov 27, 2017

Fixes #304
Fixes #240

Description of the Change

This PR introduces new -with-installer flag for mirror create. When updating and publishing mirror it will include installer files.

After analysis of Debian and Ubuntu repositories following rules are applied for this to work:

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 27, 2017

Documentation at aptly-dev/www.aptly.info#58

@sliverc sliverc force-pushed the with_installer branch 2 times, most recently from 7553741 to 08de6af Compare December 1, 2017 08:43
@sliverc sliverc force-pushed the with_installer branch 2 times, most recently from 00d0f3d to 95d76de Compare December 18, 2017 10:05
@gittygoo
Copy link

Great feature, lets bring it to production

@hsitter hsitter added 1.4.0 and removed 1.3.0 labels Apr 30, 2018
@sliverc sliverc force-pushed the with_installer branch 2 times, most recently from 56e63ec to 2f212dd Compare May 17, 2018 12:07
@codecov
Copy link

codecov bot commented May 17, 2018

Codecov Report

Merging #680 into master will decrease coverage by 0.04%.
The diff coverage is 66.08%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #680      +/-   ##
==========================================
- Coverage   64.13%   64.08%   -0.05%     
==========================================
  Files          50       50              
  Lines        6329     6446     +117     
==========================================
+ Hits         4059     4131      +72     
- Misses       1776     1810      +34     
- Partials      494      505      +11
Impacted Files Coverage Δ
http/compression.go 86.11% <0%> (ø) ⬆️
http/http.go 50% <0%> (-50%) ⬇️
swift/public.go 59.37% <100%> (ø) ⬆️
deb/changes.go 59.74% <100%> (ø) ⬆️
files/public.go 78.62% <100%> (+0.16%) ⬆️
s3/public.go 59.22% <100%> (ø) ⬆️
deb/deb.go 60.83% <100%> (ø) ⬆️
deb/index_files.go 43.26% <50%> (+0.28%) ⬆️
deb/remote.go 62.74% <60.37%> (-1.37%) ⬇️
deb/publish.go 63.48% <61.9%> (-0.33%) ⬇️
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ec57d17...d1b2814. Read the comment docs.

@sliverc sliverc requested a review from a team May 17, 2018 12:27
@sliverc
Copy link
Contributor Author

sliverc commented May 17, 2018

@apachelogger I have rebased this PR to current master. Could you review it? Thanks.

@hsitter
Copy link
Contributor

hsitter commented May 18, 2018

First I'll have to read up installer files again, it's been ages since I last dealt with them xD

I'll try to get it done today.

Copy link
Contributor

@hsitter hsitter left a comment

Choose a reason for hiding this comment

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

It bothers me greatly that the installer metadata is so very randomly put together and doesn't even have proper documentation 😒

https://wiki.debian.org/DebianInstaller/NetbootMetadata proposes a proper format and is a 10 year old page. So I have zero hope for this getting any less awkward in the future.
Anyway, nothing we can do much about unfortunately.

I didn't quite get through everything, and I won't get it to it before Tuesday. So, if @smira wants to review meanwhile I'd have no problem with that.

Do we want to support installer data from our side as well? i.e. on a !mirror repo, should you be able to add installer stuff? I kinda think yes, but then I also don't really care 😉. A cheap way to support this might be via the proposed #473 actually, not sure if we need to do anything to facilitate that though.

The PR does generally look alright. I have a particular gripe with the change in files/public.go though and would like some background info on that + adjustments to s3/swift.

Lastly, iff the remote had detatched signatures on the SUMS files I think we also need to detach the signatures on the SUMS files. From some quick research I did, the entire structure and content of the installer-* directories is entirely dependent on the debian-installer version at hand (in fact, udeb.list apparently changed its format at some point even). So, to actually have this mirrored reliably I think the actual signing specifics need to get repliacted as well.

deb/remote.go Outdated
if err != nil {
return err
if _, ok := err.(*http.NoCandidateFoundError); isInstaller && ok {
// checking of gpg file is only needed when checksums matches are required.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/of/if

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@@ -123,10 +123,11 @@ func (storage *PublishedStorage) RemoveDirs(path string, progress aptly.Progress
// sourcePath is a relative path to package file in package pool
//
// LinkFromPool returns relative path for the published file to be included in package index
func (storage *PublishedStorage) LinkFromPool(publishedDirectory, baseName string, sourcePool aptly.PackagePool,
func (storage *PublishedStorage) LinkFromPool(publishedDirectory, fileName string, sourcePool aptly.PackagePool,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this actually related?

It's missing a unit test.
It also seems inconsistent with s3 and swift, both still call it baseName.
Talking about s3 and swift, do they need changing (other than that the var name should be the same)?

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 my intention was to keep directory & file name (without any paths) as separate args, as directory might need to be created. I'm not sure what we get if we allow paths in baseName

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Up to now the files in the published folder were flat but with installer files can be nested.

The only difference is that creating of directories needs to be handled differently which this changes addresses here. For s3/swift there is no difference as directory creation does not matter there.

I have adjusted all LinkFromPool params in s3/swift to be named fileName to clarify that it can contain slashes (even though implementation doesn't change). Also added a test so this is actually proven.

}

// NewControlFileReader creates ControlFileReader, it wraps with buffering
func NewControlFileReader(r io.Reader) *ControlFileReader {
func NewControlFileReader(r io.Reader, isRelease, isInstaller bool) *ControlFileReader {
Copy link
Contributor

Choose a reason for hiding this comment

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

So, I am not sure how iditomatic this is, but I feel something like

const (
        IsRelease = iota
        IsInstaller = 1 << iota
)

used like NewControlFileReader(reader, IsInstaller | IsRelease) would be vastly easier to read than the distinctly unexpressive NewControlFileReader(reader, true, false).

That said, I've never tried anything like that, so I couldn't say how well this works in practise.

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 agree that this would be more readable in this certain case. But issue is that flags (meaning whether it is a release, source or installer package) are currently stored as boolean on the level database and therefore simply forwarded e.g. to WriteTo. Simply adjusting this in NewControlFileReader but leaving it in all other cases would make the code inconsistent.

As mentioned above I think we should think about refactoring the code how package index types are handled, to simplify this and potentially also store information of a package as flags. However I think this is out of scope for this PR.

scanner *bufio.Scanner
scanner *bufio.Scanner
isRelease bool
isInstaller bool
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you didn't write a new reader for the installer metadata? They aren't really deb822 let alone control files, so it seems a bit odd to run them through the control reader.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we want to make its own reader type for installer package files it would still need to implement ReadStanza but this would be odd as well as it doesn't have any sections.

So instead to not complicate the code (especially DownloadPackageIndex) I handle the file as it would be a control file without any sections. This avoids duplication of code.

To be honest though I think there are too many if/else all over the code in terms of package index type. I think such should be avoided by implementing proper types but this I think is out of scope for this PR.

@smira
Copy link
Contributor

smira commented May 18, 2018

I would agree with @apachelogger in the sense that if we support installer, we should support it everywhere, including local repos. I'm not that familiar with this thing to understand what do we actually need to support on our side to make it work properly.

@@ -130,6 +130,8 @@ type Downloader interface {
DownloadWithChecksum(ctx context.Context, url string, destination string, expected *utils.ChecksumInfo, ignoreMismatch bool, maxTries int) error
// GetProgress returns Progress object
GetProgress() Progress
// GetLength of given url
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 it should be better to say 'GetLength returns size by heading object with url` ?

It's not len(url) ;)

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

deb/publish.go Outdated
for _, arch := range p.Architectures {
if pkg.MatchesArchitecture(arch) {
matches = true
hadUdebs = hadUdebs || pkg.IsUdeb
err = pkg.LinkFromPool(publishedStorage, packagePool, p.Prefix, p.Distribution, component, arch, forceOverwrite)
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like overkill to call it len(p.Arhitectures) times if package is not installer package, as each call does Stat for local fs and for S3 it's even more involved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not quite sure what you mean. Only LinkFromPool actually accesses storage. But on line 595 there is still a break, so LinkFromPool is only called once.

Could you elaborate a bit more what actually does the Stat here which it didn't before? For me it looks the same just simply the if inlined... but maybe I am overlooking something.

deb/package.go Outdated
@@ -576,6 +621,9 @@ func (p *Package) LinkFromPool(publishedStorage aptly.PublishedStorage, packageP
}

relPath := filepath.Join("pool", component, poolDir)
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 build relPath outside of LinkFromPool so that we don't have to pass all the params?

e.g. publish.go could have had correct logic for it, or we can make a method of Package which returns correct "pool" path depending on package type?

Something like LinkFromPool(publishedStorage, packagePool, relPath, force) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair point. I have adjusted it so only a relPath is passed on. I kept prefix though as this is handled the same way in all cases.

@sliverc
Copy link
Contributor Author

sliverc commented May 22, 2018

For completeness aptly now also creates a detached signature of the installer hash sum file when publishing. This way we should be on the safe side for the installer to work no matter what version.

All other questions and reviews points I should have addressed (see discussion comments), otherwise let me know if there is anything still unclear.

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, 👍

one thing which might be good for the future work is to add support for installer file handling in local repos (adding them from local filesystem)

@sliverc
Copy link
Contributor Author

sliverc commented May 28, 2018

@smira Thanks. Agree that it would be a great addition to add installer files in local repos for the future.

@apachelogger How does it look to you now? (I am not able to merge it even though @smira Accepeted as there are still requesting changes)

Additionally I have added some more unit test to fix codecov checks.

@sliverc sliverc force-pushed the with_installer branch 3 times, most recently from 9b331ae to 768db88 Compare June 18, 2018 07:24
@sliverc sliverc added this to the 1.4.0 milestone Jun 19, 2018
@sliverc
Copy link
Contributor Author

sliverc commented Jun 19, 2018

@apachelogger
Do you think you have time to review your requested changes? Even though @smira has accepted, merge is blocked till all reviews are accepted.

I would like to update my other PRs once this is merged. If you do not have any time you can also consider dismissing your review. Thanks.

@gittygoo
Copy link

Can we get this merged? we are desperately needing it :(

@sliverc sliverc dismissed hsitter’s stale review September 27, 2018 07:49

As this has been hanging around for quite a while I am merging this PR as of accpeted review of smira. In case there are still comments, we can always follow up on them later. Just let me know.

@sliverc sliverc merged commit 702c1ff into aptly-dev:master Sep 27, 2018
@sliverc sliverc deleted the with_installer branch September 27, 2018 07:50
sliverc added a commit to aptly-dev/www.aptly.info that referenced this pull request Sep 27, 2018
@sathieu
Copy link

sathieu commented Jan 22, 2019

I know it's late in buster release cycle, but:

Is there any chance to release a new aptly version to have this feature in Debian buster?

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.

5 participants