Object
Returns true if the given IP and port are currently bound according to lsof, otherwise false.
# File lib/openshift/runtime/containerization/selinux_container.rb, line 279 def address_bound?(ip, port, hourglass) _, _, rc = Utils.oo_spawn("/usr/sbin/lsof -i @#{ip}:#{port}", timeout: hourglass.remaining) rc == 0 end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 284 def addresses_bound?(addresses, hourglass) command = "/usr/sbin/lsof" addresses.each do |addr| command << " -i @#{addr[:ip]}:#{addr[:port]}" end _, _, rc = Utils.oo_spawn(command, timeout: hourglass.remaining) rc == 0 end
Public: Create an empty gear.
Examples
create # => nil # a user # Setup permissions
Returns nil on Success or raises on Failure
# File lib/openshift/runtime/containerization/selinux_container.rb, line 43 def create(create_initial_deployment_dir = true) # Lock to prevent race condition on obtaining a UNIX user uid. # When running without districts, there is a simple search on the # passwd file for the next available uid. File.open("/var/lock/oo-create", File::RDWR|File::CREAT|File::TRUNC, 0o0600) do | uid_lock | uid_lock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) uid_lock.flock(File::LOCK_EX) unless @container.uid @container.uid = @container.gid = @container.next_uid end cmd = %{useradd -u #{@container.uid} \ -d #{@container.container_dir} \ -s #{@gear_shell} \ -c '#{@container.gecos}' \ -m \ -k #{@container.skel_dir} \ #{@container.uuid}} if @container.supplementary_groups != "" cmd << %{ -G "#{@container.supplementary_groups}"} end out,err,rc = ::OpenShift::Runtime::Utils::oo_spawn(cmd) raise ::OpenShift::Runtime::UserCreationException.new( "ERROR: unable to create user account(#{rc}): #{cmd.squeeze(" ")} stdout: #{out} stderr: #{err}" ) unless rc == 0 set_ro_permission(@container.container_dir) FileUtils.chmod 0o0750, @container.container_dir end enable_cgroups enable_traffic_control @container.initialize_homedir(@container.base_dir, @container.container_dir, create_initial_deployment_dir) enable_fs_limits delete_all_public_endpoints end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 214 def create_public_endpoint(private_ip, private_port) proxy = ::OpenShift::Runtime::FrontendProxyServer.new # Add the public-to-private endpoint-mapping to the port proxy public_port = proxy.add(@container.uid, private_ip, private_port) end
Public: Initialize OpenShift Port Proxy for this gear
The port proxy range is determined by configuration and must produce identical results to the abstract cartridge provided range.
Examples: reset_openshift_port_proxy
=> true service openshift_port_proxy setproxy 35000 delete 35001 delete etc...
Returns:
true - port proxy could be initialized properly false - port proxy could not be initialized properly
# File lib/openshift/runtime/containerization/selinux_container.rb, line 239 def delete_all_public_endpoints proxy_server = ::OpenShift::Runtime::FrontendProxyServer.new proxy_server.delete_all_for_uid(@container.uid, true) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 220 def delete_public_endpoints(proxy_mappings) proxy = ::OpenShift::Runtime::FrontendProxyServer.new proxy.delete_all(proxy_mappings.map{|p| p[:proxy_port]}, true) end
Public: Destroys a gear stopping all processes and removing all files
The order of the calls and gyrations done in this code is to prevent
pam_namespace from locking polyinstantiated directories during their deletion. If you see "broken" gears, i.e. ~uuid/.tmp and ~/uuid/.sandbox after #destroy has been called, this method is broken.
See Bug 853582 for history.
Examples
destroy # => nil
Returns nil on Success or raises on Failure
# File lib/openshift/runtime/containerization/selinux_container.rb, line 97 def destroy # These calls and their order is designed to release pam_namespace's # locks on .tmp and .sandbox. Change then at your peril. # # 1. Kill off the easy processes # 2. Lock down the user from creating new processes (cgroups freeze, nprocs 0) # 3. Attempt to move any processes that didn't die into state 'D' (re: cgroups freeze) @container.kill_procs freeze_fs_limits freeze_cgroups disable_traffic_control last_access_dir = @config.get("LAST_ACCESS_DIR") ::OpenShift::Runtime::Utils::oo_spawn("rm -f #{last_access_dir}/#{@container.name} > /dev/null") @container.kill_procs purge_sysvipc delete_all_public_endpoints ::OpenShift::Runtime::FrontendHttpServer.new(@container).destroy dirs = list_home_dir(@container.container_dir) begin cmd = "userdel --remove -f \"#{@container.uuid}\"" out,err,rc = ::OpenShift::Runtime::Utils::oo_spawn(cmd) # Ref man userdel(8) for exit codes. case rc when 0 when 6 logger.debug("Userdel: user does not exist: #{@container.uuid}") when 12 logger.debug("Userdel: could not remove home directory, we will retry: #{@container.uuid}") else # 1 == cannot update password file. # 2 == invalid command syntax. # 8 == currently logged in, should not be possible after we kill the pids. # 10 == can't update group file msg = "ERROR: unable to delete user account(#{rc}): #{cmd} stdout: #{out} stderr: #{err}" raise ::OpenShift::Runtime::UserDeletionException.new(msg) end rescue ArgumentError => e logger.debug("user does not exist. ignore.") end # 1. Don't believe everything you read on the userdel man page... # 2. If there are any active processes left pam_namespace is not going # to let polyinstantiated directories be deleted. FileUtils.rm_rf(@container.container_dir) if File.exists?(@container.container_dir) # Ops likes the verbose verbage logger.warn %{ 1st attempt to remove \'#{@container.container_dir}\' from filesystem failed. Dir(before) #{@container.uuid}/#{@container.uid} => #{dirs} Dir(after) #{@container.uuid}/#{@container.uid} => #{list_home_dir(@container.container_dir)} } end # release resources (cgroups thaw), this causes Zombies to get killed unfreeze_cgroups stop_cgroups disable_fs_limits # try one last time... if File.exists?(@container.container_dir) sleep(5) # don't fear the reaper FileUtils.rm_rf(@container.container_dir) # This is our last chance to nuke the polyinstantiated directories logger.warn("2nd attempt to remove \'#{@container.container_dir}\' from filesystem failed.") if File.exists?(@container.container_dir) end [out,err,rc] end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 272 def disable_fs_limits ::OpenShift::Runtime::Node.remove_pam_limits(@container.uuid) ::OpenShift::Runtime::Node.remove_quota(@container.uuid) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 260 def disable_traffic_control begin ::OpenShift::Runtime::Utils::TC.new.deluser(@container.uuid) rescue RuntimeError, ArgumentError => e end end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 244 def enable_cgroups ::OpenShift::Runtime::Utils::Cgroups.new(@container.uuid).create end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 267 def enable_fs_limits ::OpenShift::Runtime::Node.init_quota(@container.uuid, @container.quota_blocks, @container.quota_files) ::OpenShift::Runtime::Node.init_pam_limits(@container.uuid) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 252 def enable_traffic_control begin ::OpenShift::Runtime::Utils::TC.new.startuser(@container.uuid) rescue RuntimeError, ArgumentError => e raise ::OpenShift::Runtime::UserCreationException.new("Unable to setup tc for #{@container.uuid}") end end
Deterministically constructs an IP address for the given UID based on the given host identifier (LSB of the IP). The host identifier must be a value between 1-127 inclusive.
The global user IP range begins at 0x7F000000.
Returns an IP address string in dotted-quad notation.
# File lib/openshift/runtime/containerization/selinux_container.rb, line 196 def get_ip_addr(host_id) raise "Invalid host_id specified" unless host_id && host_id.is_a?(Integer) if @container.uid.to_i < 0 || @container.uid.to_i > 262143 raise "User uid #{@container.uid} is outside the working range 0-262143" end if host_id < 1 || host_id > 127 raise "Supplied host identifier #{host_id} must be between 1 and 127" end # Generate an IP (32-bit unsigned) in the user's range ip = 0x7F000000 + (@container.uid.to_i << 7) + host_id # Return the IP in dotted-quad notation "#{ip >> 24}.#{ip >> 16 & 0xFF}.#{ip >> 8 & 0xFF}.#{ip & 0xFF}" end
Public
Lazy load the MCS label only when its needed
# File lib/openshift/runtime/containerization/selinux_container.rb, line 24 def mcs_label if not @mcs_label if @container.uid @mcs_label = ::OpenShift::Runtime::Utils::SELinux.instance.get_mcs_label(@container.uid) end end @mcs_label end
retrieve the default maximum memory limit
# File lib/openshift/runtime/containerization/selinux_container.rb, line 361 def memory_in_bytes(uuid) OpenShift::Runtime::Utils::Cgroups.new(uuid).templates[:default]['memory.limit_in_bytes'].to_i end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 330 def reset_permission(paths) ::OpenShift::Runtime::Utils::SELinux.instance.clear_mcs_label(paths) ::OpenShift::Runtime::Utils::SELinux.instance.set_mcs_label(mcs_label, paths) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 335 def reset_permission_R(paths) ::OpenShift::Runtime::Utils::SELinux.instance.clear_mcs_label_R(paths) ::OpenShift::Runtime::Utils::SELinux.instance.set_mcs_label_R(mcs_label, paths) end
run_in_container_context(command, [, options]) -> [stdout, stderr, exit status]
Executes specified command and return its stdout, stderr and exit status. Or, raise exceptions if certain conditions are not met. The command is as container user in a SELinux context using runuser/runcon. The environment variables are cleared and mys be specified by :env.
command: command line string which is passed to the standard shell
options: hash
:env: hash name => val : set the environment variable name => nil : unset the environment variable :chdir => path : set current directory when running command :expected_exitstatus : An Integer value for the expected return code of command : If not set spawn() returns exitstatus from command otherwise : raise an error if exitstatus is not expected_exitstatus :timeout : Maximum number of seconds to wait for command to finish. default: 3600 : stdin for the command is /dev/null :out : If specified, STDOUT from the child process will be redirected to the provided +IO+ object. :err : If specified, STDERR from the child process will be redirected to the provided +IO+ object.
NOTE: If the out or err options are specified, the corresponding return value from oo_spawn will be the incoming/provided IO objects instead of the buffered String output. It's the responsibility of the caller to correctly handle the resulting data type.
# File lib/openshift/runtime/containerization/selinux_container.rb, line 321 def run_in_container_context(command, options = {}) require 'openshift-origin-node/utils/selinux' options[:unsetenv_others] = true options[:uid] = @container.uid options[:gid] = @container.gid options[:selinux_context] = ::OpenShift::Runtime::Utils::SELinux.instance.context_from_defaults(mcs_label) ::OpenShift::Runtime::Utils::oo_spawn(command, options) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 345 def set_ro_permission(paths) PathUtils.oo_chown(0, @container.gid, paths) ::OpenShift::Runtime::Utils::SELinux.instance.set_mcs_label(mcs_label, paths) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 340 def set_ro_permission_R(paths) PathUtils.oo_chown_R(0, @container.gid, paths) ::OpenShift::Runtime::Utils::SELinux.instance.set_mcs_label_R(mcs_label, paths) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 355 def set_rw_permission(paths) PathUtils.oo_chown(@container.uid, @container.gid, paths) ::OpenShift::Runtime::Utils::SELinux.instance.set_mcs_label(mcs_label, paths) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 350 def set_rw_permission_R(paths) PathUtils.oo_chown_R(@container.uid, @container.gid, paths) ::OpenShift::Runtime::Utils::SELinux.instance.set_mcs_label_R(mcs_label, paths) end
# File lib/openshift/runtime/containerization/selinux_container.rb, line 185 def start restore_cgroups end
Private: Kill all processes for a given gear
Kill all processes owned by the uid or uuid. No reason for graceful shutdown first, the directories and user are going
to be removed from the system.
Examples: kill_gear_procs
=> true pkill -u id
Raises exception on error.
# File lib/openshift/runtime/containerization/selinux_container.rb, line 181 def stop(options={}) @container.kill_procs(options) end
Generated with the Darkfish Rdoc Generator 2.