Class: OsCtld::Lxcfs::Server

Inherits:
Object
  • Object
show all
Includes:
OsCtl::Lib::Utils::Log, OsCtl::Lib::Utils::System
Defined in:
lib/osctld/lxcfs/server.rb

Overview

Manage LXCFS instance using osctl-lxcfs runit service on the host

Constant Summary collapse

RUNDIR_SERVERS =
File.join(RunState::LXCFS_DIR, 'servers')
RUNDIR_RUNSVDIR =
File.join(RunState::LXCFS_DIR, 'runsvdir')
RUNDIR_MOUNTROOT =
File.join(RunState::LXCFS_DIR, 'mountpoint')

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, uid: 0, gid: 0, mode: 0555, cpuset: nil, loadavg: true, cfs: true) ⇒ Server

Returns a new instance of Server.

Parameters:

  • name (String)

    LXCFS instance name, used for runit service

  • uid (Integer) (defaults to: 0)

    user ID with access to the mountpoint

  • gid (Integer) (defaults to: 0)

    group ID with access to the mountpoint

  • mode (Integer) (defaults to: 0555)

    mountpoint access mode

  • cpuset (String, nil) (defaults to: nil)

    cpuset mask

  • loadavg (Boolean) (defaults to: true)

    enable load average tracking

  • cfs (Boolean) (defaults to: true)

    enable virtualized CPU usage view based on CFS quotas



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/osctld/lxcfs/server.rb', line 39

def initialize(name, uid: 0, gid: 0, mode: 0555, cpuset: nil, loadavg: true, cfs: true)
  @name = name
  @uid = uid
  @gid = gid
  @mode = mode
  @cpuset = cpuset
  @loadavg = loadavg
  @cfs = cfs
  @runsv_source = File.join(RUNDIR_SERVERS, name)
  @runsv_target = File.join(RUNDIR_RUNSVDIR, name)
  @runsv_run = File.join(runsv_source, 'run')
  @mountroot = File.join(RUNDIR_MOUNTROOT, name)
  @mountpoint = File.join(mountroot, 'mount')
  @cgroup_root = CGroup.abs_cgroup_path('cpuset', CGroup::ROOT_GROUP, 'lxcfs')
  @cgroup_dir = File.join(@cgroup_root, name)
end

Instance Attribute Details

#cfsBoolean (readonly)

Returns:

  • (Boolean)


24
25
26
# File 'lib/osctld/lxcfs/server.rb', line 24

def cfs
  @cfs
end

#cgroup_dirObject (readonly, protected)

Returns the value of attribute cgroup_dir.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def cgroup_dir
  @cgroup_dir
end

#cgroup_rootObject (readonly, protected)

Returns the value of attribute cgroup_root.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def cgroup_root
  @cgroup_root
end

#cpusetString? (readonly)

Returns:

  • (String, nil)


18
19
20
# File 'lib/osctld/lxcfs/server.rb', line 18

def cpuset
  @cpuset
end

#gidObject (readonly, protected)

Returns the value of attribute gid.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def gid
  @gid
end

#loadavgBoolean (readonly)

Returns:

  • (Boolean)


21
22
23
# File 'lib/osctld/lxcfs/server.rb', line 21

def loadavg
  @loadavg
end

#modeObject (readonly, protected)

Returns the value of attribute mode.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def mode
  @mode
end

#mountpointString (readonly)

Returns:

  • (String)


30
31
32
# File 'lib/osctld/lxcfs/server.rb', line 30

def mountpoint
  @mountpoint
end

#mountrootString (readonly)

Returns:

  • (String)


27
28
29
# File 'lib/osctld/lxcfs/server.rb', line 27

def mountroot
  @mountroot
end

#nameString (readonly)

Returns:

  • (String)


15
16
17
# File 'lib/osctld/lxcfs/server.rb', line 15

def name
  @name
end

#runsv_runObject (readonly, protected)

Returns the value of attribute runsv_run.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def runsv_run
  @runsv_run
end

#runsv_sourceObject (readonly, protected)

Returns the value of attribute runsv_source.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def runsv_source
  @runsv_source
end

#runsv_targetObject (readonly, protected)

Returns the value of attribute runsv_target.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def runsv_target
  @runsv_target
end

#uidObject (readonly, protected)

Returns the value of attribute uid.



191
192
193
# File 'lib/osctld/lxcfs/server.rb', line 191

def uid
  @uid
end

Instance Method Details

#chown(uid, gid) ⇒ Object

Change owner

Parameters:

  • uid (Integer)
  • gid (Integer)


127
128
129
130
131
132
133
134
135
# File 'lib/osctld/lxcfs/server.rb', line 127

def chown(uid, gid)
  @uid = uid
  @gid = gid

  begin
    File.chown(uid, gid, mountroot)
  rescue Errno::ENOENT
  end
end

#configure(loadavg: true, cfs: true) ⇒ Object



137
138
139
140
141
# File 'lib/osctld/lxcfs/server.rb', line 137

def configure(loadavg: true, cfs: true)
  @loadavg = loadavg
  @cfs = cfs
  create
end

#createObject (protected)



212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/osctld/lxcfs/server.rb', line 212

def create
  cg_root = CGroup.abs_cgroup_path('cpuset', 'osctl')

  FileUtils.mkdir_p(runsv_source)
  ErbTemplate.render_to('ct/lxcfs_runsv', {
    executable: Daemon.get.config.lxcfs.path,
    name: name,
    cpuset: cpuset,
    cgroup_root: cgroup_root,
    cgroup_dir: cgroup_dir,
    options: options,
    mountpoint: mountpoint,
  }, runsv_run, perm: 0500)
end

#destroyObject



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
# File 'lib/osctld/lxcfs/server.rb', line 86

def destroy
  log(:info, "Destroying LXCFS")
  FileUtils.rm_rf(runsv_source, secure: true)

  begin
    Dir.rmdir(mountpoint)
  rescue Errno::ENOENT
    # pass
  rescue SystemCallError => e
    log(
      :fatal,
      "Unable to delete LXCFS mountpoint at #{mountpoint}: #{e.message} (#{e.class})"
    )
  end

  begin
    Dir.rmdir(mountroot)
  rescue Errno::ENOENT
    # pass
  rescue SystemCallError => e
    log(
      :fatal,
      "Unable to delete LXCFS mountroot at #{mountroot}: #{e.message} (#{e.class})"
    )
  end

  begin
    Dir.rmdir(cgroup_dir)
  rescue Errno::ENOENT
    # pass
  rescue SystemCallError => e
    log(
      :fatal,
      "Unable to delete LXCFS cgroup at #{cgroup_dir}: #{e.message} (#{e.class})"
    )
  end
end

#ensure_destroyObject

Stop and destroy LXCFS if it was created



159
160
161
162
# File 'lib/osctld/lxcfs/server.rb', line 159

def ensure_destroy
  ensure_stop
  destroy if exist?
end

#ensure_startObject

Start LXCFS if it is not already running



148
149
150
151
# File 'lib/osctld/lxcfs/server.rb', line 148

def ensure_start
  start
  sv_command('start') if supervised?
end

#ensure_stopObject

Stop LXCFS if it is running



154
155
156
# File 'lib/osctld/lxcfs/server.rb', line 154

def ensure_stop
  stop if running?
end

#exist?Boolean (protected)

Returns:

  • (Boolean)


194
195
196
# File 'lib/osctld/lxcfs/server.rb', line 194

def exist?
  File.exist?(runsv_run)
end

#log_typeObject



186
187
188
# File 'lib/osctld/lxcfs/server.rb', line 186

def log_type
  "lxcfs:#{name}"
end

#mount_filesArray<String>

Get a list of files which can be mounted from this LXCFS instance

Returns:

  • (Array<String>)


182
183
184
# File 'lib/osctld/lxcfs/server.rb', line 182

def mount_files
  Dir.glob('proc/*', base: mountpoint)
end

#operational?Boolean (protected)

Returns:

  • (Boolean)


198
199
200
201
202
203
204
205
206
# File 'lib/osctld/lxcfs/server.rb', line 198

def operational?
  File.open(File.join(mountpoint, 'proc/cpuinfo')) do |f|
    f.readline
  end
  true

rescue SystemCallError
  false
end

#optionsObject (protected)



227
228
229
230
231
232
233
# File 'lib/osctld/lxcfs/server.rb', line 227

def options
  ret = []
  ret << "--pidfile=#{File.join(runsv_source, 'lxcfs.pid')}"
  ret << '--enable-loadavg' if loadavg
  ret << '--enable-cfs' if cfs
  ret
end

#reconfigureObject



143
144
145
# File 'lib/osctld/lxcfs/server.rb', line 143

def reconfigure
  create if exist?
end

#restartObject



75
76
77
78
# File 'lib/osctld/lxcfs/server.rb', line 75

def restart
  log(:info, "Restarting LXCFS")
  sv_command('restart')
end

#running?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/osctld/lxcfs/server.rb', line 56

def running?
  Dir.exist?(runsv_target)
end

#startObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/osctld/lxcfs/server.rb', line 60

def start
  create unless exist?

  log(:info, "Starting LXCFS")

  FileUtils.mkdir_p(mountroot)
  File.chown(uid, gid, mountroot)
  File.chmod(mode, mountroot)

  begin
    File.symlink(runsv_source, runsv_target)
  rescue Errno::EEXIST
  end
end

#stopObject



80
81
82
83
84
# File 'lib/osctld/lxcfs/server.rb', line 80

def stop
  log(:info, "Stopping LXCFS")
  sv_command('stop')
  File.unlink(runsv_target)
end

#supervised?Boolean (protected)

Returns:

  • (Boolean)


208
209
210
# File 'lib/osctld/lxcfs/server.rb', line 208

def supervised?
  File.exist?(File.join(runsv_target, 'supervise/ok'))
end

#sv_command(command, timeout: 60) ⇒ Object (protected)



235
236
237
238
239
# File 'lib/osctld/lxcfs/server.rb', line 235

def sv_command(command, timeout: 60)
  syscmd("sv -w #{timeout} #{command} \"#{runsv_target}\"")
rescue SystemCommandFailed => e
  log(:warn, "sv #{command} failed: #{e.message}")
end

#wait(timeout: nil) ⇒ Object

Block until LXCFS becomes operational or timeout occurs

Raises:



166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/osctld/lxcfs/server.rb', line 166

def wait(timeout: nil)
  wait_until = timeout && (Time.now + timeout)

  until operational?
    if timeout && wait_until < Time.now
      log(:fatal, 'Timed while waiting for LXCFS to become operational')
      raise Lxcfs::Timeout, "Timed out while waiting for LXCFS to become operational"
    end

    log(:info, 'Waiting for LXCFS to become operational')
    sleep(1)
  end
end