Skip to content

Commit

Permalink
Manage CLI apps on linux packages in addition of Service Apps #24
Browse files Browse the repository at this point in the history
  • Loading branch information
hdsdi3g committed Dec 23, 2023
1 parent 8d36205 commit b983769
Show file tree
Hide file tree
Showing 21 changed files with 1,236 additions and 100 deletions.
14 changes: 11 additions & 3 deletions .github/workflows/install-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,19 @@ jobs:
run: sudo apt-get install -y --no-install-recommends man xmlstarlet git wget tar nsis
- name: Prepare temp dir for internal tests
run: mkdir -p test/temp
- name: Run internal DEB test
- name: Run internal make DEB test
run: make-springboot-deb test/demospringboot test/temp
- name: Run internal RPM test
- name: Run internal make DEB CLI test
run: make-springboot-deb test/democlispringboot test/temp
- name: Install internal DEB CLI test
run: sudo dpkg -i test/temp/democlispringboot-0.0.1-SNAPSHOT.deb
- name: Run internal DEB CLI test
run: democlispringboot A B
- name: Run internal make RPM test
run: make-springboot-rpm test/demospringboot test/temp
- name: Run internal make RPM CLI test
run: make-springboot-rpm test/democlispringboot test/temp
- name: Prepare fake WinSW
run: sudo sh -c 'echo "Empty" > /usr/lib/linux-springboot-packager/templates/WinSW-x64.exe'
- name: Run internal EXE test
- name: Run internal make EXE test
run: make-springboot-exe test/demospringboot test/temp
48 changes: 39 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This script collection will create:
- a [DEB package](man-make-springboot-deb.md)
- a [Windows self installer](man-make-springboot-exe.md) (via [NSIS](https://sourceforge.net/projects/nsis/) and [WinSW](https://github.com/winsw/winsw))

For a **Spring Boot** project, runned as service, and build npm/front during packaging.
For a **Spring Boot** project, runned as service, or as command line interface (CLI / shell), and build npm/front during packaging.

Via _bash_, on Linux (RHEL/Debian) and Windows/WSL, not tested on macOS.

Expand Down Expand Up @@ -42,23 +42,24 @@ For build RPMs and/or DEB files, you will need, in addition to `maven` and `java

The builded DEB/RPM will run some install/uninstall scripts and do a few things, apart from that, it's a classic, non-signed DEB and RPM files.

The setup script check the presence of `bash`, `man`, `useradd`, and `systemctl`, and will deploy:
The setup script check the presence of `bash`, `man`, `useradd` (not for CLI), and `systemctl` (idem), and will deploy:
- A man file ([template here](src/usr/lib/linux-springboot-packager/templates/template-man.md)), as `man artifactId`
- some example files:
- some example files (not for CLI):
- An configuration file (`application.yml`)
- An configuration log file (`log4j2.xml` or `logback.xml`)
- An default file
- The application `jar` file
- A `Systemd` service file, deployed, ready to run
- A `Systemd` service file, deployed, ready to run (not for CLI)
- A command line runner (only for CLI)
- THIRD-PARTY and LICENCE files if available.
- An user/group and home dir for this user, as service name, to run the created service.
- A log directory ready to get log files
- An user/group and home dir for this user, as service name, to run the created service (not for CLI).
- A log directory ready to get log files (not for CLI)

All templates are in the `src/usr/lib/linux-springboot-packager/templates` directory.

Java presence will _not be_ checked by the installer. The default service file will expect to found it in `/usr/bin/java`. Change it as you what after setup.

Before deploy files, the service will be stopped (if exists and if running). After deploy files, it will be enabled, at boot, but not started.
Before deploy files, the service will be stopped (if exists and if running). After deploy files, it will be enabled, at boot, but not started (not for CLI).

Run the setup with:

Expand All @@ -85,7 +86,7 @@ sudo rpm -e <artifactid>
sudo rpm -e --allmatches <artifactid>
```

You can run manually with like:
You can run manually service with:

```bash
runuser -u <SERVICE_NAME> \
Expand All @@ -94,6 +95,33 @@ runuser -u <SERVICE_NAME> \
--spring.config.location=/etc/<SERVICE_NAME>/application.yml
```

And can run CLI with:
```bash
<artifactId> [params] [...]
```

## CLI or Service mode

By default, all service options (systemd, user, logs...) will be setup.

To switch to CLI mode, just add a POM proprerty on project pom (or it's ancestry) as:

```xml
<properties>
<linux-springboot-packager.kind>cli</linux-springboot-packager.kind>
</properties>
```

And you **MUST** provide a **MAN** page. Free feel to generate it as you want. The _first_ `.man` file founded on project directory will be used. This call will be done after generate JAR with Maven, so you can link `mvn package` and *man* generation.

On Service building, the man page will be provided (see `template-man.md`).

On all cases, the man page will be displayed with:

```bash
man <artifactId>
```

## make-springboot-exe

Executable files, and uninstaller will be placed on `C:\Program Files\<project name>`, and "variable files" like log and application.yml in `C:\ProgramData\<project name>`.
Expand All @@ -106,6 +134,8 @@ By default, the service run will need a valid `application.yml` and `log4j2.xml`

Actually, Windows builds don't support logback/log4j automatic switch as Linux does. `log4j.xml` still is here the only option now.

CLI option is not setup for Windows.

### Install the EXE files

Just run setup files with admin rights. If you use WinSW with a _.NET_ dependency, you should install it before.
Expand Down Expand Up @@ -139,6 +169,6 @@ Do a
./run-tests.bash
```

It will create a test DEB and RPM files for a demo java project on `test/demospringboot`, and optionnaly a EXE file.
It will create a test DEB and RPM files for a demo java project on `test/demospringboot` and `test/democlispringboot` for CLI option, and optionnaly a EXE file.

You will need all the mandatory DEB and RPM deps, optionnaly EXE deps.
13 changes: 10 additions & 3 deletions man-make-springboot-deb.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
% linux-springboot-packager

# NAME
make-springboot-deb - make a deb package from a Spring Boot application as a system service
make-springboot-deb - make a deb package from a Spring Boot application as a system service, or a CLI application.

# SYNOPSIS
make-springboot-deb *&lt;PROJECT&gt;* *[&lt;TARGET&gt;]*

# DESCRIPTION
With the help of Maven, this app will compile the application jar, create man page, create and prepare SystemD service file with adduser scripts, prepare an configuration file sample, in an autonomous deb file.
With the help of Maven, this app will compile the application jar, create man page, create and prepare SystemD service file with adduser scripts (not for CLI), prepare an configuration file sample (not for CLI), deploy a bash runner (only for CLI), in an autonomous DEB file.

It don't manage a deb repository either a signature.

Expand Down Expand Up @@ -65,6 +65,12 @@ And should strongly define:
- `project/properties/java.version`
- `project/packaging`

Switch CLI mode with:

- `project/properties/linux-springboot-packager.kind` set on `cli`

On CLI mode, you must provide an **man** file in the project directory.

Optionally with npm, if your project have a `package.json` file on main dir. It will only run `npm install` before start maven package, only if a `package.json` is founded on the main project directory. On builded project side, **npm install** *should* run an **webpack** for a **production ready version front app** (minified, etc), and *should* put finals files on *src/main/resources/static*. Maven and Spring Boot will collects these files during back building. No checks will be done on this project

Optionally, your project should have a **LICENCE(|.txt|.TXT)** file on its root path.
Expand Down Expand Up @@ -106,6 +112,7 @@ All used file which can be included and/or adapted in the creation of the packag
| EXIT_CODE_CANT_FOUND_RPM_FILE_OUTPUT | 10 |
| EXIT_CODE_CANT_FOUND_APP_LOGGER | 11 |
| EXIT_CODE_CANT_FOUND_DEST_DIR | 12 |
| EXIT_CODE_CANT_FOUND_CLI_MAN | 13 |

# BUGS
Free feel to send issues to https://github.com/hdsdi3g/linux-springboot-packager/issues.
Expand All @@ -122,4 +129,4 @@ This application was writted by **hdsdi3g**; see on GitHub https://github.com/hd
This document was transformed by *pandoc* from the original markdown documentation file.

# COPYRIGHT
Copyright (C) hdsdi3g for hd3g.tv 2022, under the **GNU General Public License v3+**
Copyright (C) hdsdi3g for hd3g.tv 2022-2023, under the **GNU General Public License v3+**
1 change: 1 addition & 0 deletions man-make-springboot-exe.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ All used file which can be included and/or adapted in the creation of the packag
| EXIT_CODE_CANT_FOUND_RPM_FILE_OUTPUT | 10 |
| EXIT_CODE_CANT_FOUND_APP_LOGGER | 11 |
| EXIT_CODE_CANT_FOUND_DEST_DIR | 12 |
| EXIT_CODE_CANT_FOUND_CLI_MAN | 13 |

# BUGS
Free feel to send issues to https://github.com/hdsdi3g/linux-springboot-packager/issues.
Expand Down
12 changes: 9 additions & 3 deletions man-make-springboot-rpm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
% linux-springboot-packager

# NAME
make-springboot-rpm - make a RPM package from a Spring Boot application as a system service
make-springboot-rpm - make a RPM package from a Spring Boot application as a system service, or a CLI application.

# SYNOPSIS
make-springboot-rpm *&lt;PROJECT&gt;* *[&lt;TARGET&gt;]*

# DESCRIPTION
With the help of Maven, this app will compile the application jar, create man page, create and prepare SystemD service file with adduser scripts, prepare an configuration file sample, in an autonomous RPM file.
With the help of Maven, this app will compile the application jar, create man page, create and prepare SystemD service file with adduser scripts (not for CLI), prepare an configuration file sample (not for CLI), deploy a bash runner (only for CLI), in an autonomous RPM file.

It don't manage a RPM repository either a signature.

Expand Down Expand Up @@ -65,6 +65,12 @@ And should strongly define:
- `project/properties/java.version`
- `project/packaging`

Switch CLI mode with:

- `project/properties/linux-springboot-packager.kind` set on `cli`

On CLI mode, you must provide an **man** file in the project directory.

Optionally with npm, if your project have a `package.json` file on main dir. It will only run `npm install` before start maven package, only if a `package.json` is founded on the main project directory. On builded project side, **npm install** *should* run an **webpack** for a **production ready version front app** (minified, etc), and *should* put finals files on *src/main/resources/static*. Maven and Spring Boot will collects these files during back building. No checks will be done on this project

Optionally, your project should have a **LICENCE(|.txt|.TXT)** file on its root path.
Expand Down Expand Up @@ -122,4 +128,4 @@ This application was writted by **hdsdi3g**; see on GitHub https://github.com/hd
This document was transformed by *pandoc* from the original markdown documentation file.

# COPYRIGHT
Copyright (C) hdsdi3g for hd3g.tv 2022, under the **GNU General Public License v3+**
Copyright (C) hdsdi3g for hd3g.tv 2022-2023, under the **GNU General Public License v3+**
23 changes: 23 additions & 0 deletions run-tests.bash
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ if [ -d "$TEST_TEMP_DIR" ]; then
fi
mkdir -p "$TEST_TEMP_DIR";

###################
# DEB CLI TEST ZONE
###################
"$PREFIX/usr/bin/make-springboot-deb" "$TESTROOT/democlispringboot" "$TEST_TEMP_DIR"

EXPECTED_TEST_PACKAGE="$TEST_TEMP_DIR/democlispringboot-0.0.1-SNAPSHOT.deb";
if [ ! -f "$EXPECTED_TEST_PACKAGE" ]; then
echo "Error: can't found builded package: $EXPECTED_TEST_PACKAGE" >&2;
exit 1;
fi

################
# DEB TEST ZONE
################
Expand Down Expand Up @@ -101,6 +112,18 @@ assert_contain "/etc/systemd/system/demospringboot.service";
assert_contain "/usr/local/share/man/man8/demospringboot.8";
assert_contain "/var/log/demospringboot";

###################
# RPM CLI TEST ZONE
###################

"$PREFIX/usr/bin/make-springboot-rpm" "$TESTROOT/democlispringboot" "$TEST_TEMP_DIR"

EXPECTED_TEST_PACKAGE="$TEST_TEMP_DIR/democlispringboot-0.0.1-SNAPSHOT.rpm";
if [ ! -f "$EXPECTED_TEST_PACKAGE" ]; then
echo "Error: can't found builded package: $EXPECTED_TEST_PACKAGE" >&2;
exit 1;
fi

################
# EXE TEST ZONE
################
Expand Down
79 changes: 51 additions & 28 deletions src/usr/bin/make-springboot-deb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def_linux_base_dir_vars;
def_linux_deb_base_dir_vars;
echo " * Def file/dir vars";
def_files_dir_vars;

echo " * Prepare DEB build dir";
prepare_deb_build_dir;

Expand All @@ -93,74 +92,98 @@ make_replace_list_vars;
echo " * Extract linux log conf";
extract_default_linux_log_conf;

echo " * Prepare man page";
make_man_page;
gzip -9n "$BUILD_DIR/$OUTPUT_MAN_FILE";
chmod 644 "$BUILD_DIR/$OUTPUT_MAN_FILE.gz"

echo " * Make service conf";
make_service_conf;

echo " * Make CLI runner";
make_bash_cli_runner;

echo " * Make Debian package files";
OUTPUT_CONTROL_FILE="$DEBIAN_DIR/control";
OUTPUT_CHANGELOG_FILE="$DEB_WORKING_DIR/$OUTPUT_DIR_DOC/changelog";
OUTPUT_COPYRIGHT_FILE="$DEB_WORKING_DIR/$OUTPUT_DIR_DOC/copyright";

sed -e "$REPLACE" < "$TEMPLATES_DIR/debian-control" > "$OUTPUT_CONTROL_FILE";
if [ "$IS_CLI" = true ]; then
sed -e "$REPLACE" < "$TEMPLATES_DIR/debian-control-cli" > "$OUTPUT_CONTROL_FILE";
else
sed -e "$REPLACE" < "$TEMPLATES_DIR/debian-control-service" > "$OUTPUT_CONTROL_FILE";
fi

sed -e "$REPLACE" < "$TEMPLATES_DIR/debian-changelog" > "$OUTPUT_CHANGELOG_FILE";
sed -e "$REPLACE" < "$TEMPLATES_DIR/debian-copyright" > "$OUTPUT_COPYRIGHT_FILE";

gzip -9n "$OUTPUT_CHANGELOG_FILE"
chmod 644 "$OUTPUT_CHANGELOG_FILE.gz"
chmod 644 "$OUTPUT_COPYRIGHT_FILE"

find "$DEB_WORKING_DIR/etc" -type f \
| sed -e "s~$DEB_WORKING_DIR/~/~g;" > "$DEBIAN_DIR/conffiles";
if [ "$IS_CLI" = false ]; then
find "$DEB_WORKING_DIR/etc" -type f \
| sed -e "s~$DEB_WORKING_DIR/~/~g;" > "$DEBIAN_DIR/conffiles";
fi

OUTPUT_PREINST_FILE="$DEBIAN_DIR/preinst";
OUTPUT_POSTINST_FILE="$DEBIAN_DIR/postinst";
OUTPUT_PRERM_FILE="$DEBIAN_DIR/prerm";
OUTPUT_POSTRM_FILE="$DEBIAN_DIR/postrm";

{
echo '#!/bin/sh';
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/stop-service.inc.sh";
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/create-user.inc.sh";
} > "$OUTPUT_PREINST_FILE";
if [ "$IS_CLI" = false ]; then
{
echo '#!/bin/sh';
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/stop-service.inc.sh";
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/create-user.inc.sh";
} > "$OUTPUT_PREINST_FILE";
chmod +x "$OUTPUT_PREINST_FILE";
fi

{
echo '#!/bin/sh';
echo "echo \"Enable service $ARTIFACTID with systemctl, but don't start it.\"";
echo "ln -sf $OUTPUT_SERVICE_FILE $OUTPUT_SERVICE_LINK";
echo "systemctl daemon-reload";
echo "systemctl enable $ARTIFACTID";
if [ "$IS_CLI" = false ]; then
echo "echo \"Enable service $ARTIFACTID with systemctl, but don't start it.\"";
echo "ln -sf $OUTPUT_SERVICE_FILE $OUTPUT_SERVICE_LINK";
echo "systemctl daemon-reload";
echo "systemctl enable $ARTIFACTID";
echo "chown $ARTIFACTID:$ARTIFACTID \"$OUTPUT_DIR_LOG\"";
echo "chmod 0700 \"$OUTPUT_DIR_LOG\"";
fi
echo "mandb -q";
echo "chown $ARTIFACTID:$ARTIFACTID \"$OUTPUT_DIR_LOG\"";
echo "chmod 0700 \"$OUTPUT_DIR_LOG\"";
echo "echo \"Use man $ARTIFACTID to get setup informations.\"";
} > "$OUTPUT_POSTINST_FILE";
chmod +x "$OUTPUT_POSTINST_FILE";

{
echo '#!/bin/sh';
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/stop-service.inc.sh";
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/disable-service.inc.sh";
} > "$OUTPUT_PRERM_FILE";
if [ "$IS_CLI" = false ]; then
{
echo '#!/bin/sh';
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/stop-service.inc.sh";
sed -e "$REPLACE/^[ \t]*#/d;/^$/d" < "$TEMPLATES_DIR/disable-service.inc.sh";
} > "$OUTPUT_PRERM_FILE";
chmod +x "$OUTPUT_PRERM_FILE";
fi

{
echo '#!/bin/sh';
echo "mandb -q";
echo "systemctl daemon-reload";
if [ "$IS_CLI" = false ]; then
echo "systemctl daemon-reload";
fi
} > "$OUTPUT_POSTRM_FILE";

chmod +x "$OUTPUT_PREINST_FILE";
chmod +x "$OUTPUT_POSTINST_FILE";
chmod +x "$OUTPUT_PRERM_FILE";
chmod +x "$OUTPUT_POSTRM_FILE";

find "$DEB_WORKING_DIR" -type d -exec chmod 755 {} +
find "$DEB_WORKING_DIR/etc" -type f -exec chmod 644 {} +
find "$DEB_WORKING_DIR/etc" -type f -name application.yml -exec chmod 600 {} +
if [ -d "$DEB_WORKING_DIR/etc" ]; then
find "$DEB_WORKING_DIR/etc" -type f -exec chmod 644 {} +
find "$DEB_WORKING_DIR/etc" -type f -name application.yml -exec chmod 600 {} +
fi
find "$DEB_WORKING_DIR/usr" -type f -exec chmod 644 {} +

if [ -d "$DEB_WORKING_DIR/usr/bin" ]; then
find "$DEB_WORKING_DIR/usr/bin" -type f -exec chmod 755 {} +
fi

if [ "${SKIP_MAKE:-"0"}" = "0" ]; then
dpkg-deb --root-owner-group --build "$DEB_WORKING_DIR"
DEB_FILE="$DEB_WORKING_DIR.deb";
Expand All @@ -177,7 +200,7 @@ if [ "${SKIP_MAKE:-"0"}" = "0" ]; then

lintian --fail-on warning \
--no-tag-display-limit \
--suppress-tags debian-changelog-file-missing-or-wrong-name,non-standard-file-perm,unknown-java-class-version,maintainer-script-calls-systemctl,systemd-service-in-odd-location,maintainer-script-ignores-errors \
--suppress-tags debian-changelog-file-missing-or-wrong-name,non-standard-file-perm,unknown-java-class-version,maintainer-script-calls-systemctl,systemd-service-in-odd-location,maintainer-script-ignores-errors,bad-whatis-entry \
"$FINAL_DEB_FILE"

echo "";
Expand Down
Loading

0 comments on commit b983769

Please sign in to comment.