diff --git a/README.md b/README.md index 904d9d5..c9ff567 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,14 @@ Read the state of an existing resource (URI) and generate a YAML representation ![Import Resource](md-images/import-resource.gif) +## Importing resources from different sources + +JX supports importing resources data from various source types, among these are filesystem directories, tar archive contents, containers, iptables chains, installed packages, etc. + +Import system packages using the debian package type, and output the resource documents in JSON format. + +`jx import --output json:// package://?type=deb` + Import the contents of a tar archive into a resource document. `jx import ./test.tgz` diff --git a/internal/resource/package.go b/internal/resource/package.go index cfa2cd6..a7144bb 100644 --- a/internal/resource/package.go +++ b/internal/resource/package.go @@ -305,7 +305,7 @@ func (p *PackageType) NewReadPackagesCommand() (read *command.Command) { case PackageTypeApt: return NewAptReadPackagesCommand() case PackageTypeDeb: -// return NewDebReadPackagesCommand() + return NewDebReadPackagesCommand() case PackageTypeDnf: // return NewDnfReadPackagesCommand() case PackageTypeRpm: @@ -546,6 +546,7 @@ func NewAptReadPackagesCommand() *command.Command { p.Name = packageName p.State = "present" p.Version = packageVersion + p.PackageType = PackageTypeApt } return nil } @@ -627,6 +628,48 @@ func NewDebDeleteCommand() *command.Command { return c } +func NewDebReadPackagesCommand() *command.Command { + c := command.NewCommand() + c.Path = "dpkg-query" + c.FailOnError = false + c.Split = false + c.Args = []command.CommandArg{ + command.CommandArg("-W"), + command.CommandArg("-f"), + command.CommandArg("${binary:Package} ${Version} ${Status}\n"), + } + c.Env = []string{ "DEBIAN_FRONTEND=noninteractive" } + c.Extractor = func(out []byte, target any) error { + Packages := target.(*[]*Package) + lines := strings.Split(strings.TrimSpace(string(out)), "\n") + lineIndex := 0 + for _, line := range lines { + installedPackage := strings.Fields(strings.TrimSpace(line)) + status := strings.Join(installedPackage[2:], " ") + if status == "install ok installed" { + if len(*Packages) <= lineIndex + 1 { + *Packages = append(*Packages, NewPackage()) + } + p := (*Packages)[lineIndex] + packageNameFields := strings.Split(installedPackage[0], ":") + packageName := packageNameFields[0] + packageVersionFields := strings.Split(installedPackage[1], ":") + if len(packageVersionFields) > 1 { + p.Version = packageVersionFields[1] + } else { + p.Version = packageVersionFields[0] + } + p.Name = packageName + p.State = "present" + p.PackageType = PackageTypeDeb + lineIndex++ + } + } + return nil + } + return c +} + func NewDnfCreateCommand() *command.Command { c := command.NewCommand() c.Path = "dnf" @@ -706,7 +749,7 @@ func NewRpmCreateCommand() *command.Command { c.Split = false c.Args = []command.CommandArg{ command.CommandArg("-i"), - command.CommandArg("{{ .Name }}"), + command.CommandArg("{{ .Source }}"), } return c } @@ -747,7 +790,7 @@ func NewRpmUpdateCommand() *command.Command { c.Path = "rpm" c.Args = []command.CommandArg{ command.CommandArg("-i"), - command.CommandArg("{{ .Name }}"), + command.CommandArg("{{ .Source }}"), } return c } diff --git a/internal/source/package.go b/internal/source/package.go index 39c61e9..8014495 100644 --- a/internal/source/package.go +++ b/internal/source/package.go @@ -26,6 +26,7 @@ func NewPackage() *Package { func init() { SourceTypes.Register([]string{"package"}, func(u *url.URL) DocSource { p := NewPackage() + p.PackageType = resource.PackageType(u.Query().Get("type")) return p })