mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-07-26 13:47:40 +00:00
Add support to mirror non package installer files
This commit is contained in:
+84
-21
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user