Skip to content

Commit

Permalink
feat: provide more field support for rpms (#79)
Browse files Browse the repository at this point in the history
* fix: properly add the PostRemove script, not the PostInstall script

* feat: provide more field support for rpms

New RPM fields
---
* Description
* OS <= info.Platform
* Licence
* URL <= info.Homepage
* Vendor
* Packager <= info.Maintainer
* Provides
* Require <= info.Depends
* Obsolete <= info.Replaces
* Suggests
* Conflicts

Fixes
---
* RPM Compression types are supported again
* RPM Config files are supported again
  * `rpmpack` will support all the rpm file types, so we could extend this more latter

* chore: disable wsl (a new linter in 1.20.x got golangci-lint) until we decide to enable it

* chore: address PR comments
  • Loading branch information
Dj Gilcrease authored and caarlos0 committed Oct 9, 2019
1 parent 7a174b2 commit 03193b2
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fmt:
.PHONY: fmt

lint: check
./bin/golangci-lint run --disable godox --enable-all ./...
./bin/golangci-lint run --disable wsl --disable godox --enable-all ./...
.PHONY: check

ci: build lint test
Expand Down
44 changes: 32 additions & 12 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package acceptance

import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
Expand All @@ -21,7 +22,7 @@ var formats = []string{"deb", "rpm"}
func TestSimple(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s", format),
Expand All @@ -30,7 +31,7 @@ func TestSimple(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.dockerfile", format),
})
})
t.Run("i386", func(t *testing.T) {
t.Run(fmt.Sprintf("i386-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s_386", format),
Expand All @@ -39,7 +40,7 @@ func TestSimple(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.386.dockerfile", format),
})
})
t.Run("ppc64le", func(t *testing.T) {
t.Run(fmt.Sprintf("ppc64le-%s", format), func(t *testing.T) {
t.Skip("for some reason travis fails to run those")
t.Parallel()
accept(t, acceptParms{
Expand All @@ -49,7 +50,7 @@ func TestSimple(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.ppc64le.dockerfile", format),
})
})
t.Run("arm64", func(t *testing.T) {
t.Run(fmt.Sprintf("arm64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s_arm64", format),
Expand All @@ -64,7 +65,7 @@ func TestSimple(t *testing.T) {
func TestComplex(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("complex_%s", format),
Expand All @@ -73,7 +74,7 @@ func TestComplex(t *testing.T) {
Dockerfile: fmt.Sprintf("%s.complex.dockerfile", format),
})
})
t.Run("i386", func(t *testing.T) {
t.Run(fmt.Sprintf("i386-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("complex_%s_386", format),
Expand All @@ -85,10 +86,10 @@ func TestComplex(t *testing.T) {
}
}

func TestComplexOverridesDeb(t *testing.T) {
func TestComplexOverrides(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("overrides_%s", format),
Expand All @@ -100,10 +101,10 @@ func TestComplexOverridesDeb(t *testing.T) {
}
}

func TestMinDeb(t *testing.T) {
func TestMin(t *testing.T) {
for _, format := range formats {
format := format
t.Run("amd64", func(t *testing.T) {
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
t.Parallel()
accept(t, acceptParms{
Name: fmt.Sprintf("min_%s", format),
Expand Down Expand Up @@ -186,8 +187,27 @@ func accept(t *testing.T, params acceptParms) {
".",
)
cmd.Dir = "./testdata"
stdout, err := cmd.StdoutPipe()
require.NoError(t, err)
stderr, err := cmd.StderrPipe()
require.NoError(t, err)
t.Log("will exec:", cmd.Args)
bts, err := cmd.CombinedOutput()
t.Log("output:", string(bts))
err = cmd.Start()
require.NoError(t, err)

var slurp []byte
slurp, err = ioutil.ReadAll(stderr)
if len(slurp) > 0 {
t.Log("stderr:", string(slurp))
}
require.NoError(t, err)

slurp, err = ioutil.ReadAll(stdout)
if len(slurp) > 0 {
t.Log("stdout:", string(slurp))
}
require.NoError(t, err)

err = cmd.Wait()
require.NoError(t, err)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b
github.com/stretchr/testify v1.4.0
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 // indirect
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.2.4
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4A
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 h1:mgAKeshyNqWKdENOnQsg+8dRTwZFIwFaO3HNl52sweA=
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc h1:c0o/qxkaO2LF5t6fQrT4b5hzyggAkLLlCUjqfRxd8Q4=
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
129 changes: 105 additions & 24 deletions rpm/rpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,24 @@ func ensureValidArch(info nfpm.Info) nfpm.Info {

// Package writes a new RPM package to the given writer using the given info
func (*RPM) Package(info nfpm.Info, w io.Writer) error {
var (
err error
meta *rpmpack.RPMMetaData
rpm *rpmpack.RPM
)
info = ensureValidArch(info)
err := nfpm.Validate(info)
if err != nil {
if err = nfpm.Validate(info); err != nil {
return err
}

vInfo := strings.SplitN(info.Version, "-", 1)
vInfo = append(vInfo, "")
rpm, err := rpmpack.NewRPM(rpmpack.RPMMetaData{
Name: info.Name,
Version: vInfo[0],
Release: vInfo[1],
Arch: info.Arch,
})
if err != nil {
if meta, err = buildRPMMeta(info); err != nil {
return err
}
if rpm, err = rpmpack.NewRPM(*meta); err != nil {
return err
}

addEmptyDirsRPM(info, rpm)
if err = createFilesInsideRPM(info, rpm); err != nil {
return err
}
Expand All @@ -75,6 +75,65 @@ func (*RPM) Package(info nfpm.Info, w io.Writer) error {
return nil
}

func buildRPMMeta(info nfpm.Info) (*rpmpack.RPMMetaData, error) {
var (
err error
provides,
depends,
replaces,
suggests,
conflicts rpmpack.Relations
)
vInfo := strings.SplitN(info.Version, "-", 2)
vInfo = append(vInfo, info.RPM.Release)

if provides, err = toRelation(info.Provides); err != nil {
return nil, err
}
if depends, err = toRelation(info.Depends); err != nil {
return nil, err
}
if replaces, err = toRelation(info.Replaces); err != nil {
return nil, err
}
if suggests, err = toRelation(info.Suggests); err != nil {
return nil, err
}
if conflicts, err = toRelation(info.Conflicts); err != nil {
return nil, err
}

return &rpmpack.RPMMetaData{
Name: info.Name,
Description: info.Description,
Version: vInfo[0],
Release: vInfo[1],
Arch: info.Arch,
OS: info.Platform,
Licence: info.License,
URL: info.Homepage,
Vendor: info.Vendor,
Packager: info.Maintainer,
Provides: provides,
Requires: depends,
Obsoletes: replaces,
Suggests: suggests,
Conflicts: conflicts,
Compressor: info.RPM.Compression,
}, nil
}

func toRelation(items []string) (rpmpack.Relations, error) {
relations := make(rpmpack.Relations, 0)
for idx := range items {
if err := relations.Set(items[idx]); err != nil {
return nil, err
}
}

return relations, nil
}

func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
if info.Scripts.PreInstall != "" {
data, err := ioutil.ReadFile(info.Scripts.PreInstall)
Expand All @@ -101,7 +160,7 @@ func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
}

if info.Scripts.PostRemove != "" {
data, err := ioutil.ReadFile(info.Scripts.PostInstall)
data, err := ioutil.ReadFile(info.Scripts.PostRemove)
if err != nil {
return err
}
Expand All @@ -111,28 +170,45 @@ func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
return nil
}

func addEmptyDirsRPM(info nfpm.Info, rpm *rpmpack.RPM) {
for _, dir := range info.EmptyFolders {
rpm.AddFile(
rpmpack.RPMFile{
Name: dir,
Mode: uint(1 | 040000),
})
}
}

func createFilesInsideRPM(info nfpm.Info, rpm *rpmpack.RPM) error {
for _, files := range []map[string]string{
info.Files,
info.ConfigFiles,
} {
copy := func(files map[string]string, config bool) error {
for srcglob, dstroot := range files {
globbed, err := glob.Glob(srcglob, dstroot)
if err != nil {
return err
}
for src, dst := range globbed {
err := copyToRPM(rpm, src, dst)
err := copyToRPM(rpm, src, dst, config)
if err != nil {
return err
}
}
}

return nil
}
err := copy(info.Files, false)
if err != nil {
return err
}
err = copy(info.ConfigFiles, true)
if err != nil {
return err
}
return nil
}

func copyToRPM(rpm *rpmpack.RPM, src, dst string) error {
func copyToRPM(rpm *rpmpack.RPM, src, dst string, config bool) error {
file, err := os.OpenFile(src, os.O_RDONLY, 0600) //nolint:gosec
if err != nil {
return errors.Wrap(err, "could not add file to the archive")
Expand All @@ -152,12 +228,17 @@ func copyToRPM(rpm *rpmpack.RPM, src, dst string) error {
return err
}

rpm.AddFile(
rpmpack.RPMFile{
Name: dst,
Body: data,
Mode: uint(info.Mode()),
})
rpmFile := rpmpack.RPMFile{
Name: dst,
Body: data,
Mode: uint(info.Mode()),
}

if config {
rpmFile.Type = rpmpack.ConfigFile
}

rpm.AddFile(rpmFile)

return nil
}

0 comments on commit 03193b2

Please sign in to comment.