With the installation of new tools on the app servers within the Stratos Datacenter, certain functionalities now necessitate graphical user interface (GUI) access.
Adjust the default runlevel on all App servers in Stratos Datacenter to enable GUI booting by default. It's imperative not to initiate a server reboot after completing this task.
Introduction
Managing system runlevels is a fundamental task for Linux system administrators. In modern Linux distributions using systemd, the traditional runlevel concept has been replaced with systemd targets. This guide demonstrates how to configure the default boot target to graphical mode across multiple servers without requiring immediate system reboots.
Understanding Systemd Targets and Runlevels
Systemd targets serve as synchronization points that group related services and units. The relationship between traditional runlevels and systemd targets is as follows:
| Runlevel | Systemd Target | Description |
|---|---|---|
| 0 | poweroff.target | System halt |
| 1 | rescue.target | Single-user mode |
| 3 | multi-user.target | Multi-user text mode |
| 5 | graphical.target | Multi-user with GUI |
| 6 | reboot.target | System reboot |
In this scenario, the App servers currently boot to multi-user.target (runlevel 3 - text mode) and need to be configured to boot to graphical.target (runlevel 5 - GUI mode).
Common Pitfall: Password Handling in Remote Execution
When executing multiple sudo commands remotely, a common issue arises where the password is only passed to the first sudo command. This results in authentication failures for subsequent commands.
Problematic Implementation
The following approach fails because the second sudo command receives no password input:
echo 'Password123' | ssh user@server "sudo -S systemctl set-default graphical.target && sudo -S systemctl get-default"
In this example, the first sudo command receives the password via the pipe, but the second sudo command has no password available and will prompt for input, causing the command to hang or fail.
Correct Implementation
The solution is to combine all commands into a single sudo session using either a shell wrapper or a heredoc approach. This ensures the password is passed once and all commands execute within the same privileged context.
Solution Methods
Method 1: Single Shell Session with Command Chaining
This method uses a shell wrapper to execute multiple commands within a single sudo session:
echo 'Password123' | ssh user@server "sudo -S bash -c 'systemctl set-default graphical.target && systemctl get-default'"
The bash -c wrapper creates a single shell process that executes both commands sequentially. The password is passed to the sudo command once, and both systemctl commands run with elevated privileges.
Method 2: Heredoc with Sudo Wrapper
The heredoc approach provides better readability for complex command sequences:
ssh user@server << 'EOF'
echo 'Password123' | sudo -S bash -c '
systemctl set-default graphical.target
systemctl get-default
'
EOF
This method is particularly useful when executing multiple commands or when the command sequence is lengthy and requires better formatting.
Method 3: Multiple Statements with Shell
This method chains multiple statements using a shell interpreter:
echo 'Password123' | ssh user@server "sudo -S sh -c 'systemctl set-default graphical.target && systemctl get-default'"
Using sh instead of bash provides compatibility with systems where bash is not the default shell.
Interactive Method
For administrators who prefer an interactive approach, the following steps can be performed on each server:
# 1. Connect to the server
ssh tony@stapp01 # or steve@stapp02 / banner@stapp03
# Enter password
# 2. Become root
sudo su -
# Enter password
# 3. Check current default target
systemctl get-default
# 4. Set default to graphical.target
systemctl set-default graphical.target
# 5. Verify the change
systemctl get-default
# 6. Check the symlink
ls -la /etc/systemd/system/default.target
# 7. Exit
exit
exit
Complete Implementation for Multiple Servers
Server Configuration Details
| Server | Username | Password |
|---|---|---|
| stapp01 | tony | Ir0nM@n |
| stapp02 | steve | Am3ric@ |
| stapp03 | banner | BigGr33n |
Single-Command Implementation
Execute the following commands from the jump host:
# stapp01 - App Server 1
echo 'Ir0nM@n' | ssh tony@stapp01 "sudo -S bash -c 'echo \"Current: $(systemctl get-default)\"; systemctl set-default graphical.target; echo \"New: $(systemctl get-default)\"'"
# stapp02 - App Server 2
echo 'Am3ric@' | ssh steve@stapp02 "sudo -S bash -c 'echo \"Current: $(systemctl get-default)\"; systemctl set-default graphical.target; echo \"New: $(systemctl get-default)\"'"
# stapp03 - App Server 3
echo 'BigGr33n' | ssh banner@stapp03 "sudo -S bash -c 'echo \"Current: $(systemctl get-default)\"; systemctl set-default graphical.target; echo \"New: $(systemctl get-default)\"'"
Heredoc Implementation for Better Readability
# stapp01
ssh tony@stapp01 << 'EOF'
echo 'Ir0nM@n' | sudo -S bash -c '
echo "Current default target: $(systemctl get-default)"
systemctl set-default graphical.target
echo "New default target: $(systemctl get-default)"
ls -la /etc/systemd/system/default.target
'
EOF
# stapp02
ssh steve@stapp02 << 'EOF'
echo 'Am3ric@' | sudo -S bash -c '
echo "Current default target: $(systemctl get-default)"
systemctl set-default graphical.target
echo "New default target: $(systemctl get-default)"
ls -la /etc/systemd/system/default.target
'
EOF
# stapp03
ssh banner@stapp03 << 'EOF'
echo 'BigGr33n' | sudo -S bash -c '
echo "Current default target: $(systemctl get-default)"
systemctl set-default graphical.target
echo "New default target: $(systemctl get-default)"
ls -la /etc/systemd/system/default.target
'
EOF
Automated Configuration Script
Create a shell script named configure_gui_target.sh to automate the process across all servers:
#!/bin/bash
echo "========================================="
echo "Configuring GUI Boot Target on All Servers"
echo "========================================="
# stapp01
echo ""
echo "Processing stapp01"
ssh tony@stapp01 << 'EOF'
echo 'Ir0nM@n' | sudo -S bash -c '
echo "Current target: $(systemctl get-default)"
systemctl set-default graphical.target
echo "New target: $(systemctl get-default)"
ls -la /etc/systemd/system/default.target
'
EOF
# stapp02
echo ""
echo "Processing stapp02"
ssh steve@stapp02 << 'EOF'
echo 'Am3ric@' | sudo -S bash -c '
echo "Current target: $(systemctl get-default)"
systemctl set-default graphical.target
echo "New target: $(systemctl get-default)"
ls -la /etc/systemd/system/default.target
'
EOF
# stapp03
echo ""
echo "Processing stapp03"
ssh banner@stapp03 << 'EOF'
echo 'BigGr33n' | sudo -S bash -c '
echo "Current target: $(systemctl get-default)"
systemctl set-default graphical.target
echo "New target: $(systemctl get-default)"
ls -la /etc/systemd/system/default.target
'
EOF
echo ""
echo "========================================="
echo "Configuration Complete"
echo "========================================="
echo ""
echo "Verification Commands:"
echo " ssh tony@stapp01 'systemctl get-default'"
echo " ssh steve@stapp02 'systemctl get-default'"
echo " ssh banner@stapp03 'systemctl get-default'"
Make the script executable and run it:
chmod +x configure_gui_target.sh
./configure_gui_target.sh
Verification Commands
Verify the configuration on each server using the following commands:
# Check default target
ssh tony@stapp01 "echo 'Ir0nM@n' | sudo -S systemctl get-default"
ssh steve@stapp02 "echo 'Am3ric@' | sudo -S systemctl get-default"
ssh banner@stapp03 "echo 'BigGr33n' | sudo -S systemctl get-default"
# Expected output on all servers: graphical.target
For detailed verification on each server:
# Check default target
systemctl get-default
# Verify the symlink
ls -la /etc/systemd/system/default.target
# Check graphical target status
systemctl status graphical.target
# View all available targets
systemctl list-units --type=target --all | grep -E "graphical|multi-user"
# Check current runlevel
runlevel
# Verify no reboot occurred
uptime
Expected Output
When the configuration is applied successfully, you should see output similar to this:
Current default target: multi-user.target
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/graphical.target.
New default target: graphical.target
lrwxrwxrwx 1 root root 37 Jul 10 10:00 /etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.target
Understanding the Changes
Before Change:
Default target: multi-user.target
Boots to text mode (runlevel 3)
After Change:
Default target: graphical.target
Will boot to GUI mode (runlevel 5) on next reboot
Key Differences:
| Feature | multi-user.target | graphical.target |
|---|---|---|
| Boot Mode | Text/Console | Graphical/GUI |
| Display Manager | Not started | Started |
| X Server | Not running | Running |
| Memory Usage | Lower | Higher |
| Suitable for | Servers, headless | Workstations, desktops |
Troubleshooting Common Issues
Issue 1: Permission Denied
If you encounter "Operation not permitted" errors:
# Ensure proper sudo usage
sudo systemctl set-default graphical.target
Issue 2: Graphical Target Not Found
If the graphical target is unavailable:
# Check if graphical target exists
systemctl status graphical.target
# Install GUI packages (RHEL/CentOS)
yum groupinstall "Server with GUI" -y
# For Debian/Ubuntu
apt-get install ubuntu-desktop -y
# Install X11 packages if needed
yum install -y xorg-x11-server-Xorg xorg-x11-drivers
Issue 3: Display Manager Not Installed
Install and enable a display manager:
# Check available display managers
systemctl list-unit-files | grep -E "gdm|lightdm|sddm|kdm"
# Install GDM
yum install -y gdm
systemctl enable gdm
# Install LightDM
yum install -y lightdm
systemctl enable lightdm
Issue 4: Reverting to Text Mode
If you need to revert the changes:
systemctl set-default multi-user.target
Understanding Systemd Target Dependencies
The graphical target depends on the multi-user target, which in turn depends on basic system services:
graphical.target
└── multi-user.target
└── basic.target
└── sysinit.target
└── local-fs.target
└── swap.target
To view all dependencies:
systemctl list-dependencies graphical.target
Alternative Commands
Using Legacy Runlevel Commands
# Check current runlevel
runlevel
# Set default runlevel to 5 (GUI) - Deprecated, use systemctl instead
# Edit /etc/inittab (for older systems)
# id:5:initdefault:
Using Systemd Numeric Runlevels
# Runlevel 5 = graphical.target
systemctl set-default runlevel5.target
# Runlevel 3 = multi-user.target
systemctl set-default runlevel3.target
Important Considerations
No Reboot Required: The changes take effect on the next system boot only. The current session remains unaffected.
GUI Packages Required: The graphical target requires appropriate display manager and X11 packages to be installed on the servers.
Current Session Unchanged: The server continues running in its current mode until rebooted.
Symlink Verification: The default target is configured via a symbolic link at
/etc/systemd/system/default.target.Password Security: The methods demonstrated pass passwords in plain text through the command line. In production environments, consider using SSH keys or password managers for improved security.
Complete Solution Summary
The default runlevel has been configured on all App servers:
- stapp01: Default target changed to graphical.target
- stapp02: Default target changed to graphical.target
- stapp03: Default target changed to graphical.target
- Verified using systemctl get-default on each server
- Symlink created from /etc/systemd/system/default.target to graphical.target
- No servers were rebooted as required
- Changes will take effect on next reboot
Conclusion
Setting the default boot target to graphical mode across multiple Linux servers requires careful attention to password handling when executing remote sudo commands. By combining commands into a single sudo session using shell wrappers or heredoc syntax, system administrators can reliably configure the default target across all servers without encountering authentication issues.
Top comments (0)