Add support to mirror non package installer files

This commit is contained in:
Oliver Sauder
2017-11-23 14:22:41 +01:00
parent 9a704de43b
commit 108b0ea226
35 changed files with 593 additions and 153 deletions
+84 -21
View File
@@ -68,6 +68,8 @@ type RemoteRepo struct {
DownloadSources bool
// Should we download .udebs?
DownloadUdebs bool
// Should we download installer files?
DownloadInstaller bool
// "Snapshot" of current list of packages
packageRefs *PackageRefList
// Parsed archived root
@@ -78,16 +80,17 @@ type RemoteRepo struct {
// NewRemoteRepo creates new instance of Debian remote repository with specified params
func NewRemoteRepo(name string, archiveRoot string, distribution string, components []string,
architectures []string, downloadSources bool, downloadUdebs bool) (*RemoteRepo, error) {
architectures []string, downloadSources bool, downloadUdebs bool, downloadInstaller bool) (*RemoteRepo, error) {
result := &RemoteRepo{
UUID: uuid.New(),
Name: name,
ArchiveRoot: archiveRoot,
Distribution: distribution,
Components: components,
Architectures: architectures,
DownloadSources: downloadSources,
DownloadUdebs: downloadUdebs,
UUID: uuid.New(),
Name: name,
ArchiveRoot: archiveRoot,
Distribution: distribution,
Components: components,
Architectures: architectures,
DownloadSources: downloadSources,
DownloadUdebs: downloadUdebs,
DownloadInstaller: downloadInstaller,
}
err := result.prepare()
@@ -140,6 +143,9 @@ func (repo *RemoteRepo) String() string {
if repo.DownloadUdebs {
srcFlag += " [udeb]"
}
if repo.DownloadInstaller {
srcFlag += " [installer]"
}
distribution := repo.Distribution
if distribution == "" {
distribution = "./"
@@ -243,6 +249,12 @@ func (repo *RemoteRepo) UdebPath(component string, architecture string) string {
return fmt.Sprintf("%s/debian-installer/binary-%s/Packages", component, architecture)
}
// InstallerPath returns path of Packages files for given component and
// architecture
func (repo *RemoteRepo) InstallerPath(component string, architecture string) string {
return fmt.Sprintf("%s/installer-%s/current/images/SHA256SUMS", component, architecture)
}
// PackageURL returns URL of package file relative to repository root
// architecture
func (repo *RemoteRepo) PackageURL(filename string) *url.URL {
@@ -311,8 +323,8 @@ ok:
defer release.Close()
sreader := NewControlFileReader(release)
stanza, err := sreader.ReadStanza(true)
sreader := NewControlFileReader(release, true, false)
stanza, err := sreader.ReadStanza()
if err != nil {
return err
}
@@ -409,7 +421,7 @@ ok:
}
// DownloadPackageIndexes downloads & parses package index files
func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.Downloader, collectionFactory *CollectionFactory,
func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.Downloader, verifier pgp.Verifier, collectionFactory *CollectionFactory,
ignoreMismatch bool, maxTries int) error {
if repo.packageList != nil {
panic("packageList != nil")
@@ -420,39 +432,85 @@ func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.
packagesPaths := [][]string{}
if repo.IsFlat() {
packagesPaths = append(packagesPaths, []string{repo.FlatBinaryPath(), PackageTypeBinary})
packagesPaths = append(packagesPaths, []string{repo.FlatBinaryPath(), PackageTypeBinary, "", ""})
if repo.DownloadSources {
packagesPaths = append(packagesPaths, []string{repo.FlatSourcesPath(), PackageTypeSource})
packagesPaths = append(packagesPaths, []string{repo.FlatSourcesPath(), PackageTypeSource, "", ""})
}
} else {
for _, component := range repo.Components {
for _, architecture := range repo.Architectures {
packagesPaths = append(packagesPaths, []string{repo.BinaryPath(component, architecture), PackageTypeBinary})
packagesPaths = append(packagesPaths, []string{repo.BinaryPath(component, architecture), PackageTypeBinary, component, architecture})
if repo.DownloadUdebs {
packagesPaths = append(packagesPaths, []string{repo.UdebPath(component, architecture), PackageTypeUdeb})
packagesPaths = append(packagesPaths, []string{repo.UdebPath(component, architecture), PackageTypeUdeb, component, architecture})
}
if repo.DownloadInstaller {
packagesPaths = append(packagesPaths, []string{repo.InstallerPath(component, architecture), PackageTypeInstaller, component, architecture})
}
}
if repo.DownloadSources {
packagesPaths = append(packagesPaths, []string{repo.SourcesPath(component), PackageTypeSource})
packagesPaths = append(packagesPaths, []string{repo.SourcesPath(component), PackageTypeSource, component, "source"})
}
}
}
for _, info := range packagesPaths {
path, kind := info[0], info[1]
path, kind, component, architecture := info[0], info[1], info[2], info[3]
packagesReader, packagesFile, err := http.DownloadTryCompression(gocontext.TODO(), d, repo.IndexesRootURL(), path, repo.ReleaseFiles, ignoreMismatch, maxTries)
isInstaller := kind == PackageTypeInstaller
if err != nil {
return err
if _, ok := err.(*http.NoCandidateFoundError); isInstaller && ok {
// checking of gpg file is only needed when checksums matches are required.
// otherwise there actually has been no candidate found and we can continue
if ignoreMismatch {
continue
}
// some repos do not have installer hashsum file listed in release file but provide a separate gpg file
hashsumPath := repo.IndexesRootURL().ResolveReference(&url.URL{Path: path}).String()
packagesFile, err = http.DownloadTemp(gocontext.TODO(), d, hashsumPath)
if err != nil {
if herr, ok := err.(*http.Error); ok && (herr.Code == 404 || herr.Code == 403) {
// installer files are not available in all components and architectures
// so ignore it if not found
continue
}
return err
}
if verifier != nil {
hashsumGpgPath := repo.IndexesRootURL().ResolveReference(&url.URL{Path: path + ".gpg"}).String()
var filesig *os.File
filesig, err = http.DownloadTemp(gocontext.TODO(), d, hashsumGpgPath)
if err != nil {
return err
}
err = verifier.VerifyDetachedSignature(filesig, packagesFile, false)
if err != nil {
return err
}
_, err = packagesFile.Seek(0, 0)
}
packagesReader = packagesFile
}
if err != nil {
return err
}
}
defer packagesFile.Close()
stat, _ := packagesFile.Stat()
progress.InitBar(stat.Size(), true)
sreader := NewControlFileReader(packagesReader)
sreader := NewControlFileReader(packagesReader, false, isInstaller)
for {
stanza, err := sreader.ReadStanza(false)
stanza, err := sreader.ReadStanza()
if err != nil {
return err
}
@@ -474,6 +532,11 @@ func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.
if err != nil {
return err
}
} else if kind == PackageTypeInstaller {
p, err = NewInstallerPackageFromControlFile(stanza, repo, component, architecture, d)
if err != nil {
return err
}
}
err = repo.packageList.Add(p)
if err != nil {