Skip to content

Instantly share code, notes, and snippets.

@masahide
Last active January 5, 2023 00:59
Show Gist options
  • Save masahide/67fe96fa9382bba0489ee7db76367ae4 to your computer and use it in GitHub Desktop.
Save masahide/67fe96fa9382bba0489ee7db76367ae4 to your computer and use it in GitHub Desktop.
rpmpack_sample
package main
import (
"fmt"
"log"
"os"
"github.com/google/rpmpack"
"github.com/kelseyhightower/envconfig"
)
type specification struct {
BinPath string `required:"true"`
Name string `default:"app"`
Version string `default:"0.0.1"`
Hash string `default:""`
Release string `default:"el7"` // el7, el8 , el9, amzn1, amzn2, amzn2022
Arch string `default:"x86_64"` // x86_64, aarch64
Sign string
}
/*
```
$ docker run -it --rm centos:7 rpm --eval %{?dist}
.el7
$ docker run -it --rm almalinux:9 rpm --eval %{?dist}
.el9
$ docker run -it --rm almalinux:8 rpm --eval %{?dist}
.el8
$ docker run -it --rm rockylinux:9 rpm --eval %{?dist}
.el9
$ docker run -it --rm rockylinux:8 rpm --eval %{?dist}
.el8
$ docker run -it --rm -v $PWD/.:/mnt amazonlinux:1 rpm --eval %{?dist}
.amzn1
$ docker run -it --rm -v $PWD/.:/mnt amazonlinux:2 rpm --eval %{?dist}
.amzn2
$ docker run -it --rm -v $PWD/.:/mnt amazonlinux:2022 rpm --eval %{?dist}
.amzn2022
```
*/
func main() {
var s specification
err := envconfig.Process("", &s)
if err != nil {
log.Fatal(err.Error())
}
if len(s.Hash) > 0 {
s.Release = s.Hash + "." + s.Release
}
r, err := rpmpack.NewRPM(rpmpack.RPMMetaData{
Name: s.Name,
Version: s.Version,
Release: s.Release,
Arch: s.Arch,
})
if err != nil {
log.Fatal(err)
}
// mkdir
r.AddFile(
rpmpack.RPMFile{
Name: "/var/lib/rpmpack",
Mode: 040755,
Owner: "root",
Group: "root",
})
// files
r.AddFile(
rpmpack.RPMFile{
Name: "/var/lib/rpmpack/sample.txt",
Body: []byte("testsample\n"),
Mode: 0600,
Owner: "root",
Group: "root",
})
r.AddFile(
rpmpack.RPMFile{
Name: "/var/lib/rpmpack/sample2.txt",
Body: []byte("testsample2\n"),
Mode: 0644,
Owner: "root",
Group: "root",
})
// symlink
r.AddFile(
rpmpack.RPMFile{
Name: "/var/lib/rpmpack/sample3_link.txt",
Body: []byte("/var/lib/rpmpack/sample.txt"),
Mode: 0120777,
Owner: "root",
Group: "root",
})
// ゴーストファイルインストール時に存在しないがアンインストール時に削除される
r.AddFile(
rpmpack.RPMFile{
Name: "/var/lib/rpmpack/sample4_ghost.txt",
Mode: 0644,
Owner: "root",
Group: "root",
Type: rpmpack.GhostFile,
})
// config file
r.AddFile(
rpmpack.RPMFile{
Name: "/etc/sample.conf",
Mode: 0644,
Body: []byte("testsample\n"),
Owner: "root",
Group: "root",
Type: rpmpack.ConfigFile,
})
/*
// https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html-single/rpm_packaging_guide/index#scriptlets-new_epoch-scriplets-and-triggers
// パッケージのインストールまたは削除の直前に実行されるスクリプトレット。
r.AddPretrans("")
// ターゲットシステムにパッケージをインストールする直前に実行されるスクリプトレット。
r.AddPrein("")
// ターゲットシステムにパッケージがインストールされた直後に実行されるスクリプトレット。
r.AddPostin("systemctl daemon-reload")
// ターゲットシステムからパッケージをアンインストールする直前に実行されるスクリプトレット。
r.AddPreun("")
// ターゲットシステムからパッケージをアンインストールした直後に実行されるスクリプトレット。
r.AddPostun("systemctl daemon-reload")
// トランザクションの最後に実行されるスクリプトレット。
r.AddPosttrans("")
*/
r.AddPostin("echo postin>>/tmp/postin")
r.AddPostun("echo postun>>/tmp/postun")
verRelease := r.FullVersion()
if len(s.Sign) > 0 {
r.SetPGPSigner(func([]byte) ([]byte, error) {
return []byte(s.Sign), nil
})
}
// http://ftp.rpm.org/max-rpm/ch-rpm-file-format.html
// ex: name-version-release.architecture.rpm
filename := s.Name + "-" + verRelease + "." + s.Arch + ".rpm"
fmt.Printf("fullVersion:%s\n", verRelease)
fmt.Printf("filename:%s\n", filename)
f, err := os.Create(filename)
if err != nil {
log.Fatalf("open err: %v", err)
}
defer f.Close()
if err := r.Write(f); err != nil {
log.Fatalf("write failed: %v", err)
}
}
func file(f string) []byte {
b, err := os.ReadFile(f)
if err != nil {
log.Fatalf("ReadFile(%s) err:%s", f, err)
}
return b
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment