Skip to content

Commit

Permalink
Update Remote module to handle systemd based VNC.
Browse files Browse the repository at this point in the history
The VNC service switched from xinetd to systemd.
VNC over HTTP service can be enabled/disabled separately.
  • Loading branch information
Michal Srb committed Oct 2, 2017
1 parent 273c8f3 commit cd8dffa
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 149 deletions.
18 changes: 17 additions & 1 deletion src/include/network/remote/dialogs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ def RemoteMainDialog
_("&Do Not Allow Remote Administration"),
Remote.IsDisabled
)
),
VSpacing(0.3),
Left(
CheckBox(
Id(:allow_web),
_("Enable access using a &web browser"),
Remote.IsWebVncEnabled
)
)
)
)
Expand All @@ -101,7 +109,7 @@ def RemoteMainDialog
"<p>If this feature is enabled, you can\n" \
"administer this machine remotely from another machine. Use a VNC\n" \
"client, such as krdc (connect to <tt>&lt;hostname&gt;:%1</tt>), or\n" \
"a Java-capable Web browser (connect to <tt>https://&lt;hostname&gt;:%2/</tt>).</p>\n" \
"a Web browser (connect to <tt>https://&lt;hostname&gt;:%2/</tt>).</p>\n" \
"<p>Without Session Management, only one user can be connected\n"\
"at a time to a session, and that session is terminated when the VNC client\n" \
"disconnects.</p>" \
Expand Down Expand Up @@ -166,6 +174,14 @@ def RemoteMainDialog
else
Remote.Disable
end

allow_web = UI.QueryWidget(Id(:allow_web), :Value)

if allow_web
Remote.EnableWebVnc
else
Remote.DisableWebVnc
end
end

Convert.to_symbol(ret)
Expand Down
129 changes: 57 additions & 72 deletions src/modules/Remote.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ class RemoteClass < Module
include Yast::Logger

XDM_SERVICE_NAME = "display-manager".freeze
XINETD_SERVICE = "xinetd".freeze
XVNC_SERVICE = "xvnc.socket".freeze
XVNC_NOVNC_SERVICE = "xvnc-novnc.socket".freeze
VNCMANAGER_SERVICE = "vncmanager".freeze

PKG_CONTAINING_FW_SERVICES = "xorg-x11-Xvnc".freeze
PKG_CONTAINING_VNCMANAGER = "vncmanager".freeze
PKG_CONTAINING_XVNC_NOVNC = "xorg-x11-Xvnc-novnc".freeze

GRAPHICAL_TARGET = "graphical".freeze

Expand All @@ -61,9 +63,12 @@ def main
# Currently, all attributes (enablement of remote access)
# are applied on vnc1 even vnchttpd1 configuration

# Remote administration mode, :disabled, :xinetd or :vncmanager
# Remote administration mode, :disabled, :xvnc or :vncmanager
@mode = :disabled

# Whether a web based vnc viewer should be served
@web_vnc_enabled = false

# Remote administration has been already proposed
# Only force-reset can change it
@already_proposed = false
Expand All @@ -81,7 +86,7 @@ def IsDisabled

# Enables remote administration without vnc manager.
def Enable
@mode = :xinetd
@mode = :xvnc

nil
end
Expand All @@ -104,6 +109,18 @@ def EnabledVncManager
@mode == :vncmanager
end

def IsWebVncEnabled
@web_vnc_enabled
end

def EnableWebVnc
@web_vnc_enabled = true
end

def DisableWebVnc
@web_vnc_enabled = false
end

# Reset all module data.
def Reset
@already_proposed = true
Expand Down Expand Up @@ -131,54 +148,29 @@ def Propose
# Read the current status
# @return true on success
def Read
# are the proper services enabled in xinetd?
xinetd_conf = SCR.Read(path(".etc.xinetd_conf.services")) || {}
xinetd_vnc1_enabled = xinetd_conf.any? { |c| c["service"] == "vnc1" && c["enabled"] }

log.info "VNC1 enabled: #{xinetd_vnc1_enabled}"
display_manager_remote_access = SCR.Read(path(".sysconfig.displaymanager.DISPLAYMANAGER_REMOTE_ACCESS")) == "yes"

xdm = Service.Enabled(XDM_SERVICE_NAME)
vncmanager = Service.Enabled(VNCMANAGER_SERVICE)
vnc_service_running = xinetd_vnc1_enabled || vncmanager
xvnc = Service.Enabled(XVNC_SERVICE)
xvnc_novnc = Service.Enabled(XVNC_NOVNC_SERVICE)

if xdm && display_manager_remote_access && (xvnc || vncmanager)
if xvnc
Enable()
else
EnableVncManager()
end

if xinet_ready? && vnc_service_running
Enable() if xinetd_vnc1_enabled
EnableVncManager() if vncmanager
EnableWebVnc() if xvnc_novnc
else
Disable()
DisableWebVnc()
end

true
end

def WriteXinetd
# Enable/disable vnc1 and vnchttpd1 in xinetd.d/vnc
# If the port is changed, change also the help in remote/dialogs.ycp
# The agent is in yast2-inetd.rpm
xinetd = Convert.convert(
SCR.Read(path(".etc.xinetd_conf.services")),
from: "any",
to: "list <map>"
)

xinetd = xinetd.map do |m|
case m["service"]
when "vnc1"
m["enabled"] = IsEnabled() && !EnabledVncManager()
m["changed"] = true
when "vnchttpd1"
m["enabled"] = IsEnabled()
m["changed"] = true
end

log.info "Updated xinet cfg: #{m}" if m["changed"]
deep_copy(m)
end

SCR.Write(path(".etc.xinetd_conf.services"), xinetd)

true
end

# Update the SCR according to network settings
# @return true on success
def Write
Expand Down Expand Up @@ -232,27 +224,29 @@ def Write
# Updates the VNC and xdm configuration
#
# Called from #Write. Ensures that required packages are installed,
# enables xinetd and xdm and writes the configuration files, reporting
# any error in the process.
# enables vnc services and xdm and writes the configuration files,
# reporting any error in the process.
#
# @return [Boolean] true if success, false otherwise
def configure_display_manager
if IsEnabled()
# Install required packages
packages = Packages.vnc_packages
packages << PKG_CONTAINING_VNCMANAGER if EnabledVncManager()
packages << PKG_CONTAINING_XVNC_NOVNC if IsWebVncEnabled()

if !Package.InstallAll(packages)
log.error "Installing of required packages failed"
return false
end

services = [
[XINETD_SERVICE, true],
[XVNC_SERVICE, !EnabledVncManager()],
[XDM_SERVICE_NAME, true]
]

services << [VNCMANAGER_SERVICE, EnabledVncManager()] if Package.Installed("vncmanager")
services << [VNCMANAGER_SERVICE, EnabledVncManager()] if Package.Installed(PKG_CONTAINING_VNCMANAGER)
services << [XVNC_NOVNC_SERVICE, IsWebVncEnabled()] if Package.Installed(PKG_CONTAINING_XVNC_NOVNC)

services.each do |service, enable|
if enable
Expand Down Expand Up @@ -282,9 +276,6 @@ def configure_display_manager
)
SCR.Write(path(".sysconfig.displaymanager"), nil)

# Do this only if package xinetd is installed (#256385)
return false if Package.Installed("xinetd") && !WriteXinetd()

true
end

Expand All @@ -303,25 +294,30 @@ def restart_display_manager
end
end

# Restarts xinetd and xdm, reporting errors to the user
# Restarts services, reporting errors to the user
def restart_services
if IsEnabled()
SystemdTarget.set_default(GRAPHICAL_TARGET)

Report.Error(Message.CannotRestartService(XINETD_SERVICE)) unless Service.Restart(XINETD_SERVICE)

# Enable vncmanager or xvnc service, depending on which mode are we in
if EnabledVncManager()
Report.Error(Message.CannotRestartService(VNCMANAGER_SERVICE)) unless Service.Restart(VNCMANAGER_SERVICE)
else
Report.Error(Message.CannotRestartService(XVNC_SERVICE)) unless Service.Restart(XVNC_SERVICE)
end

# Enable xvnc-novnc service in addition to xvnc/vncmanager if enabled
if IsWebVncEnabled()
Report.Error(Message.CannotRestartService(XVNC_NOVNC_SERVICE)) unless Service.Restart(XVNC_NOVNC_SERVICE)
else
Service.Stop(XVNC_NOVNC_SERVICE)
end

restart_display_manager
else
# xinetd may be needed for other services so we never turn it
# off. It will exit anyway if no services are configured.
# If it is running, restart it.
Service.Reload(XINETD_SERVICE) if Service.active?(XINETD_SERVICE)

Service.Stop(VNCMANAGER_SERVICE)
Service.Stop(XVNC_SERVICE)
Service.Stop(XVNC_NOVNC_SERVICE)
end
end

Expand All @@ -336,27 +332,16 @@ def Summary
publish function: :IsDisabled, type: "boolean ()"
publish function: :Enable, type: "void ()"
publish function: :Disable, type: "void ()"
publish function: :EnableVncManager, type: "void ()"
publish function: :EnabledVncManager, type: "boolean ()"
publish function: :IsWebVncEnabled, type: "boolean ()"
publish function: :EnableWebVnc, type: "void ()"
publish function: :DisableWebVnc, type: "void ()"
publish function: :Reset, type: "void ()"
publish function: :Propose, type: "void ()"
publish function: :Read, type: "boolean ()"
publish function: :Write, type: "boolean ()"
publish function: :Summary, type: "string ()"

private

# Checks and reports if system is configured for remote access
#
# @return [true,false] true when all necessarry services are running
# and sysconfig is configured properly, false otherwise
def xinet_ready?
xdm = Service.Enabled(XDM_SERVICE_NAME)
dm_ra = SCR.Read(path(".sysconfig.displaymanager.DISPLAYMANAGER_REMOTE_ACCESS")).to_s == "yes"
xinetd = Service.Enabled(XINETD_SERVICE)

log.info "#{XDM_SERVICE_NAME}: #{xdm}, DM_R_A configured: #{dm_ra}"

xdm && dm_ra && xinetd
end
end

Remote = RemoteClass.new
Expand Down

0 comments on commit cd8dffa

Please sign in to comment.