func (repo *RemoteRepo) ReleaseURL(name string) *url.URL {
	return repo.IndexesRootURL().ResolveReference(&url.URL{Path: name})
}
ReleaseURL returns URL to Release* files in repo root
package deb
import (
	"bytes"
	gocontext "context"
	"errors"
	"fmt"
	"log"
	"net/url"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"
	"github.com/aptly-dev/aptly/aptly"
	"github.com/aptly-dev/aptly/database"
	"github.com/aptly-dev/aptly/http"
	"github.com/aptly-dev/aptly/pgp"
	"github.com/aptly-dev/aptly/utils"
	"github.com/pborman/uuid"
	"github.com/ugorji/go/codec"
)
const (
	MirrorIdle = iota
	MirrorUpdating
)
type RemoteRepo struct {
	UUID string
	Name string
	ArchiveRoot string
	Distribution string
	Components []string
	Architectures []string
	Meta Stanza
	LastDownloadDate time.Time
	ReleaseFiles map[string]utils.ChecksumInfo `json:"-"`  
	Filter string
	Status int
	WorkerPID int
	FilterWithDeps bool
	SkipComponentCheck bool
	SkipArchitectureCheck bool
	DownloadSources bool
	DownloadUdebs bool
	DownloadInstaller bool
	Packages []string `codec:"-" json:",omitempty"`
	packageRefs *PackageRefList
	archiveRootURL *url.URL
	packageList *PackageList
}
func NewRemoteRepo(name string, archiveRoot string, distribution string, components []string,
	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,
		DownloadInstaller: downloadInstaller,
	}
	err := result.prepare()
	if err != nil {
		return nil, err
	}
	if strings.HasSuffix(result.Distribution, "/") || strings.HasPrefix(result.Distribution, ".") {
		if !strings.HasPrefix(result.Distribution, ".") {
			result.Distribution = "./" + result.Distribution
		}
		result.Architectures = nil
		if len(result.Components) > 0 {
			return nil, fmt.Errorf("components aren't supported for flat repos")
		}
		if result.DownloadUdebs {
			return nil, fmt.Errorf("debian-installer udebs aren't supported for flat repos")
		}
		result.Components = nil
	}
	return result, nil
}
func (repo *RemoteRepo) SetArchiveRoot(archiveRoot string) {
	repo.ArchiveRoot = archiveRoot
	repo.prepare()
}
func (repo *RemoteRepo) prepare() error {
	var err error
	if !strings.HasSuffix(repo.ArchiveRoot, "/") {
		repo.ArchiveRoot = repo.ArchiveRoot + "/"
	}
	repo.archiveRootURL, err = url.Parse(repo.ArchiveRoot)
	return err
}
func (repo *RemoteRepo) String() string {
	srcFlag := ""
	if repo.DownloadSources {
		srcFlag += " [src]"
	}
	if repo.DownloadUdebs {
		srcFlag += " [udeb]"
	}
	if repo.DownloadInstaller {
		srcFlag += " [installer]"
	}
	distribution := repo.Distribution
	if distribution == "" {
		distribution = "./"
	}
	return fmt.Sprintf("[%s]: %s %s%s", repo.Name, repo.ArchiveRoot, distribution, srcFlag)
}
func (repo *RemoteRepo) IsFlat() bool {
	return repo.Distribution == "" || (strings.HasPrefix(repo.Distribution, ".") && strings.HasSuffix(repo.Distribution, "/"))
}
func (repo *RemoteRepo) NumPackages() int {
	if repo.packageRefs == nil {
		return 0
	}
	return repo.packageRefs.Len()
}
func (repo *RemoteRepo) RefList() *PackageRefList {
	return repo.packageRefs
}
func (repo *RemoteRepo) MarkAsUpdating() {
	repo.Status = MirrorUpdating
	repo.WorkerPID = os.Getpid()
}
func (repo *RemoteRepo) MarkAsIdle() {
	repo.Status = MirrorIdle
	repo.WorkerPID = 0
}
func (repo *RemoteRepo) CheckLock() error {
	if repo.Status == MirrorIdle || repo.WorkerPID == 0 {
		return nil
	}
	p, err := os.FindProcess(repo.WorkerPID)
	if err != nil {
		return nil
	}
	err = p.Signal(syscall.Signal(0))
	if err == nil {
		return fmt.Errorf("mirror is locked by update operation, PID %d", repo.WorkerPID)
	}
	return nil
}
func (repo *RemoteRepo) IndexesRootURL() *url.URL {
	var path *url.URL
	if !repo.IsFlat() {
		path = &url.URL{Path: fmt.Sprintf("dists/%s/", repo.Distribution)}
	} else {
		path = &url.URL{Path: repo.Distribution}
	}
	return repo.archiveRootURL.ResolveReference(path)
}