ちゃんるいすのブログ

オタクエンジニアの雑記

Goでビルドしたものを超簡単にrpmとdebにパッケージしてLinux向けに配布する


Linux サーバーで動かすことを前提に書いたものを Linux 向けに簡単にインストールさせるためにいちいち Go を入れたりするのは面倒。
あと、GitHub Enterprise(GHE)とかを使っているとパブリックなリポジトリに対してもトークンが必要だったり超面倒。

なので、rpmdeb でパッケージして配布しようという記事。
CircleCI を使って、rpm, deb 化したものを S3 に上げて、README の URL を変更するという流れ。

必要なものは CentOS 環境のみ!

RPM

今回は Systemd で管理させたいので必要なファイルは2つ。
1. Systemd script
2. Spec ファイル

Systemd script については割愛します。

hogehoge.spec

コピペで、Summary、Name を変更すればOK
やっていることは見るとなんとなく分かると思ふ。

%define _binaries_in_noarch_packages_terminate_build 0

Summary: hogehoge
Name:    hogehoge
Version: 0.0.0
Release: 1
License: MIT
Group:   Applications/System
URL:     url

Source0:   %{name}-%{version}
Source1:   %{name}.service
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root

%description
%{summary}

%prep

%build

%install
%{__rm} -rf %{buildroot}
%{__install} -Dp -m0755 %{SOURCE0} %{buildroot}/usr/local/bin/%{name}
%{__install} -Dp -m0755 %{SOURCE1} %{buildroot}/etc/systemd/system/%{name}.service

%clean
%{__rm} -rf %{buildroot}

%post
if [ $1 -eq 1 ] ; then
    # Initial installation
    /bin/systemctl daemon-reload >/dev/null 2>&1 || :
fi

%preun
if [ $1 -eq 0 ] ; then
    # Package removal, not upgrade
    /bin/systemctl --no-reload disable %{name}.service > /dev/null 2>&1 || :
    /bin/systemctl stop %{name}.service > /dev/null 2>&1 || :
fi

%postun
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ] ; then
    # Package upgrade, not uninstall
    /bin/systemctl try-restart %{name}.service >/dev/null 2>&1 || :
fi

%files
%defattr(-,root,root)
/usr/local/bin/%{name}
/etc/systemd/system/%{name}.service
rpmbuild
yum install rpmdevtools yum-utils -y
rpmdev-setuptree
cp -rf rpmbuild/SOURCES ${HOME}/rpmbuild
cp -rf rpmbuild/SPECS ${HOME}/rpmbuild
mv hoge ${HOME}/rpmbuild/SOURCES/hoge-${CIRCLE_TAG}
rpmbuild -bb ${HOME}/rpmbuild/SPECS/hoge.spec
deb

rpm から deb を作るのは alien を使えばお手軽

yum install alien -y
alien -d hoge-${CIRCLE_TAG}-1.x86_64.rpm
mv hoge_0${CIRCLE_TAG}-2_amd64.deb /tmp/

.circleci/config.yml

完全版

やっていることは
1. hoge.spec の Version を置換
2. rpm
3. deb
4. s3 アップロード
5. README.md のバージョンを置換

version: 2

defaults: &defaults
  working_directory: /root/go/src/ghe.hoge.com/hoge/hoge
  docker:
    - image: centos:7
      environment:
        GO111MODULE: "on"

jobs:
  release:
    <<: *defaults
    steps:
      - checkout
      - add_ssh_keys
      - run:
          name: install go & build
          command: |
            yum install epel-release -y
            yum install go -y
            export GOPATH=$HOME/go
            go build -ldflags "-s -w" .
      - run:
          name: awscli
          command: |
            curl -O https://bootstrap.pypa.io/get-pip.py
            python get-pip.py
            pip install awscli
            rm -rf get-pip.py
      - run:
          name: rpmbuild
          command: |
            yum install rpmdevtools yum-utils -y
            rpmdev-setuptree
            cp -rf rpmbuild/SOURCES ${HOME}/rpmbuild
            cp -rf rpmbuild/SPECS ${HOME}/rpmbuild
            sed -i -e "s/Version: 0.0.0/Version: ${CIRCLE_TAG}/" ${HOME}/rpmbuild/SPECS/hoge.spec
            mv hoge ${HOME}/rpmbuild/SOURCES/hoge-${CIRCLE_TAG}
            rpmbuild -bb ${HOME}/rpmbuild/SPECS/hoge.spec
            mv ${HOME}/rpmbuild/RPMS/x86_64/hoge-${CIRCLE_TAG}-1.x86_64.rpm /tmp/
      - run:
          name: deb
          command: |
            yum install alien -y
            alien -d /tmp/hoge-${CIRCLE_TAG}-1.x86_64.rpm
            mv hoge_0${CIRCLE_TAG}-2_amd64.deb /tmp/
      - run:
          name: upload
          command: |
            aws s3 cp /tmp/hoge-${CIRCLE_TAG}-1.x86_64.rpm s3://rpm-mirror/hoge/hoge-${CIRCLE_TAG}-1.x86_64.rpm
            aws s3 cp /tmp/hoge_0${CIRCLE_TAG}-2_amd64.deb s3://rpm-mirror/hoge/hoge_0${CIRCLE_TAG}-2_amd64.deb
      - run:
          name: setup git
          command: |
            yum install git -y
            git config --global user.email "email@com"
            git config --global user.name "username"
            echo -e "Host ghe.hoge.com\n\tStrictHostKeyChecking no\n" > ${HOME}/.ssh/config
            git checkout master
      - run:
          name: change README.md for install command
          command: |
            sed -i -e "s/v[0-9].[0-9].[0-9]/${CIRCLE_TAG}/g" README.md
      - run:
          name: git push
          command: |
            git add --all . && git commit -m "[ci skip] release ${CIRCLE_TAG}"
            git push -u origin master

workflows:
  version: 2
  build-workflow:
    jobs:
      - release:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /v[0-9]+(\.[0-9]+)*(-.*)*/
ツリー
.
├── hoge.go
└── rpmbuild
    ├── SOURCES
    │   └── hoge.service
    └── SPECS
        └── hoge.spec