diff --git a/contrib/config/luet.yaml b/contrib/config/luet.yaml index 9699e55c..9738e725 100644 --- a/contrib/config/luet.yaml +++ b/contrib/config/luet.yaml @@ -103,7 +103,7 @@ # urls: # - https://mydomain.local/luet/repo1 # -# authentication: +# auth: # Define Basic authentication header # basic: "mybasicauth" # Define token authentication header diff --git a/pkg/installer/client/http.go b/pkg/installer/client/http.go index 5ce0ba51..95dae4bd 100644 --- a/pkg/installer/client/http.go +++ b/pkg/installer/client/http.go @@ -16,7 +16,9 @@ package client import ( + "fmt" "io/ioutil" + "math" "net/url" "os" "path" @@ -38,8 +40,34 @@ func NewHttpClient(r RepoData) *HttpClient { return &HttpClient{RepoData: r} } +func (c *HttpClient) PrepareReq(dst, url string) (*grab.Request, error) { + + req, err := grab.NewRequest(dst, url) + if err != nil { + return nil, err + } + + if val, ok := c.RepoData.Authentication["token"]; ok { + req.HTTPRequest.Header.Set("Authorization", "token "+val) + } else if val, ok := c.RepoData.Authentication["basic"]; ok { + req.HTTPRequest.Header.Set("Authorization", "Basic "+val) + } + + return req, err +} + +func Round(input float64) float64 { + if input < 0 { + return math.Ceil(input - 0.5) + } + return math.Floor(input + 0.5) +} + func (c *HttpClient) DownloadArtifact(artifact compiler.Artifact) (compiler.Artifact, error) { var u *url.URL = nil + var err error + var req *grab.Request + var temp string artifactName := path.Base(artifact.GetPath()) cacheFile := filepath.Join(helpers.GetSystemPkgsCacheDirPath(), artifactName) @@ -50,12 +78,14 @@ func (c *HttpClient) DownloadArtifact(artifact compiler.Artifact) (compiler.Arti Info("Use artifact", artifactName, "from cache.") } else { - temp, err := ioutil.TempDir(os.TempDir(), "tree") + temp, err = ioutil.TempDir(os.TempDir(), "tree") if err != nil { return nil, err } defer os.RemoveAll(temp) + client := grab.NewClient() + for _, uri := range c.RepoData.Urls { Info("Downloading artifact", artifactName, "from", uri) @@ -65,11 +95,20 @@ func (c *HttpClient) DownloadArtifact(artifact compiler.Artifact) (compiler.Arti } u.Path = path.Join(u.Path, artifactName) - _, err = grab.Get(temp, u.String()) + req, err = c.PrepareReq(temp, u.String()) if err != nil { continue } + resp := client.Do(req) + if err = resp.Err(); err != nil { + continue + } + + Info("Downloaded", artifactName, "of", + fmt.Sprintf("%.2f", (float64(resp.BytesComplete())/1000)/1000), "MB (", + fmt.Sprintf("%.2f", (float64(resp.BytesPerSecond())/1024)/1024), "MiB/s )") + Debug("Copying file ", filepath.Join(temp, artifactName), "to", cacheFile) err = helpers.CopyFile(filepath.Join(temp, artifactName), cacheFile) if err != nil { @@ -93,19 +132,26 @@ func (c *HttpClient) DownloadArtifact(artifact compiler.Artifact) (compiler.Arti func (c *HttpClient) DownloadFile(name string) (string, error) { var file *os.File = nil var u *url.URL = nil + var err error + var req *grab.Request + var temp string + ok := false - temp, err := ioutil.TempDir(os.TempDir(), "tree") + temp, err = ioutil.TempDir(os.TempDir(), "tree") if err != nil { return "", err } + client := grab.NewClient() + for _, uri := range c.RepoData.Urls { file, err = ioutil.TempFile(os.TempDir(), "HttpClient") if err != nil { continue } + u, err = url.Parse(uri) if err != nil { continue @@ -114,11 +160,20 @@ func (c *HttpClient) DownloadFile(name string) (string, error) { Info("Downloading", u.String()) - _, err = grab.Get(temp, u.String()) + req, err = c.PrepareReq(temp, u.String()) if err != nil { continue } + resp := client.Do(req) + if err = resp.Err(); err != nil { + continue + } + + Info("Downloaded", filepath.Base(resp.Filename), "of", + fmt.Sprintf("%.2f", (float64(resp.BytesComplete())/1000)/1000), "MB (", + fmt.Sprintf("%.2f", (float64(resp.BytesPerSecond())/1024)/1024), "MiB/s )") + err = helpers.CopyFile(filepath.Join(temp, name), file.Name()) if err != nil { continue diff --git a/pkg/installer/client/interface.go b/pkg/installer/client/interface.go index 1d142b3c..89bdc752 100644 --- a/pkg/installer/client/interface.go +++ b/pkg/installer/client/interface.go @@ -16,5 +16,6 @@ package client type RepoData struct { - Urls []string + Urls []string + Authentication map[string]string } diff --git a/pkg/installer/installer.go b/pkg/installer/installer.go index 27b65724..6876dc07 100644 --- a/pkg/installer/installer.go +++ b/pkg/installer/installer.go @@ -285,6 +285,9 @@ func (l *LuetInstaller) Install(cp []pkg.Package, s *System) error { func (l *LuetInstaller) installPackage(a ArtifactMatch, s *System) error { artifact, err := a.Repository.Client().DownloadArtifact(a.Artifact) + if err != nil { + return errors.Wrap(err, "Error on download artifact") + } err = artifact.Verify() if err != nil { diff --git a/pkg/installer/interface.go b/pkg/installer/interface.go index a11f6db4..c9912dee 100644 --- a/pkg/installer/interface.go +++ b/pkg/installer/interface.go @@ -53,6 +53,8 @@ type Repository interface { SetTreePath(string) GetType() string SetType(string) + SetAuthentication(map[string]string) + GetAuthentication() map[string]string GetRevision() int IncrementRevision() GetLastUpdate() string diff --git a/pkg/installer/repository.go b/pkg/installer/repository.go index d0887002..6ba7533c 100644 --- a/pkg/installer/repository.go +++ b/pkg/installer/repository.go @@ -174,6 +174,10 @@ func (r *LuetSystemRepository) GetDescription() string { return r.LuetRepository.Description } +func (r *LuetSystemRepository) GetAuthentication() map[string]string { + return r.LuetRepository.Authentication +} + func (r *LuetSystemRepository) GetTreeCompressionType() compiler.CompressionImplementation { return r.TreeCompressionType } @@ -224,16 +228,20 @@ func (r *LuetSystemRepository) GetTree() tree.Builder { return r.Tree } func (r *LuetSystemRepository) GetRevision() int { - return r.Revision + return r.LuetRepository.Revision } func (r *LuetSystemRepository) GetLastUpdate() string { - return r.LastUpdate + return r.LuetRepository.LastUpdate } func (r *LuetSystemRepository) SetLastUpdate(u string) { - r.LastUpdate = u + r.LuetRepository.LastUpdate = u } func (r *LuetSystemRepository) IncrementRevision() { - r.Revision++ + r.LuetRepository.Revision++ +} + +func (r *LuetSystemRepository) SetAuthentication(auth map[string]string) { + r.LuetRepository.Authentication = auth } func (r *LuetSystemRepository) ReadSpecFile(file string, removeFile bool) (Repository, error) { @@ -327,7 +335,11 @@ func (r *LuetSystemRepository) Client() Client { case "disk": return client.NewLocalClient(client.RepoData{Urls: r.GetUrls()}) case "http": - return client.NewHttpClient(client.RepoData{Urls: r.GetUrls()}) + return client.NewHttpClient( + client.RepoData{ + Urls: r.GetUrls(), + Authentication: r.GetAuthentication(), + }) } return nil @@ -440,6 +452,7 @@ func (r *LuetSystemRepository) Sync(force bool) (Repository, error) { repo.SetTree(reciper) repo.SetTreePath(treefs) repo.SetUrls(r.GetUrls()) + repo.SetAuthentication(r.GetAuthentication()) return repo, nil }