From: Jyrki Aaltonen Date: Fri, 22 Mar 2019 11:40:05 +0000 (+0200) Subject: Initial commit X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;ds=sidebyside;h=refs%2Fchanges%2F59%2F659%2F1;p=ta%2Fstart-menu.git Initial commit Change-Id: I4b7f96a1ed236e8b98852882599d65cb67a4cf1e Signed-off-by: Jyrki Aaltonen --- diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/services/start-menu.service b/services/start-menu.service new file mode 100644 index 0000000..8cec895 --- /dev/null +++ b/services/start-menu.service @@ -0,0 +1,26 @@ +# Copyright 2019 Nokia + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[Unit] +Description=Start Menu service +After=local-fs.target syslog-ng.service multi-user.target +Requires=local-fs.target syslog-ng.service multi-user.target + +[Service] +Type=forking +ExecStart=/opt/start-menu/start_menu_service.sh +ExecStopPost=/usr/bin/systemctl disable start-menu --no-block + +[Install] +WantedBy=multi-user.target diff --git a/src/os_net_config_template.yml b/src/os_net_config_template.yml new file mode 100644 index 0000000..e98aff1 --- /dev/null +++ b/src/os_net_config_template.yml @@ -0,0 +1,23 @@ +# Copyright 2019 Nokia + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +network_config: + - type: interface + name: PHYDEV + use_dhcp: false + addresses: + - ip_netmask: IPADDR + routes: + - ip_netmask: DEFAULTROUTE + next_hop: GATEWAY diff --git a/src/os_net_config_vlan_template.yml b/src/os_net_config_vlan_template.yml new file mode 100644 index 0000000..67b6d1a --- /dev/null +++ b/src/os_net_config_vlan_template.yml @@ -0,0 +1,24 @@ +# Copyright 2019 Nokia + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +network_config: + - type: vlan + vlan_id: VLANID + device: PHYDEV + use_dhcp: false + addresses: + - ip_netmask: IPADDR + routes: + - ip_netmask: DEFAULTROUTE + next_hop: GATEWAY diff --git a/src/start_menu.sh b/src/start_menu.sh new file mode 100755 index 0000000..3e17e81 --- /dev/null +++ b/src/start_menu.sh @@ -0,0 +1,371 @@ +#!/bin/bash + +# Copyright 2019 Nokia + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +DEFAULT_WIDTH=120 +DEFAULT_HEIGHT=40 + +USER_CONFIG_FILE=/etc/userconfig/user_config.yaml +LOG_DIR=/var/log/start-menu +RC_FILE=/tmp/start_menu.rc +DEBUG_FLAG=/opt/start-menu/config/__debug + +function ask_for_device() +{ + device=$1 + shift 1 + + declare -a devices + devices=($(ls /sys/class/net)) + radiolist="" + if [ -z "$device" ]; then + device=${devices[0]} + fi + for dev in ${devices[*]}; do + if [ "$dev" != "lo" ]; then + mac=$(cat /sys/class/net/$dev/address) + if [ "$dev" == "$device" ]; then + status="on" + else + status="off" + fi + radiolist="${radiolist}$dev $mac $status " + fi + done + device=$(dialog --clear --stdout --no-cancel --radiolist "Select network device:" 0 $DEFAULT_WIDTH 10 $radiolist) + RC=$? + if [ "$RC" -eq 0 ]; then + echo $device + fi + + return $RC +} + +function ask_for_ip() +{ + device=$1 + address=$2 + + rc=1 + while [ "$rc" -ne 0 ]; do + address=$(dialog --clear --stdout --inputbox "Enter IP address for $device (CIDR format):" 0 $DEFAULT_WIDTH $address) + if [ "$?" -ne 0 ]; then + return 1 + fi + + if [ -z "$address" ]; then + dialog --clear --stdout --msgbox "No address entered" 0 0 + else + # check if valid address + err=$(ipcalc -c $address 2>&1) + rc=$? + if [ "$rc" -ne 0 ]; then + dialog --clear --stdout --msgbox "$err" 0 0 + else + # check if network address (prefix given) + if [[ $address != */* ]]; then + dialog --clear --stdout --msgbox "No CIDR prefix given" 0 0 + fi + fi + fi + done + + echo $address + + return 0 +} + +function ask_for_gateway() +{ + device=$1 + gateway=$2 + + rc=1 + while [ "$rc" -ne 0 ]; do + gateway=$(dialog --clear --stdout --inputbox "Enter gateway address for $device:" 0 $DEFAULT_WIDTH $gateway) + if [ "$?" -ne 0 ]; then + return 1 + fi + + if [ -z "$gateway" ]; then + dialog --clear --stdout --msgbox "No address entered" 0 0 + else + err=$(ipcalc -c $gateway 2>&1) + rc=$? + if [ "$rc" -ne 0 ]; then + dialog --clear --stdout --msgbox "$err" 0 0 + fi + fi + done + + echo $gateway + + return 0 +} + +function ask_for_vlan() +{ + device=$1 + vlanid=$2 + + rc=255 + while [ "$rc" -eq 255 ]; do + dialog --clear --stdout --yesno "Set VLAN for $device?" 0 0 + rc=$? + if [ "$rc" -eq 0 ]; then + id_rc=1 + while [ "$id_rc" -ne 0 ]; do + vlanid=$(dialog --clear --stdout --inputbox "Enter VLAN ID:" 0 $DEFAULT_WIDTH $vlanid) + id_rc=$? + if [ "$id_rc" -eq 255 ]; then + return 1 + fi + done + fi + done + + echo $vlanid +} + +function wait_for_gateway() +{ + GATEWAY=$1 + for i in {1..180}; do + echo "$(date)" + if [[ $GATEWAY = *:* ]]; then + ping -6 -w 1 -c 1 $GATEWAY + else + ping -w 1 -c 1 $GATEWAY + fi + if [ "$?" -eq 0 ]; then + echo -e "\nping to network gateway OK.\n" + return 0 + else + sleep 1 + fi + done + + echo -e "\nping to network gateway failed." + + if [ "$vlanid" != "" ] ; then + ip link delete vlan$vlanid + rm -f /etc/sysconfig/network-scripts/*vlan$vlanid* + else + ip a delete $address dev $device + rm -f /etc/sysconfig/network-scripts/*$device* + fi + ip link set $device down + dialog --colors --stdout --clear --cr-wrap --title "ERROR" \ + --msgbox '\n\Z1 Can not ping gateway! \n Shut down link!' 8 29 +} + +function run_external_network_create_command() +{ + local if_status + local max_retries + local i + + echo -e "Creating external network." + echo -e " Device : $device" + echo -e "Address : $address" + echo -e "Gateway : $gateway" + [ -z "$vlanid" ] || echo -e " VlanId : $vlanid" + + mkdir -p /etc/os-net-config/ + if [[ $gateway = *:* ]]; then + defaultroute=::/0 + else + defaultroute=0.0.0.0/0 + fi + if [ "$vlanid" != "" ]; then + sed "s|PHYDEV|${device}|g;s|VLANID|${vlanid}|g;s|IPADDR|${address}|g;s|DEFAULTROUTE|${defaultroute}|g;s|GATEWAY|${gateway}|g" os_net_config_vlan_template.yml > /etc/os-net-config/config.yaml + else + sed "s|PHYDEV|${device}|g;s|IPADDR|${address}|g;s|DEFAULTROUTE|${defaultroute}|g;s|GATEWAY|${gateway}|g" os_net_config_template.yml > /etc/os-net-config/config.yaml + fi + + /bin/os-net-config + rm -rf /etc/os-net-config/config.yaml + + max_retries=180 + i=0 + while [ $i -lt $max_retries ]; do + echo "Waiting for interface ${device} to come up..." + if_status="$(cat /sys/class/net/${device}/operstate)" + [ "$if_status" = "up" ] && break + sleep 1; + i=$((i+1)) + done + echo "Link status of interface $device : $if_status" + [ "$if_status" != "up" ] && \ + dialog --colors --stdout --clear --cr-wrap --title "ERROR" --msgbox '\n\Z1 Link does not come up!' 8 29 +} + +function set_external_network() +{ + device=$1 + address=$2 + gateway=$3 + vlanid=$4 + shift 4 + + device=$(ask_for_device "$device") + if [ "$?" -ne 0 ]; then + return 1 + fi + + address=$(ask_for_ip "$device" "$address") + if [ "$?" -ne 0 ]; then + return 1 + fi + + addr_no_mask=$(awk -F\/ '{print $1}' <<< "$address") + + gateway=$(ask_for_gateway "$device" "$gateway") + if [ "$?" -ne 0 ]; then + return 1 + fi + + vlanid=$(ask_for_vlan "$device" "$vlanid") + if [ "$?" -ne 0 ]; then + return 1 + fi + + # echo is an ugly hack to workaround dialog bug (ok button loses two first lines of output) + (echo -e -n "\n\n"; run_external_network_create_command 2>&1) | tee $LOG_DIR/external_net_create.log | dialog --clear --stdout --progressbox "Setting up external network:" $DEFAULT_HEIGHT $DEFAULT_WIDTH + + # echo is an ugly hack to workaround dialog bug (ok button loses two first lines of output) + + (echo -e -n "\n\n"; wait_for_gateway $gateway 2>&1) | tee $LOG_DIR/wait_for_gateway.log | sed -ru "s/.{$[DEFAULT_WIDTH-4]}/&\n /g" | dialog --clear --stdout --programbox "Verify ping to gateway:" $DEFAULT_HEIGHT $DEFAULT_WIDTH + +} + + +function installation_start() +{ + local config_file + config_file=${1} + local mode + mode=${2} + if validate_user_config ${config_file}; then + pushd /opt/cmframework/scripts/ + if ./bootstrap.sh ${config_file} ${mode}; then + echo -e "################################################################################" + echo -e "######################### All Done!! ########################################" + echo -e "################################################################################" + return 0 + else + echo -e "Installation failed!!!" + fi + else + echo -e "Validation failed!!!" + return 1 + fi +} + +function start_install() +{ + local config_file + config_file=${1} + + (echo -e -n "\n\n";installation_start ${config_file} --install 2>&1) | tee $LOG_DIR/start_install.log +} + +function validate_user_config() +{ + local config_file + config_file=${1} + if [ -e ${config_file} ]; then + return 0 + else + return 1 + fi +} + +function main_menu() +{ + echo -e "Starting main menu" + selection="0" + while [ "$selection" != "X" ]; do + rc=255 + while [ "$rc" -ne 0 ]; do + rm -f /tmp/dialog.out + selection=$(dialog --clear --stdout --no-cancel --menu "Installation" 0 0 10 \ + 0 "Set external network" \ + 1 "Start installation") + rc=$? + done + case $selection in + 0) + set_external_network + ;; + 1) + if start_install ${USER_CONFIG_FILE}; then + echo "0" > $RC_FILE + exit 0 + else + /usr/bin/bash + fi + ;; + *) + ;; + esac + done +} + +function create_config_user() +{ + mkdir -p /etc/userconfig/ + userconfig_passwd=$(python -c "import crypt, getpass, pwd; print crypt.crypt('userconfig')") + useradd --home-dir=/etc/userconfig/ --password=$userconfig_passwd userconfig + chown userconfig:userconfig /etc/userconfig +} + +function delete_config_user() +{ + pkill -u userconfig + userdel userconfig +} + +while [[ "$(systemctl is-system-running)" == "starting" ]]; do + echo "start-menu waiting for systemctl to finish startup..." + sleep 10 +done + +clear + +# disable kernel logs to console +echo 3 > /proc/sysrq-trigger + +mkdir -p $LOG_DIR + +if [ -e $DEBUG_FLAG ]; then + logger "start-menu in debug mode" + /usr/bin/bash +fi + +if [ -e ${USER_CONFIG_FILE} ]; then + if start_install ${USER_CONFIG_FILE}; then + echo "Install succeeded" + echo "0" > $RC_FILE + exit 0 + else + echo "Install failed, check logs ($LOG_DIR)" + echo "1" > $RC_FILE + /usr/bin/bash + exit 1 + fi +else + main_menu +fi diff --git a/src/start_menu_service.sh b/src/start_menu_service.sh new file mode 100755 index 0000000..4bd92b7 --- /dev/null +++ b/src/start_menu_service.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Copyright 2019 Nokia + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +export TERM=linux +export HOME=/root/ + +# Run this only if it is installation host +if [ -e /opt/images/guest-image.img ]; then + cd /opt/start-menu + openvt -s -w ./start_menu.sh & +fi diff --git a/start-menu.spec b/start-menu.spec new file mode 100644 index 0000000..76a2e04 --- /dev/null +++ b/start-menu.spec @@ -0,0 +1,67 @@ +# Copyright 2019 Nokia + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Name: start-menu +Version: %{_version} +Release: 1%{?dist} +Summary: Contains code for start menu. +License: %{_platform_licence} +Source0: %{name}-%{version}.tar.gz +Vendor: %{_platform_vendor} +BuildArch: noarch + +Requires: dialog +BuildRequires: rsync + +%description +This RPM contains code and support files for installing start menu + +%prep +%autosetup + +%build + +%install +mkdir -p %{buildroot}/opt/start-menu/ +mkdir -p %{buildroot}/etc/userconfig/ +mkdir -p %{buildroot}/usr/lib/systemd/system/ + +rsync -av src/* %{buildroot}/opt/start-menu +rsync -av services/start-menu.service %{buildroot}/usr/lib/systemd/system/start-menu.service + +find + +%files +%defattr(0755,root,root,0755) +/opt/start-menu* +/etc/userconfig +%attr(0644, root, root) /usr/lib/systemd/system/start-menu.service + +%pre + +%post +# Only enable the service, if it is a new installation or it will break the upgrade +if [ $1 -eq 1 ] +then + systemctl enable start-menu.service +fi + +%preun + +%postun +systemctl disable start-menu.service + +%clean +rm -rf %{buildroot} +