summarylogtreecommitdiffstats
path: root/pxe-boot-admin.install
blob: 51f11ee177d3c96b3e2b2e2ced0fa04b6d99a4cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# In your pxe-boot-admin.install file

APP_NAME="pxe-boot-admin"
APP_USER="pxebootadmin"
APP_GROUP="pxebootadmin"
APP_HOME="/opt/${APP_NAME}"
CERT_DIR_BASE="/etc/ssl"
CERT_DIR="${CERT_DIR_BASE}/certs/${APP_NAME}"
KEY_DIR="${CERT_DIR_BASE}/private/${APP_NAME}"
CERT_FILE="${CERT_DIR}/${APP_NAME}.pem"
KEY_FILE="${KEY_DIR}/${APP_NAME}.key"
ENV_CONFIG_DIR="/etc/${APP_NAME}"
ENV_CONFIG_FILE="${ENV_CONFIG_DIR}/environment"
ENV_CONFIG_EXAMPLE_FILE="${ENV_CONFIG_DIR}/environment.example"

_msg() {
  echo -e "\033[0;32m==>\033[0m \033[1m$1\033[0m"
}

_warn() {
  echo -e "\033[0;33m==> WARNING:\033[0m \033[1m$1\033[0m"
}

# Shared function for creating user/group and setting initial permissions
_setup_user_group_and_perms() {
  _msg "Checking/Creating user '${APP_USER}' and group '${APP_GROUP}' for ${APP_NAME}..."
  getent group "${APP_GROUP}" &>/dev/null || groupadd -r "${APP_GROUP}"
  if ! getent passwd "${APP_USER}" &>/dev/null; then
    useradd -r -g "${APP_GROUP}" -d "${APP_HOME}" -s /usr/bin/nologin "${APP_USER}"
  fi

  _msg "Setting ownership for application directory: ${APP_HOME}"
  # Ensure base directory exists and is owned correctly before chowning recursively
  mkdir -p "${APP_HOME}"
  chown -R "${APP_USER}:${APP_GROUP}" "${APP_HOME}"
}

# Shared function for certificate setup
_setup_certificates() {
  _msg "Checking SSL certificate status for ${APP_NAME}..."
  mkdir -p "${CERT_DIR}"
  mkdir -p "${KEY_DIR}"
  # Ensure base directories have correct general permissions
  # (Usually set by openssl/nginx packages, but good to be defensive)
  # chmod 755 "${CERT_DIR_BASE}" # Might be too broad
  chmod 755 "${CERT_DIR_BASE}/certs"
  chmod 700 "${CERT_DIR_BASE}/private" # private should be restrictive
  chmod 755 "${CERT_DIR}"
  chmod 700 "${KEY_DIR}"

  if [ ! -f "${CERT_FILE}" ] || [ ! -f "${KEY_FILE}" ]; then
    _msg "Generating self-signed SSL certificate for ${APP_NAME} (CN=localhost)..."
    openssl req -x509 -nodes -newkey rsa:2048 -sha256 \
      -days 3650 \
      -keyout "${KEY_FILE}" \
      -out "${CERT_FILE}" \
      -subj "/C=PL/ST=Mazowieckie/L=Warsaw/O=${APP_NAME} (SelfSigned)/CN=localhost"
    chmod 644 "${CERT_FILE}"
    chmod 600 "${KEY_FILE}" # Restrict private key access
    _msg "SSL Certificates generated."
  else
    _msg "SSL certificate files already exist. Skipping generation."
  fi
}

# Shared function for environment file guidance
_check_environment_file_guidance() {
  mkdir -p "${ENV_CONFIG_DIR}"
  # /etc/pxe-boot-admin directory itself owned by root
  chown root:root "${ENV_CONFIG_DIR}"
  chmod 750 "${ENV_CONFIG_DIR}" # Only root and members of root group can enter (or just root if 700)

  if [ ! -f "${ENV_CONFIG_FILE}" ] && [ -f "${ENV_CONFIG_EXAMPLE_FILE}" ]; then
    _warn "Environment configuration file ${ENV_CONFIG_FILE} not found."
    _warn "A template has been installed at ${ENV_CONFIG_EXAMPLE_FILE}."
    _warn "Please copy it to ${ENV_CONFIG_FILE}, fill in your secrets, and set permissions:"
    _warn "  sudo cp ${ENV_CONFIG_EXAMPLE_FILE} ${ENV_CONFIG_FILE}"
    _warn "  sudo chown ${APP_USER}:${APP_GROUP} ${ENV_CONFIG_FILE}" # App user needs to read it
    _warn "  sudo chmod 640 ${ENV_CONFIG_FILE}"                     # Secure: user-read, group-read, no-other
    _warn "  sudo nano ${ENV_CONFIG_FILE}"                          # Edit the file
  elif [ ! -f "${ENV_CONFIG_FILE}" ]; then
     _warn "Environment configuration file ${ENV_CONFIG_FILE} not found and no example was installed to copy."
     _warn "Please create it at ${ENV_CONFIG_FILE} with your application secrets, then chown/chmod it appropriately (e.g., chown ${APP_USER}:${APP_GROUP} and chmod 640)."
  fi
}

# Helper function to ensure APP_USER is in /etc/at.allow
_ensure_at_allow_user() {
  local at_allow_file="/etc/at.allow"
  if [ ! -f "$at_allow_file" ]; then
    touch "$at_allow_file"
    chmod 644 "$at_allow_file"
  fi
  if ! grep -Fxq "$APP_USER" "$at_allow_file"; then
    echo "$APP_USER" >> "$at_allow_file"
    _msg "Added $APP_USER to $at_allow_file for at daemon access."
  else
    _msg "$APP_USER is already present in $at_allow_file."
  fi
}
# Helper function to create data folder in /opt/{$APP_NAME}
_create_data_folder() {
  if [ ! -d "/opt/${APP_NAME}" ]; then
    mkdir -p "/opt/${APP_NAME}"
    chown "${APP_USER}:${APP_GROUP}" "/opt/${APP_NAME}"
    chmod 750 "/opt/${APP_NAME}"
  fi
}

post_install() {
  _setup_user_group_and_perms
  _setup_certificates
  _check_environment_file_guidance
  _ensure_at_allow_user
  _create_data_folder

  systemctl daemon-reload
  systemctl enable --now atd.service
  systemctl start --now atd.service

  _msg "To complete the setup, please:"
  _msg "1. If you haven't already, populate ${ENV_CONFIG_FILE} with your secrets (ensure correct ownership and permissions as noted above)."
  _msg "2. Enable and start the necessary services:"
  _msg "   sudo systemctl enable --now nginx.service  (if not already running)"
  _msg "   sudo systemctl enable --now ${APP_NAME}.service"
  _msg "3. Ensure your firewall allows traffic on ports 80 (HTTP) and 443 (HTTPS)."

  # Check if nginx.conf includes conf.d/*.conf
  local nginx_conf="/etc/nginx/nginx.conf"
  if [ -f "$nginx_conf" ]; then
    if grep -q "include \/etc\/nginx\/conf.d\/\\*.conf;" "$nginx_conf"; then
      _msg "nginx.conf is correctly set to include /etc/nginx/conf.d/*.conf."
    else
      _warn "nginx.conf does not include /etc/nginx/conf.d/*.conf in the http block."
      _warn "Please ensure the following line is present inside the 'http' block in /etc/nginx/nginx.conf:"
      _warn "  include /etc/nginx/conf.d/*.conf;"
    fi
  else
    _warn "/etc/nginx/nginx.conf not found. Please ensure your nginx configuration includes /etc/nginx/conf.d/*.conf in the http block."
  fi

  if command -v nginx > /dev/null; then
    # Test nginx config after all setup is done.
    if sudo -u "${APP_USER}" nginx -t &>/dev/null || nginx -t &>/dev/null; then # Try as app user or root
      _msg "Nginx configuration test successful."
    else
      _warn "Nginx configuration test failed. Please review /etc/nginx/conf.d/${APP_NAME}.conf and Nginx logs after starting services."
    fi
  fi
}

post_upgrade() {
  # Ensure user/group and permissions are still correct
  _setup_user_group_and_perms
  # Ensure certificates exist, or regenerate them if missing
  _setup_certificates
  _ensure_at_allow_user

  systemctl daemon-reload
  systemctl restart atd.service

  if [ -f "${ENV_CONFIG_EXAMPLE_FILE}.pacnew" ]; then
    _warn "A new version of the example environment file has been installed as ${ENV_CONFIG_EXAMPLE_FILE}.pacnew."
    _warn "Please review it for any changes you might want to incorporate into your ${ENV_CONFIG_FILE}."
  else
    # Check env file guidance in case it was missed or the file was removed
    _check_environment_file_guidance
  fi

  _msg "Package upgraded. You might need to restart the service:"
  _msg "  sudo systemctl restart ${APP_NAME}.service"
  _msg "If Nginx configuration was part of the upgrade (check .pacnew for nginx conf):"
  _msg "  sudo systemctl reload nginx.service"
}

pre_remove() {
  _msg "Stopping and disabling ${APP_NAME} service..."
  systemctl stop "${APP_NAME}.service" || true
  systemctl disable "${APP_NAME}.service" || true
}

post_remove() {
  _msg "Removing user '${APP_USER}' and group '${APP_GROUP}'..."
  # Only remove user if no other packages or files depend on it (tricky to check automatically)
  # For simplicity, this script attempts removal. If it fails, admin might need to intervene.
  userdel "${APP_USER}" || _warn "Could not remove user ${APP_USER} (may not exist or still in use by other files/processes)."
  groupdel "${APP_GROUP}" || _warn "Could not remove group ${APP_GROUP} (may not exist or still in use by other users/files)."

  _msg "Removing SSL certificates for ${APP_NAME}..."
  rm -f "${KEY_FILE}" "${CERT_FILE}"
  rmdir --ignore-fail-on-non-empty "${KEY_DIR}" || _warn "Could not remove dir ${KEY_DIR} or it was not empty. Manual check may be needed."
  rmdir --ignore-fail-on-non-empty "${CERT_DIR}" || _warn "Could not remove dir ${CERT_DIR} or it was not empty. Manual check may be needed."

  _msg "Nginx configuration for ${APP_NAME} has been removed."
  _msg "You may want to manually reload Nginx if it was running: sudo systemctl reload nginx.service"
  _msg "The application directory ${APP_HOME} is removed by pacman."
  _msg "The environment configuration directory ${ENV_CONFIG_DIR} and its contents are NOT removed by this package."
  _msg "You can remove it manually if desired: sudo rm -rf ${ENV_CONFIG_DIR}"

  systemctl daemon-reload
}