diff --git a/cmd/repo.go b/cmd/repo.go index 2f9742ed..c6ba6f75 100644 --- a/cmd/repo.go +++ b/cmd/repo.go @@ -31,6 +31,8 @@ func init() { RootCmd.AddCommand(repoGroupCmd) repoGroupCmd.AddCommand( + NewRepoAddCommand(), + NewRepoGetCommand(), NewRepoListCommand(), NewRepoUpdateCommand(), ) diff --git a/cmd/repo/add.go b/cmd/repo/add.go new file mode 100644 index 00000000..d217ceb6 --- /dev/null +++ b/cmd/repo/add.go @@ -0,0 +1,137 @@ +// Copyright © 2022 Ettore Di Giacinto +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + +package cmd_repo + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/ghodss/yaml" + "github.com/mudler/luet/cmd/util" + "github.com/mudler/luet/pkg/api/core/types" + "github.com/mudler/luet/pkg/helpers" + + "github.com/spf13/cobra" +) + +func NewRepoAddCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "add [OPTIONS] https://..../something.yaml /local/file.yaml", + Short: "Add a repository to the system", + Args: cobra.ExactArgs(1), + Long: ` +Adds a repository to the system. URLs, local files or inline repo can be specified, examples: + +# URL/File: + + luet repo add /path/to/file + + luet repo add https://.... + + luet repo add ... --name "foo" + +# Inline: + + luet repo add testfo --description "Bar" --url "FOZZ" --type "ff" + + `, + Run: func(cmd *cobra.Command, args []string) { + + uri := args[0] + d, _ := cmd.Flags().GetString("dir") + yes, _ := cmd.Flags().GetBool("yes") + + desc, _ := cmd.Flags().GetString("description") + t, _ := cmd.Flags().GetString("type") + url, _ := cmd.Flags().GetString("url") + ref, _ := cmd.Flags().GetString("reference") + prio, _ := cmd.Flags().GetInt("priority") + + if len(util.DefaultContext.Config.RepositoriesConfDir) == 0 && d == "" { + util.DefaultContext.Fatal("No repository dirs defined") + return + } + if d == "" { + d = util.DefaultContext.Config.RepositoriesConfDir[0] + } + + var r *types.LuetRepository + str, err := helpers.GetURI(uri) + if err != nil { + r = &types.LuetRepository{ + Enable: true, + Cached: true, + Name: uri, + Description: desc, + ReferenceID: ref, + Type: t, + Urls: []string{url}, + Priority: prio, + } + } else { + r, err = types.LoadRepository([]byte(str)) + if err != nil { + util.DefaultContext.Fatal(err) + } + if desc != "" { + r.Description = desc + } + if ref != "" { + r.ReferenceID = ref + } + if t != "" { + r.Type = t + } + if url != "" { + r.Urls = []string{url} + } + if prio != 0 { + r.Priority = prio + } + } + + file := filepath.Join(util.DefaultContext.Config.System.Rootfs, d, fmt.Sprintf("%s.yaml", r.Name)) + + b, err := yaml.Marshal(r) + if err != nil { + util.DefaultContext.Fatal(err) + } + + util.DefaultContext.Infof("Adding repository to the sytem as %s", file) + fmt.Println(string(b)) + util.DefaultContext.Info(r.String()) + + if !yes && !util.DefaultContext.Ask() { + util.DefaultContext.Info("Aborted by user") + return + } + + if err := ioutil.WriteFile(file, b, os.ModePerm); err != nil { + util.DefaultContext.Fatal(err) + } + }, + } + cmd.Flags().BoolP("yes", "y", false, "Assume yes to questions") + cmd.Flags().StringP("dir", "o", "", "Folder to write to") + cmd.Flags().String("description", "", "Repository description") + cmd.Flags().String("type", "", "Repository type") + cmd.Flags().String("url", "", "Repository URL") + cmd.Flags().String("reference", "", "Repository Reference ID") + cmd.Flags().IntP("priority", "p", 99, "repository prio") + return cmd +} diff --git a/cmd/repo/get.go b/cmd/repo/get.go new file mode 100644 index 00000000..7859975a --- /dev/null +++ b/cmd/repo/get.go @@ -0,0 +1,62 @@ +// Copyright © 2022 Ettore Di Giacinto +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + +package cmd_repo + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/ghodss/yaml" + "github.com/mudler/luet/cmd/util" + + "github.com/spf13/cobra" +) + +func NewRepoGetCommand() *cobra.Command { + var ans = &cobra.Command{ + Use: "get [OPTIONS] name", + Short: "get repository in the system", + Args: cobra.ExactArgs(1), + PreRun: func(cmd *cobra.Command, args []string) { + }, + Run: func(cmd *cobra.Command, args []string) { + o, _ := cmd.Flags().GetString("output") + + for _, repo := range util.DefaultContext.Config.SystemRepositories { + if repo.Name != args[0] { + continue + } + + switch strings.ToLower(o) { + case "json": + b, _ := json.Marshal(repo) + fmt.Println(string(b)) + case "yaml": + b, _ := yaml.Marshal(repo) + fmt.Println(string(b)) + default: + fmt.Println(repo) + } + break + } + }, + } + + ans.Flags().StringP("output", "o", "", "output format (json, yaml, text)") + + return ans +} diff --git a/pkg/helpers/uri.go b/pkg/helpers/uri.go new file mode 100644 index 00000000..fc4a2e15 --- /dev/null +++ b/pkg/helpers/uri.go @@ -0,0 +1,62 @@ +// Copyright © 2022 Ettore Di Giacinto +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + +package helpers + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + + "github.com/pkg/errors" +) + +func IsUrl(s string) bool { + url, err := url.Parse(s) + if err != nil || url.Scheme == "" { + return false + } + return true +} + +func GetURI(s string) (string, error) { + f, err := os.Stat(s) + + switch { + case err == nil && f.IsDir(): + return "", errors.New("directories not supported") + case err == nil: + b, err := ioutil.ReadFile(s) + return string(b), err + case IsUrl(s): + resp, err := http.Get(s) + if err != nil { + return "", err + } + defer resp.Body.Close() + + buf := bytes.NewBuffer([]byte{}) + _, err = io.Copy(buf, resp.Body) + if err != nil { + return "", err + } + return buf.String(), nil + default: + return "", errors.New("not supported") + } +}