2018-02-03 20:42:56 +01:00
|
|
|
package rpm
|
|
|
|
|
|
|
|
import (
|
2020-07-13 17:10:03 +02:00
|
|
|
"bytes"
|
2020-09-17 14:18:44 +02:00
|
|
|
"errors"
|
2019-09-10 20:01:43 +02:00
|
|
|
"fmt"
|
2020-07-27 16:11:33 +02:00
|
|
|
"io"
|
2018-02-12 22:15:37 +01:00
|
|
|
"io/ioutil"
|
2018-02-16 23:50:13 +01:00
|
|
|
"os"
|
2020-07-27 16:11:33 +02:00
|
|
|
"path"
|
|
|
|
"path/filepath"
|
2020-07-13 17:10:03 +02:00
|
|
|
"strings"
|
2018-02-03 20:42:56 +01:00
|
|
|
"testing"
|
2020-07-13 17:10:03 +02:00
|
|
|
"time"
|
2018-02-03 20:42:56 +01:00
|
|
|
|
2020-12-15 17:47:00 +01:00
|
|
|
"github.com/goreleaser/chglog"
|
2019-09-10 20:01:43 +02:00
|
|
|
"github.com/sassoftware/go-rpmutils"
|
2020-07-30 04:20:50 +02:00
|
|
|
"github.com/sassoftware/go-rpmutils/cpio"
|
2018-02-05 03:54:03 +01:00
|
|
|
"github.com/stretchr/testify/assert"
|
2020-08-04 19:55:52 +02:00
|
|
|
"github.com/stretchr/testify/require"
|
2020-09-17 14:18:44 +02:00
|
|
|
"golang.org/x/crypto/openpgp"
|
2019-10-11 22:11:28 +02:00
|
|
|
|
|
|
|
"github.com/goreleaser/nfpm"
|
2020-12-15 17:47:00 +01:00
|
|
|
"github.com/goreleaser/nfpm/files"
|
2018-02-03 20:42:56 +01:00
|
|
|
)
|
|
|
|
|
2019-10-11 22:11:28 +02:00
|
|
|
func exampleInfo() *nfpm.Info {
|
|
|
|
return nfpm.WithDefaults(&nfpm.Info{
|
2018-04-10 23:10:32 +02:00
|
|
|
Name: "foo",
|
2019-03-20 01:48:14 +01:00
|
|
|
Arch: "amd64",
|
2018-03-28 19:22:19 +02:00
|
|
|
Description: "Foo does things",
|
|
|
|
Priority: "extra",
|
|
|
|
Maintainer: "Carlos A Becker <pkg@carlosbecker.com>",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Section: "default",
|
|
|
|
Homepage: "http://carlosbecker.com",
|
|
|
|
Vendor: "nope",
|
|
|
|
License: "MIT",
|
2018-04-10 17:39:43 +02:00
|
|
|
Overridables: nfpm.Overridables{
|
|
|
|
Depends: []string{
|
|
|
|
"bash",
|
|
|
|
},
|
|
|
|
Recommends: []string{
|
|
|
|
"git",
|
|
|
|
},
|
|
|
|
Suggests: []string{
|
|
|
|
"bash",
|
|
|
|
},
|
|
|
|
Replaces: []string{
|
|
|
|
"svn",
|
|
|
|
},
|
|
|
|
Provides: []string{
|
|
|
|
"bzr",
|
|
|
|
},
|
|
|
|
Conflicts: []string{
|
|
|
|
"zsh",
|
|
|
|
},
|
|
|
|
Files: map[string]string{
|
|
|
|
"../testdata/fake": "/usr/local/bin/fake",
|
|
|
|
},
|
|
|
|
ConfigFiles: map[string]string{
|
|
|
|
"../testdata/whatever.conf": "/etc/fake/fake.conf",
|
|
|
|
},
|
2018-05-17 01:58:56 +02:00
|
|
|
EmptyFolders: []string{
|
|
|
|
"/var/log/whatever",
|
|
|
|
"/usr/share/whatever",
|
|
|
|
},
|
2018-04-10 17:39:43 +02:00
|
|
|
Scripts: nfpm.Scripts{
|
|
|
|
PreInstall: "../testdata/scripts/preinstall.sh",
|
|
|
|
PostInstall: "../testdata/scripts/postinstall.sh",
|
|
|
|
PreRemove: "../testdata/scripts/preremove.sh",
|
|
|
|
PostRemove: "../testdata/scripts/postremove.sh",
|
|
|
|
},
|
2018-04-09 16:53:49 +02:00
|
|
|
},
|
2018-03-28 19:22:19 +02:00
|
|
|
})
|
|
|
|
}
|
2018-02-18 21:13:47 +01:00
|
|
|
|
2018-02-03 20:42:56 +01:00
|
|
|
func TestRPM(t *testing.T) {
|
2019-10-22 05:55:29 +02:00
|
|
|
f, err := ioutil.TempFile("", "test.rpm")
|
2020-12-09 19:28:30 +01:00
|
|
|
require.NoError(t, err)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, Default.Package(exampleInfo(), f))
|
2019-10-22 05:55:29 +02:00
|
|
|
|
|
|
|
file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0600) //nolint:gosec
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-12-09 19:28:30 +01:00
|
|
|
defer func() {
|
|
|
|
f.Close()
|
|
|
|
file.Close()
|
|
|
|
err = os.Remove(file.Name())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}()
|
2019-10-22 05:55:29 +02:00
|
|
|
rpm, err := rpmutils.ReadRpm(file)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-11-05 03:56:18 +01:00
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
version, err := rpm.Header.GetString(rpmutils.VERSION)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-11-05 13:38:13 +01:00
|
|
|
assert.Equal(t, "1.0.0", version)
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
release, err := rpm.Header.GetString(rpmutils.RELEASE)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-10-22 05:55:29 +02:00
|
|
|
assert.Equal(t, "1", release)
|
2019-11-05 03:56:18 +01:00
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
epoch, err := rpm.Header.Get(rpmutils.EPOCH)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-12-31 15:55:19 +01:00
|
|
|
epochUint32, ok := epoch.([]uint32)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.True(t, ok)
|
2019-12-31 15:55:19 +01:00
|
|
|
assert.Len(t, epochUint32, 1)
|
|
|
|
assert.Equal(t, uint32(0), epochUint32[0])
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
group, err := rpm.Header.GetString(rpmutils.GROUP)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-08-04 20:41:54 +02:00
|
|
|
assert.Equal(t, "", group)
|
2019-11-05 03:56:18 +01:00
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
summary, err := rpm.Header.GetString(rpmutils.SUMMARY)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-11-05 03:56:18 +01:00
|
|
|
assert.Equal(t, "Foo does things", summary)
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
description, err := rpm.Header.GetString(rpmutils.DESCRIPTION)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-11-05 03:56:18 +01:00
|
|
|
assert.Equal(t, "Foo does things", description)
|
2018-02-03 20:42:56 +01:00
|
|
|
}
|
2018-02-16 22:11:52 +01:00
|
|
|
|
2020-08-04 20:41:54 +02:00
|
|
|
func TestRPMGroup(t *testing.T) {
|
|
|
|
f, err := ioutil.TempFile("", "test.rpm")
|
2020-12-09 19:28:30 +01:00
|
|
|
require.NoError(t, err)
|
2020-08-04 20:41:54 +02:00
|
|
|
info := exampleInfo()
|
|
|
|
info.RPM.Group = "Unspecified"
|
|
|
|
require.NoError(t, Default.Package(info, f))
|
|
|
|
|
|
|
|
file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0600) //nolint:gosec
|
|
|
|
require.NoError(t, err)
|
2020-12-09 19:28:30 +01:00
|
|
|
defer func() {
|
|
|
|
f.Close()
|
|
|
|
file.Close()
|
|
|
|
err = os.Remove(file.Name())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}()
|
|
|
|
|
2020-08-04 20:41:54 +02:00
|
|
|
rpm, err := rpmutils.ReadRpm(file)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
group, err := rpm.Header.GetString(rpmutils.GROUP)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "Unspecified", group)
|
|
|
|
}
|
|
|
|
|
2020-11-08 18:49:40 +01:00
|
|
|
func TestRPMSummary(t *testing.T) {
|
|
|
|
f, err := ioutil.TempFile("", "test.rpm")
|
2020-12-09 19:28:30 +01:00
|
|
|
require.NoError(t, err)
|
2020-11-08 18:49:40 +01:00
|
|
|
|
|
|
|
var customSummary = "This is my custom summary"
|
|
|
|
info := exampleInfo()
|
|
|
|
info.RPM.Group = "Unspecified"
|
|
|
|
info.RPM.Summary = customSummary
|
|
|
|
|
|
|
|
require.NoError(t, Default.Package(info, f))
|
|
|
|
|
|
|
|
file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0600) //nolint:gosec
|
|
|
|
require.NoError(t, err)
|
2020-12-09 19:28:30 +01:00
|
|
|
defer func() {
|
|
|
|
f.Close()
|
|
|
|
file.Close()
|
|
|
|
err = os.Remove(file.Name())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}()
|
2020-11-08 18:49:40 +01:00
|
|
|
rpm, err := rpmutils.ReadRpm(file)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
summary, err := rpm.Header.GetString(rpmutils.SUMMARY)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, customSummary, summary)
|
|
|
|
}
|
|
|
|
|
2019-07-16 01:20:57 +02:00
|
|
|
func TestWithRPMTags(t *testing.T) {
|
2019-10-22 05:55:29 +02:00
|
|
|
f, err := ioutil.TempFile("", "test.rpm")
|
2020-12-09 19:28:30 +01:00
|
|
|
require.NoError(t, err)
|
2019-10-22 05:55:29 +02:00
|
|
|
|
2019-07-16 01:20:57 +02:00
|
|
|
var info = exampleInfo()
|
2019-10-22 05:55:29 +02:00
|
|
|
info.Release = "3"
|
2019-12-31 15:55:19 +01:00
|
|
|
info.Epoch = "42"
|
2019-09-10 20:01:43 +02:00
|
|
|
info.RPM = nfpm.RPM{
|
2019-10-22 23:29:42 +02:00
|
|
|
Group: "default",
|
2019-07-16 01:20:57 +02:00
|
|
|
}
|
2019-11-05 03:56:18 +01:00
|
|
|
info.Description = "first line\nsecond line\nthird line"
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, Default.Package(info, f))
|
2019-10-22 05:55:29 +02:00
|
|
|
|
|
|
|
file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0600) //nolint:gosec
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-12-09 19:28:30 +01:00
|
|
|
defer func() {
|
|
|
|
f.Close()
|
|
|
|
file.Close()
|
|
|
|
err = os.Remove(file.Name())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}()
|
2019-10-23 19:03:35 +02:00
|
|
|
|
2019-10-22 05:55:29 +02:00
|
|
|
rpm, err := rpmutils.ReadRpm(file)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-10-23 19:03:35 +02:00
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
version, err := rpm.Header.GetString(rpmutils.VERSION)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-11-05 13:38:13 +01:00
|
|
|
assert.Equal(t, "1.0.0", version)
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
release, err := rpm.Header.GetString(rpmutils.RELEASE)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-10-22 05:55:29 +02:00
|
|
|
assert.Equal(t, "3", release)
|
2019-10-23 19:03:35 +02:00
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
epoch, err := rpm.Header.Get(rpmutils.EPOCH)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-12-31 15:55:19 +01:00
|
|
|
epochUint32, ok := epoch.([]uint32)
|
|
|
|
assert.Len(t, epochUint32, 1)
|
|
|
|
assert.True(t, ok)
|
|
|
|
assert.Equal(t, uint32(42), epochUint32[0])
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
group, err := rpm.Header.GetString(rpmutils.GROUP)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-10-23 19:03:35 +02:00
|
|
|
assert.Equal(t, "default", group)
|
2019-11-05 03:56:18 +01:00
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
summary, err := rpm.Header.GetString(rpmutils.SUMMARY)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-11-05 03:56:18 +01:00
|
|
|
assert.Equal(t, "first line", summary)
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
description, err := rpm.Header.GetString(rpmutils.DESCRIPTION)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-11-05 03:56:18 +01:00
|
|
|
assert.Equal(t, info.Description, description)
|
2019-07-16 01:20:57 +02:00
|
|
|
}
|
|
|
|
|
2020-02-18 14:49:10 +01:00
|
|
|
func TestRPMVersion(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
info.Version = "1.0.0" //nolint:golint,goconst
|
|
|
|
meta, err := buildRPMMeta(info)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-02-18 14:49:10 +01:00
|
|
|
assert.Equal(t, "1.0.0", meta.Version)
|
|
|
|
assert.Equal(t, "1", meta.Release)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRPMVersionWithRelease(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
info.Version = "1.0.0" //nolint:golint,goconst
|
|
|
|
info.Release = "2"
|
|
|
|
meta, err := buildRPMMeta(info)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-02-18 14:49:10 +01:00
|
|
|
assert.Equal(t, "1.0.0", meta.Version)
|
|
|
|
assert.Equal(t, "2", meta.Release)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRPMVersionWithPrerelease(t *testing.T) {
|
|
|
|
// https://fedoraproject.org/wiki/Package_Versioning_Examples#Complex_versioning_examples
|
|
|
|
info := exampleInfo()
|
2020-08-19 15:20:02 +02:00
|
|
|
|
|
|
|
info.Version = "1.0.0"
|
|
|
|
info.Prerelease = "rc1" // nolint:goconst
|
2020-02-18 14:49:10 +01:00
|
|
|
meta, err := buildRPMMeta(info)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-08-19 15:20:02 +02:00
|
|
|
assert.Equal(t, "1.0.0~rc1", meta.Version)
|
|
|
|
assert.Equal(t, "1", meta.Release)
|
|
|
|
|
|
|
|
info.Version = "1.0.0~rc1"
|
|
|
|
info.Prerelease = ""
|
|
|
|
meta, err = buildRPMMeta(info)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "1.0.0~rc1", meta.Version)
|
|
|
|
assert.Equal(t, "1", meta.Release)
|
2020-02-18 14:49:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestRPMVersionWithReleaseAndPrerelease(t *testing.T) {
|
|
|
|
// https://fedoraproject.org/wiki/Package_Versioning_Examples#Complex_versioning_examples
|
|
|
|
info := exampleInfo()
|
2020-08-19 15:20:02 +02:00
|
|
|
|
|
|
|
info.Version = "1.0.0"
|
2020-02-18 14:49:10 +01:00
|
|
|
info.Release = "0.2"
|
|
|
|
info.Prerelease = "rc1"
|
|
|
|
meta, err := buildRPMMeta(info)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-08-19 15:20:02 +02:00
|
|
|
assert.Equal(t, "1.0.0~rc1", meta.Version)
|
|
|
|
assert.Equal(t, "0.2", meta.Release)
|
|
|
|
|
|
|
|
info.Version = "1.0.0~rc1"
|
|
|
|
info.Release = "0.2"
|
|
|
|
info.Prerelease = ""
|
|
|
|
meta, err = buildRPMMeta(info)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "1.0.0~rc1", meta.Version)
|
|
|
|
assert.Equal(t, "0.2", meta.Release)
|
2020-02-18 14:49:10 +01:00
|
|
|
}
|
|
|
|
|
2020-08-20 06:00:17 +02:00
|
|
|
func TestRPMVersionWithVersionMetadata(t *testing.T) {
|
|
|
|
// https://fedoraproject.org/wiki/Package_Versioning_Examples#Complex_versioning_examples
|
|
|
|
info := exampleInfo()
|
|
|
|
|
|
|
|
info.Version = "1.0.0+meta"
|
|
|
|
info.VersionMetadata = ""
|
|
|
|
meta, err := buildRPMMeta(nfpm.WithDefaults(info))
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "1.0.0+meta", meta.Version)
|
|
|
|
|
|
|
|
info.Version = "1.0.0"
|
|
|
|
info.VersionMetadata = "meta"
|
|
|
|
meta, err = buildRPMMeta(nfpm.WithDefaults(info))
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "1.0.0+meta", meta.Version)
|
|
|
|
}
|
|
|
|
|
2019-12-31 15:55:19 +01:00
|
|
|
func TestWithInvalidEpoch(t *testing.T) {
|
|
|
|
f, err := ioutil.TempFile("", "test.rpm")
|
|
|
|
defer func() {
|
|
|
|
_ = f.Close()
|
|
|
|
err = os.Remove(f.Name())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}()
|
|
|
|
|
|
|
|
var info = exampleInfo()
|
|
|
|
info.Release = "3"
|
|
|
|
info.Epoch = "-1"
|
|
|
|
info.RPM = nfpm.RPM{
|
|
|
|
Group: "default",
|
|
|
|
}
|
|
|
|
info.Description = "first line\nsecond line\nthird line"
|
|
|
|
assert.Error(t, Default.Package(info, f))
|
|
|
|
}
|
|
|
|
|
2019-09-10 20:01:43 +02:00
|
|
|
func TestRPMScripts(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
f, err := ioutil.TempFile(".", fmt.Sprintf("%s-%s-*.rpm", info.Name, info.Version))
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-10 20:01:43 +02:00
|
|
|
err = Default.Package(info, f)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-10 20:01:43 +02:00
|
|
|
file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0600) //nolint:gosec
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-12-09 19:28:30 +01:00
|
|
|
defer func() {
|
|
|
|
f.Close()
|
|
|
|
file.Close()
|
|
|
|
err = os.Remove(file.Name())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}()
|
2019-09-10 20:01:43 +02:00
|
|
|
rpm, err := rpmutils.ReadRpm(file)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-10 20:01:43 +02:00
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
data, err := rpm.Header.GetString(rpmutils.PREIN)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-10 20:01:43 +02:00
|
|
|
assert.Equal(t, `#!/bin/bash
|
|
|
|
|
|
|
|
echo "Preinstall" > /dev/null
|
|
|
|
`, data, "Preinstall script does not match")
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
data, err = rpm.Header.GetString(rpmutils.PREUN)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-10 20:01:43 +02:00
|
|
|
assert.Equal(t, `#!/bin/bash
|
|
|
|
|
|
|
|
echo "Preremove" > /dev/null
|
|
|
|
`, data, "Preremove script does not match")
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
data, err = rpm.Header.GetString(rpmutils.POSTIN)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-10 20:01:43 +02:00
|
|
|
assert.Equal(t, `#!/bin/bash
|
|
|
|
|
|
|
|
echo "Postinstall" > /dev/null
|
|
|
|
`, data, "Postinstall script does not match")
|
|
|
|
|
2020-07-31 20:29:07 +02:00
|
|
|
data, err = rpm.Header.GetString(rpmutils.POSTUN)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2019-09-10 20:01:43 +02:00
|
|
|
assert.Equal(t, `#!/bin/bash
|
|
|
|
|
|
|
|
echo "Postremove" > /dev/null
|
|
|
|
`, data, "Postremove script does not match")
|
|
|
|
}
|
|
|
|
|
2018-03-28 01:36:02 +02:00
|
|
|
func TestRPMFileDoesNotExist(t *testing.T) {
|
2019-03-20 01:48:14 +01:00
|
|
|
info := exampleInfo()
|
2018-03-28 19:22:19 +02:00
|
|
|
info.Files = map[string]string{
|
2020-11-08 21:09:12 +01:00
|
|
|
"../testdata/fake": "/usr/local/bin/fake",
|
2018-03-28 19:22:19 +02:00
|
|
|
}
|
|
|
|
info.ConfigFiles = map[string]string{
|
|
|
|
"../testdata/whatever.confzzz": "/etc/fake/fake.conf",
|
|
|
|
}
|
|
|
|
var err = Default.Package(info, ioutil.Discard)
|
2020-11-10 14:35:00 +01:00
|
|
|
assert.EqualError(t, err, "matching \"../testdata/whatever.confzzz\": file does not exist")
|
2018-03-28 01:36:02 +02:00
|
|
|
}
|
|
|
|
|
2019-06-28 19:14:45 +02:00
|
|
|
func TestRPMMultiArch(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
|
|
|
|
for k := range archToRPM {
|
|
|
|
info.Arch = k
|
|
|
|
info = ensureValidArch(info)
|
|
|
|
assert.Equal(t, archToRPM[k], info.Arch)
|
|
|
|
}
|
|
|
|
}
|
2020-07-13 17:10:03 +02:00
|
|
|
|
2020-08-04 19:44:13 +02:00
|
|
|
func TestConfigNoReplace(t *testing.T) {
|
|
|
|
var (
|
|
|
|
buildConfigFile = "../testdata/whatever.conf"
|
|
|
|
packageConfigFile = "/etc/fake/fake.conf"
|
|
|
|
)
|
|
|
|
|
|
|
|
info := &nfpm.Info{
|
|
|
|
Name: "symlink-in-files",
|
|
|
|
Arch: "amd64",
|
|
|
|
Description: "This package's config references a file via symlink.",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Overridables: nfpm.Overridables{
|
|
|
|
RPM: nfpm.RPM{
|
|
|
|
ConfigNoReplaceFiles: map[string]string{
|
|
|
|
buildConfigFile: packageConfigFile,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var rpmFileBuffer bytes.Buffer
|
|
|
|
err := Default.Package(info, &rpmFileBuffer)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
expectedConfigContent, err := ioutil.ReadFile(buildConfigFile)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
packageConfigContent, err := extractFileFromRpm(rpmFileBuffer.Bytes(), packageConfigFile)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, expectedConfigContent, packageConfigContent)
|
|
|
|
}
|
|
|
|
|
2020-07-15 15:10:29 +02:00
|
|
|
func TestRPMConventionalFileName(t *testing.T) {
|
|
|
|
info := &nfpm.Info{
|
|
|
|
Name: "testpkg",
|
|
|
|
Arch: "noarch",
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
Version string
|
|
|
|
Release string
|
|
|
|
Prerelease string
|
|
|
|
Expected string
|
2020-08-20 06:00:17 +02:00
|
|
|
Metadata string
|
2020-07-15 15:10:29 +02:00
|
|
|
}{
|
2020-08-20 06:00:17 +02:00
|
|
|
{Version: "1.2.3", Release: "", Prerelease: "", Metadata: "",
|
2020-07-15 15:10:29 +02:00
|
|
|
Expected: fmt.Sprintf("%s-1.2.3.%s.rpm", info.Name, info.Arch)},
|
2020-08-20 06:00:17 +02:00
|
|
|
{Version: "1.2.3", Release: "4", Prerelease: "", Metadata: "",
|
2020-07-15 15:10:29 +02:00
|
|
|
Expected: fmt.Sprintf("%s-1.2.3-4.%s.rpm", info.Name, info.Arch)},
|
2020-08-20 06:00:17 +02:00
|
|
|
{Version: "1.2.3", Release: "4", Prerelease: "5", Metadata: "",
|
2020-08-19 15:20:02 +02:00
|
|
|
Expected: fmt.Sprintf("%s-1.2.3~5-4.%s.rpm", info.Name, info.Arch)},
|
2020-08-20 06:00:17 +02:00
|
|
|
{Version: "1.2.3", Release: "", Prerelease: "5", Metadata: "",
|
2020-07-15 15:10:29 +02:00
|
|
|
Expected: fmt.Sprintf("%s-1.2.3~5.%s.rpm", info.Name, info.Arch)},
|
2020-08-20 06:00:17 +02:00
|
|
|
{Version: "1.2.3", Release: "1", Prerelease: "5", Metadata: "git",
|
|
|
|
Expected: fmt.Sprintf("%s-1.2.3~5+git-1.%s.rpm", info.Name, info.Arch)},
|
2020-07-15 15:10:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, testCase := range testCases {
|
|
|
|
info.Version = testCase.Version
|
|
|
|
info.Release = testCase.Release
|
|
|
|
info.Prerelease = testCase.Prerelease
|
2020-08-20 06:00:17 +02:00
|
|
|
info.VersionMetadata = testCase.Metadata
|
2020-07-15 15:10:29 +02:00
|
|
|
|
|
|
|
assert.Equal(t, testCase.Expected, Default.ConventionalFileName(info))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-13 17:10:03 +02:00
|
|
|
func TestRPMChangelog(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
info.Changelog = "../testdata/changelog.yaml"
|
|
|
|
|
|
|
|
var rpmFileBuffer bytes.Buffer
|
|
|
|
err := Default.Package(info, &rpmFileBuffer)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
|
|
|
|
rpm, err := rpmutils.ReadRpm(bytes.NewReader(rpmFileBuffer.Bytes()))
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
|
|
|
|
changelog, err := chglog.Parse(info.Changelog)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
|
|
|
|
_times, err := rpm.Header.Get(tagChangelogTime)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
times, ok := _times.([]uint32)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.True(t, ok)
|
2020-07-13 17:10:03 +02:00
|
|
|
assert.Equal(t, len(changelog), len(times))
|
|
|
|
|
|
|
|
_titles, err := rpm.Header.Get(tagChangelogName)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
titles, ok := _titles.([]string)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.True(t, ok)
|
2020-07-13 17:10:03 +02:00
|
|
|
assert.Equal(t, len(changelog), len(titles))
|
|
|
|
|
|
|
|
_notes, err := rpm.Header.Get(tagChangelogText)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
allNotes, ok := _notes.([]string)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.True(t, ok)
|
2020-07-13 17:10:03 +02:00
|
|
|
assert.Equal(t, len(changelog), len(allNotes))
|
|
|
|
|
|
|
|
for i, entry := range changelog {
|
|
|
|
timestamp := time.Unix(int64(times[i]), 0).UTC()
|
|
|
|
title := titles[i]
|
|
|
|
notes := strings.Split(allNotes[i], "\n")
|
|
|
|
|
|
|
|
assert.Equal(t, entry.Date, timestamp)
|
|
|
|
assert.True(t, strings.Contains(title, entry.Packager))
|
|
|
|
assert.True(t, strings.Contains(title, entry.Semver))
|
|
|
|
assert.Equal(t, len(entry.Changes), len(notes))
|
|
|
|
|
|
|
|
for j, change := range entry.Changes {
|
|
|
|
assert.True(t, strings.Contains(notes[j], change.Note))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRPMNoChangelogTagsWithoutChangelogConfigured(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
|
|
|
|
var rpmFileBuffer bytes.Buffer
|
|
|
|
err := Default.Package(info, &rpmFileBuffer)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
|
|
|
|
rpm, err := rpmutils.ReadRpm(bytes.NewReader(rpmFileBuffer.Bytes()))
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-13 17:10:03 +02:00
|
|
|
|
|
|
|
_, err = rpm.Header.Get(tagChangelogTime)
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
|
|
|
_, err = rpm.Header.Get(tagChangelogName)
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
|
|
|
_, err = rpm.Header.Get(tagChangelogText)
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
2020-07-27 16:11:33 +02:00
|
|
|
|
|
|
|
func TestSymlinkInFiles(t *testing.T) {
|
|
|
|
var (
|
|
|
|
symlinkTarget = "../testdata/whatever.conf"
|
|
|
|
packagedTarget = "/etc/fake/whatever.conf"
|
|
|
|
)
|
|
|
|
|
|
|
|
info := &nfpm.Info{
|
|
|
|
Name: "symlink-in-files",
|
|
|
|
Arch: "amd64",
|
|
|
|
Description: "This package's config references a file via symlink.",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Overridables: nfpm.Overridables{
|
|
|
|
Files: map[string]string{
|
|
|
|
symlinkTo(t, symlinkTarget): packagedTarget,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
realSymlinkTarget, err := ioutil.ReadFile(symlinkTarget)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-27 16:11:33 +02:00
|
|
|
|
|
|
|
var rpmFileBuffer bytes.Buffer
|
|
|
|
err = Default.Package(info, &rpmFileBuffer)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-27 16:11:33 +02:00
|
|
|
|
|
|
|
packagedSymlinkTarget, err := extractFileFromRpm(rpmFileBuffer.Bytes(), packagedTarget)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-27 16:11:33 +02:00
|
|
|
|
|
|
|
assert.Equal(t, string(realSymlinkTarget), string(packagedSymlinkTarget))
|
|
|
|
}
|
|
|
|
|
2020-07-30 04:20:50 +02:00
|
|
|
func TestSymlink(t *testing.T) {
|
|
|
|
var (
|
|
|
|
configFilePath = "/usr/share/doc/fake/fake.txt"
|
|
|
|
symlink = "/path/to/symlink"
|
|
|
|
symlinkTarget = configFilePath
|
|
|
|
)
|
|
|
|
|
|
|
|
info := &nfpm.Info{
|
|
|
|
Name: "symlink-in-files",
|
|
|
|
Arch: "amd64",
|
|
|
|
Description: "This package's config references a file via symlink.",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Overridables: nfpm.Overridables{
|
|
|
|
Files: map[string]string{
|
|
|
|
"../testdata/whatever.conf": configFilePath,
|
|
|
|
},
|
|
|
|
Symlinks: map[string]string{
|
|
|
|
symlink: symlinkTarget,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var rpmFileBuffer bytes.Buffer
|
|
|
|
err := Default.Package(info, &rpmFileBuffer)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-30 04:20:50 +02:00
|
|
|
|
|
|
|
packagedSymlinkHeader, err := extractFileHeaderFromRpm(rpmFileBuffer.Bytes(), symlink)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-30 04:20:50 +02:00
|
|
|
|
|
|
|
packagedSymlink, err := extractFileFromRpm(rpmFileBuffer.Bytes(), symlink)
|
2020-08-04 19:55:52 +02:00
|
|
|
require.NoError(t, err)
|
2020-07-30 04:20:50 +02:00
|
|
|
|
|
|
|
assert.Equal(t, symlink, packagedSymlinkHeader.Filename())
|
|
|
|
assert.Equal(t, cpio.S_ISLNK, packagedSymlinkHeader.Mode())
|
|
|
|
assert.Equal(t, symlinkTarget, string(packagedSymlink))
|
|
|
|
}
|
|
|
|
|
2020-09-17 14:18:44 +02:00
|
|
|
func TestRPMSignature(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
info.RPM.Signature.KeyFile = "../internal/sign/testdata/privkey.asc"
|
|
|
|
info.RPM.Signature.KeyPassphrase = "hunter2"
|
|
|
|
|
|
|
|
pubkeyFileContent, err := ioutil.ReadFile("../internal/sign/testdata/pubkey.gpg")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
keyring, err := openpgp.ReadKeyRing(bytes.NewReader(pubkeyFileContent))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
var rpmBuffer bytes.Buffer
|
|
|
|
err = Default.Package(info, &rpmBuffer)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, sigs, err := rpmutils.Verify(bytes.NewReader(rpmBuffer.Bytes()), keyring)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, sigs, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRPMSignatureError(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
info.RPM.Signature.KeyFile = "../internal/sign/testdata/privkey.asc"
|
|
|
|
info.RPM.Signature.KeyPassphrase = "wrongpass"
|
|
|
|
|
|
|
|
var rpmBuffer bytes.Buffer
|
|
|
|
err := Default.Package(info, &rpmBuffer)
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
var expectedError *nfpm.ErrSigningFailure
|
|
|
|
require.True(t, errors.As(err, &expectedError))
|
|
|
|
}
|
|
|
|
|
2020-11-08 21:10:27 +01:00
|
|
|
func TestRPMGhostFiles(t *testing.T) {
|
|
|
|
var (
|
|
|
|
filename = "/usr/lib/casper.a"
|
|
|
|
)
|
|
|
|
|
|
|
|
info := &nfpm.Info{
|
|
|
|
Name: "rpm-ghost",
|
|
|
|
Arch: "amd64",
|
|
|
|
Description: "This RPM contains ghost files.",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Overridables: nfpm.Overridables{RPM: nfpm.RPM{GhostFiles: []string{filename}}},
|
|
|
|
}
|
|
|
|
|
|
|
|
var rpmFileBuffer bytes.Buffer
|
|
|
|
err := Default.Package(info, &rpmFileBuffer)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-12-08 22:37:51 +01:00
|
|
|
headerFiles, err := extraFileInfoSliceFromRpm(rpmFileBuffer.Bytes())
|
2020-11-08 21:10:27 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-12-08 22:37:51 +01:00
|
|
|
type headerFileInfo struct {
|
|
|
|
Name string
|
|
|
|
Size int64
|
|
|
|
Mode int
|
|
|
|
}
|
|
|
|
expected := []headerFileInfo{
|
|
|
|
{filename, 0, cpio.S_ISREG | 0644},
|
|
|
|
}
|
|
|
|
actual := make([]headerFileInfo, 0)
|
|
|
|
for _, fileInfo := range headerFiles {
|
|
|
|
actual = append(actual, headerFileInfo{fileInfo.Name(), fileInfo.Size(), fileInfo.Mode()})
|
|
|
|
}
|
|
|
|
assert.Equal(t, expected, actual)
|
2020-11-08 21:10:27 +01:00
|
|
|
|
2020-12-08 22:37:51 +01:00
|
|
|
_, err = extractFileHeaderFromRpm(rpmFileBuffer.Bytes(), filename)
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
_, err = extractFileFromRpm(rpmFileBuffer.Bytes(), filename)
|
|
|
|
require.Error(t, err)
|
2020-11-08 21:10:27 +01:00
|
|
|
}
|
|
|
|
|
2020-11-10 13:37:29 +01:00
|
|
|
func TestDisableGlobbing(t *testing.T) {
|
|
|
|
info := exampleInfo()
|
|
|
|
info.DisableGlobbing = true
|
|
|
|
info.Files = map[string]string{
|
2020-11-10 22:25:58 +01:00
|
|
|
"../testdata/{file}[": "/test/{file}[",
|
2020-11-10 13:37:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var rpmFileBuffer bytes.Buffer
|
|
|
|
err := Default.Package(info, &rpmFileBuffer)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-11-10 22:25:58 +01:00
|
|
|
expectedContent, err := ioutil.ReadFile("../testdata/{file}[")
|
2020-11-10 13:37:29 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-11-10 22:25:58 +01:00
|
|
|
actualContent, err := extractFileFromRpm(rpmFileBuffer.Bytes(), "/test/{file}[")
|
2020-11-10 13:37:29 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
assert.Equal(t, expectedContent, actualContent)
|
|
|
|
}
|
|
|
|
|
2020-07-27 16:11:33 +02:00
|
|
|
func extractFileFromRpm(rpm []byte, filename string) ([]byte, error) {
|
|
|
|
rpmFile, err := rpmutils.ReadRpm(bytes.NewReader(rpm))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
pr, err := rpmFile.PayloadReader()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
hdr, err := pr.Next()
|
2020-11-10 14:35:00 +01:00
|
|
|
if errors.Is(err, io.EOF) {
|
2020-07-27 16:11:33 +02:00
|
|
|
break // End of archive
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if hdr.Filename() != filename {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
fileContents, err := ioutil.ReadAll(pr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return fileContents, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, os.ErrNotExist
|
|
|
|
}
|
|
|
|
|
2020-12-08 22:37:51 +01:00
|
|
|
func extraFileInfoSliceFromRpm(rpm []byte) ([]rpmutils.FileInfo, error) {
|
|
|
|
rpmFile, err := rpmutils.ReadRpm(bytes.NewReader(rpm))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return rpmFile.Header.GetFiles()
|
|
|
|
}
|
|
|
|
|
2020-07-30 04:20:50 +02:00
|
|
|
func extractFileHeaderFromRpm(rpm []byte, filename string) (*cpio.Cpio_newc_header, error) {
|
|
|
|
rpmFile, err := rpmutils.ReadRpm(bytes.NewReader(rpm))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
pr, err := rpmFile.PayloadReader()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
hdr, err := pr.Next()
|
2020-11-10 14:35:00 +01:00
|
|
|
if errors.Is(err, io.EOF) {
|
2020-07-30 04:20:50 +02:00
|
|
|
break // End of archive
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if hdr.Filename() != filename {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
return hdr, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, os.ErrNotExist
|
|
|
|
}
|
|
|
|
|
2020-07-27 16:11:33 +02:00
|
|
|
func symlinkTo(tb testing.TB, fileName string) string {
|
|
|
|
target, err := filepath.Abs(fileName)
|
|
|
|
assert.NoError(tb, err)
|
|
|
|
|
|
|
|
tempDir, err := ioutil.TempDir("", "nfpm_rpm_test")
|
|
|
|
assert.NoError(tb, err)
|
|
|
|
|
|
|
|
symlinkName := path.Join(tempDir, "symlink")
|
|
|
|
err = os.Symlink(target, symlinkName)
|
|
|
|
assert.NoError(tb, err)
|
|
|
|
|
|
|
|
tb.Cleanup(func() {
|
|
|
|
err = os.RemoveAll(tempDir)
|
|
|
|
assert.NoError(tb, err)
|
|
|
|
})
|
|
|
|
|
2020-12-09 19:28:30 +01:00
|
|
|
return files.ToNixPath(symlinkName)
|
2020-07-27 16:11:33 +02:00
|
|
|
}
|