Class: Storazzo::RicDisk

Inherits:
Object
  • Object
show all
Extended by:
Colors, Common
Includes:
Common, Hashify
Defined in:
lib/storazzo/ric_disk.rb

Constant Summary collapse

ConfigFiles =

in order of finding, so the first will be the one we actually READ and use. I could looknat the date but cmon… These are the files I do accept.

%w[ricdisk.yaml .ricdisk storazzo.yaml].freeze
DefaultConfigFile =

.ricdisk }

'storazzo.yaml'
RicdiskVersion =
'2.1'
RicdiskHistory =
[
  '2022-07-29 2.1 Added timestamp',
  '2022-07-28 2.0 Added tags, siz, unique_hash, computation_hostname, wr, ...'
].freeze
DefaultGemfileTestDiskFolder =

was: @@default_gemfile_test_disks_folder

"#{Storazzo.root}/var/test/disks/"
DefaultMediaFolders =

Immutable

%w[
  /Volumes/
  /mnt/
].append(DefaultGemfileTestDiskFolder).append("/media/#{ENV['USER']}/")

Constants included from Colors

Colors::PREPEND_ME

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Common

bug, deb, err, fatal, if_deb?, linux?, mac?, ppp, pverbose, slugify, warn

Methods included from Colors

azure, blue, deb2, gray, green, orange, pgreen, pred, purple, pwhite, pyellow, red, white, yellow

Methods included from Hashify

#ivars_excluded_from_hash, #obj_to_hash, #obj_to_yaml, #to_hash, #to_yaml

Constructor Details

#initialize(ric_disk_object, opts = {}) ⇒ RicDisk

Returns a new instance of RicDisk.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/storazzo/ric_disk.rb', line 48

def initialize(ric_disk_object, opts = {})
  verbose = opts.fetch :verbose, true
  pverbose verbose,
           "This needs an object of type Storazzo::Media::AbstractRicDisk now (this case: #{ric_disk_object.class})"
  raise "Woopsie, not a Storazzo::Media::AbstractRicDisk! Intead its a #{ric_disk_object.class}" unless ric_disk_object.class.superclass == Storazzo::Media::AbstractRicDisk

  # ok back to business, now path is a String :)
  path = ric_disk_object.path
  deb "RicDisk initialize.. path=#{path}"
  @local_mountpoint = File.expand_path(path)
  @ard = ric_disk_object # AbstractRicDiskObject
  @description = "This is an automated RicDisk description from v.#{RicdiskVersion}. Created on #{Time.now}'"
  @ricdisk_version = RicdiskVersion
  @ricdisk_file = compute_ricdisk_file # Storazzo::RicDisk.get_ricdisk_file(path)
  @ricdisk_file_full = "#{@local_mountpoint}/#{@ricdisk_file}"
  @label = path.split('/').last
  @name = path.split('/').last
  
  load_existing_config

  @tags ||= %w[ricdisk storazzo]
  @size = RicDisk._compute_size_could_take_long(path)
  @unique_hash = "MD5::#{Digest::MD5.hexdigest(File.expand_path(path))}"
  @disk_uuid ||= SecureRandom.uuid if defined?(SecureRandom)
  @computation_hostname = Socket.gethostname
  @created_at ||= Time.now

  @ricdisk_file_empty = ricdisk_file_empty?

  deb "RicDisk initialize. to_s: #{self}"
end

Instance Attribute Details

#active_dirsObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def active_dirs
  @active_dirs
end

#descriptionObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def description
  @description
end

#disk_uuidObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def disk_uuid
  @disk_uuid
end

#llm_descriptionObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def llm_description
  @llm_description
end

#llm_storage_typeObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def llm_storage_type
  @llm_storage_type
end

#local_mountpointObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def local_mountpoint
  @local_mountpoint
end

#nameObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def name
  @name
end

#pathObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def path
  @path
end

#ricdisk_fileObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def ricdisk_file
  @ricdisk_file
end

#ricdisk_file_emptyObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def ricdisk_file_empty
  @ricdisk_file_empty
end

#ricdisk_file_fullObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def ricdisk_file_full
  @ricdisk_file_full
end

#ricdisk_versionObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def ricdisk_version
  @ricdisk_version
end

#sizeObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def size
  @size
end

#unique_hashObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def unique_hash
  @unique_hash
end

#wrObject

# todo substitute with protobuf..



36
37
38
# File 'lib/storazzo/ric_disk.rb', line 36

def wr
  @wr
end

Class Method Details

._compute_size_could_take_long(my_path) ⇒ Object

could take long.. def size

`du -s '#{path}'`.split(/\s/)[0]

end



125
126
127
128
129
# File 'lib/storazzo/ric_disk.rb', line 125

def self._compute_size_could_take_long(my_path)
  deb 'Could take long. TODO(ricc): add some sort of cutoff/timeout to 5 seconds.'
  puts azure('could take long. Please take precautions like forking with timeout of 5sec')
  `du -s '#{my_path}' 2>/dev/null`.chomp.split(/\s/)[0] # self.size
end

.calculate_stats_files_DUPLICATE_STATIC(_dir, _opts = {}) ⇒ Object



409
410
411
# File 'lib/storazzo/ric_disk.rb', line 409

def self.calculate_stats_files_DUPLICATE_STATIC(_dir, _opts = {})
  raise 'Please use object instead. If you cant, please move the object code to STATIC and dedupe code!'
end

.compute_stats_for_dir_into_file(dir, full_file_path, reason, opts = {}) ⇒ Object



387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'lib/storazzo/ric_disk.rb', line 387

def self.compute_stats_for_dir_into_file(dir, full_file_path, reason, opts = {})
  max_lines = opts.fetch :max_lines, 42 # TODO: move to nil or -1
  # full_file_path = "#{dir}/#{stats_file}"
  puts "Crunching data stats from '#{dir}' into '#{full_file_path}' ... please bear with me.. [reason: '#{reason}']"
  if max_lines.negative? # infinite
    command = "find . -print0 | xargs -0 stats-with-md5 --no-color | tee '#{full_file_path}'"
  elsif mac?
    # WOW! https://stackoverflow.com/questions/68599963/reliably-stop-bash-find-after-n-matches
    # find . -type f -iname "*.txt" -print0 |
    # head -z -n 10 |
    # xargs -r0 myscript.sh
    puts red('Sorry head -z doesnt work on Mac :/ so this head -N will be VERY approximate. Probably you should divide by ten or so :)')
    spannometric_lines = (max_lines / 10)
    command = "find . -print0 | head -n '#{spannometric_lines}' | xargs -r0 stats-with-md5 --no-color | tee '#{full_file_path}'"
  else
    command = "find . -print0 | head -z -n '#{max_lines}' | xargs -r0 stats-with-md5 --no-color | tee '#{full_file_path}'"
  end
  puts("[#{`pwd`.chomp}] Executing: #{azure command}")
  ret = backquote_execute(command)
  puts "Done. #{ret.split("\n").count} files processed."
end

.default_media_foldersObject

All places where to find for something :)



168
169
170
# File 'lib/storazzo/ric_disk.rb', line 168

def self.default_media_folders
  DefaultMediaFolders # was DEFAULT_MEDIA_FOLDERS
end

.find_active_dirs(base_dirs = nil, _also_mountpoints = true) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/storazzo/ric_disk.rb', line 185

def self.find_active_dirs(base_dirs = nil, _also_mountpoints = true)
  if base_dirs.nil?
    base_dirs = default_media_folders
    puts "find_active_dirs with empty input -> using default_media_folders: #{yellow default_media_folders}"
  end
  active_dirs = []
  base_dirs.each do |ugly_dir|
    # https://stackoverflow.com/questions/1899072/getting-a-list-of-folders-in-a-directory#:~:text=Dir.chdir(%27/destination_directory%27)%0ADir.glob(%27*%27).select%20%7B%7Cf%7C%20File.directory%3F%20f%7D
    dir = File.expand_path(ugly_dir)
    begin
      x = []
      #        puts "TEST2 DIR EXISTS: #{dir} -> #{Dir.exists?(dir)}"
      unless Dir.exist?(dir)
        deb "Dir doesnt exist, skipping: #{dir}"
        next
      end
      Dir.chdir(dir)
      x = Dir.glob('*').select { |f| File.directory? f }
      subdirs = x.map { |subdir| "#{dir}#{subdir}" }
      subdirs.each do |subdir|
        deb "Subdir: #{subdir}"
        puts `ls -al "#{subdir}"` # TODO: refactor in exec
        active_dirs << subdir if ok_dir? # self.ok_dir?(subdir)
      end
      # puts(white x)
    rescue Exception => e # optionally: `rescue Exception => ex`
      puts "Exception: '#{e}'"
      # will always get executed
      # deb 'Always gets executed.'
      # x = []
    end
  end
end

.interesting_mount_points(_opts = {}) ⇒ Object

# new def self.get_ricdisk_file_obsolete(path)

if @ricdisk_file
  puts "[CACHE HIT] ricdisk_file"
  return @ricdisk_file
end
puts "RICC_WARNING This requires cmputation I wanna do it almost once"
ConfigFiles.each do |papable_config_filename|
  #return ".ricdisk.yaml" if File.exist?("#{path}/.ricdisk.yaml") #and File.empty?( "#{path}/.ricdisk.yaml")
  #return ".ricdisk" if File.exist?("#{path}/.ricdisk") # and File.empty?( "#{path}/.ricdisk")
  return papable_config_filename if File.exist?("#{path}/#{papable_config_filename}") # and File.empty?( "#{path}/.ricdisk")
end
return nil

end



264
265
266
267
# File 'lib/storazzo/ric_disk.rb', line 264

def self.interesting_mount_points(_opts = {})
  # https://unix.stackexchange.com/questions/177014/showing-only-interesting-mount-points-filtering-non-interesting-types
  `mount | grep -Ev 'type (proc|sysfs|tmpfs|devpts|debugfs|rpc_pipefs|nfsd|securityfs|fusectl|devtmpfs) '`.split(/\n+/)
end

.ok_dir?(subdir) ⇒ Boolean

TODO: obsolete this as i should NOT be calling it from clas, but from method.

Returns:

  • (Boolean)


340
341
342
# File 'lib/storazzo/ric_disk.rb', line 340

def self.ok_dir?(subdir)
  File.exist?("#{subdir}/.ricdisk") or File.exist?("#{subdir}/.ricdisk.yaml")
end

.testObject

_localgem_disks



173
174
175
176
177
178
# File 'lib/storazzo/ric_disk.rb', line 173

def self.test
  d = RicDisk.new(DefaultGemfileTestDiskFolder)
  puts(d)
  puts "do something with it: #{d}"
  # d.find_active_dirs()
end

Instance Method Details

#absolute_pathObject



180
181
182
183
# File 'lib/storazzo/ric_disk.rb', line 180

def absolute_path
  # @local_mountpoint + "/" +  @ricdisk_file
  "#{local_mountpoint}/#{ricdisk_file}"
end

#analyze_local_systemObject



105
106
107
108
109
110
111
# File 'lib/storazzo/ric_disk.rb', line 105

def analyze_local_system
  puts 'TODO This should analyzze the WHOLE system. TODO(ricc): move to another object which has to do with the system/computer.'
  puts "1. Interesting Mounts: #{green interesting_mount_points}"
  puts '2. Sbrodoling everything: :TODO'
  # find_info_from_mount(path)
  # find_info_from_df()
end

#compute_ricdisk_fileObject



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/storazzo/ric_disk.rb', line 219

def compute_ricdisk_file
  unless @ricdisk_file.nil?
    deb '[CACHE HIT] ricdisk_file (didnt have to recompute it - yay!)'
    return @ricdisk_file
  end
  deb '[compute_ricdisk_file] RICC_WARNING This requires cmputation I wanna do it almost once'
  ConfigFiles.each do |papable_config_filename|
    # return ".ricdisk.yaml" if File.exist?("#{path}/.ricdisk.yaml") #and File.empty?( "#{path}/.ricdisk.yaml")
    # return ".ricdisk" if File.exist?("#{path}/.ricdisk") # and File.empty?( "#{path}/.ricdisk")
    return papable_config_filename if File.exist?("#{path}/#{papable_config_filename}")
  end
  deb "File not found! Neither #{ConfigFiles} exist.."
  #      return nil
  DefaultConfigFile
end

#compute_stats_files(opts = {}) ⇒ Object



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/storazzo/ric_disk.rb', line 344

def compute_stats_files(opts = {})
  # Storazzo::RicDisk.calculate_stats_files(path, opts)
  opts_upload_to_gcs = opts.fetch :upload_to_gcs, false
  opts_force_rewrite = opts.fetch :force, false
  opts_stats_file    = opts.fetch :stats_file, 'ricdisk_stats_v11.rds' # default. TODO point to proper..
  dir = path
  puts azure("[compute_stats_files] TODO implement natively. Now I'm being lazy. stats_file=#{opts_stats_file} dir=#{dir}")

  full_file_path = "#{dir}/#{opts_stats_file}"
  deb 'This refactor is for another day. Actually no, TODAY '
  pverbose true,
           "TODO(ricc): you should compute more SMARTLY the full_file_path (#{full_file_path}): if its R/O it should be elsewhere.."
  puts azure("- full_file_path: #{full_file_path}")
  puts azure("- writeable?: #{writeable?}")

  puts("compute_stats_files(#{white dir}): #{white full_file_path}")
  deb "TEST1 DIR EXISTS: #{dir} -> #{File.directory? dir}"
  raise "Directory doesnt exist: #{dir}" unless File.directory?(dir)

  Dir.chdir(dir)
  puts azure `ls` # im curious
  if File.exist?(full_file_path)
    if opts_force_rewrite
      # raise "TODO implement file exists and FORCE enabled"
      RicDisk.compute_stats_for_dir_into_file(dir, full_file_path, 'ReWrite enabled')
    else # File.exists?(full_file_path) and (opts_force)
      puts "File '#{opts_stats_file}' exists already." #  - now should see if its too old, like more than 1 week old"
      # TODO check for file time...
      print "Lines found: #{yellow `wc -l "#{full_file_path}" `.chomp}. File obsolescence (days): #{yellow obsolescence_days(full_file_path)}."
      if obsolescence_days(full_file_path) > 7
        # puts yellow("*** ACHTUNG *** FIle is pretty old. You might consider rotating: #{yellow "mv #{full_file_path} #{full_file_path}_old"}. Or invoke with --force")
        puts yellow("*** ACHTUNG *** FIle is pretty old. I'll force a rewrite")
        RicDisk.compute_stats_for_dir_into_file(dir, full_file_path,
                                                "File older than 7 days. Indeed: #{obsolescence_days(full_file_path)}")
      end
      upload_to_gcs(full_file_path) if opts_upload_to_gcs
    end
  else
    deb('File doesnt exist..')
    RicDisk.compute_stats_for_dir_into_file(dir, full_file_path, "ConfigFile doesn't exist")
  end
end

#initialize_old_way(_path, _opts = {}) ⇒ Object

INSTANCE methods



44
45
46
# File 'lib/storazzo/ric_disk.rb', line 44

def initialize_old_way(_path, _opts = {})
  raise 'Now I dont want a string in input, I want an OBJECT <  Storazzo::Media::AbstractRicDisk'
end

#load_existing_configObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/storazzo/ric_disk.rb', line 80

def load_existing_config
  return unless File.exist?(@ricdisk_file_full) && !File.empty?(@ricdisk_file_full)
  
  begin
    config = YAML.safe_load(File.read(@ricdisk_file_full))
    @disk_uuid = config['disk_uuid']
    @llm_description = config['llm_description']
    @llm_storage_type = config['llm_storage_type']
    @tags = config['tags']
    @name = config['name'] || @name
  rescue StandardError => e
    warn "Error loading existing config from #{@ricdisk_file_full}: #{e.message}"
  end
end

#obsolescence_days(file_path) ⇒ Object

maybe move to a RiccFile class? Maybe even INHERIT from FILE?



277
278
279
# File 'lib/storazzo/ric_disk.rb', line 277

def obsolescence_days(file_path)
  obsolescence_seconds(file_path) / 86_400
end

#obsolescence_seconds(file_path) ⇒ Object

maybe move to a RiccFile class? Maybe even INHERIT from FILE?



270
271
272
273
274
# File 'lib/storazzo/ric_disk.rb', line 270

def obsolescence_seconds(file_path)
  creation_time = File.stat(file_path).ctime
  deb("[obsolescence_seconds] File #{file_path}: #{creation_time} - #{Time.now - creation_time} seconds ago")
  (Time.now - creation_time).to_i
end

#ok_dir?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/storazzo/ric_disk.rb', line 101

def ok_dir?
  !ricdisk_file.nil?
end

#ricdisk_file_empty?Boolean

Returns:

  • (Boolean)


95
96
97
98
99
# File 'lib/storazzo/ric_disk.rb', line 95

def ricdisk_file_empty?
  #      File.empty?("#{local_mountpoint}/.ricdisk.yaml")
  puts "compute_ricdisk_file: #{compute_ricdisk_file}"
  File.empty?(compute_ricdisk_file.to_s) # was (get_ricdisk_file)
end

#to_sObject



117
118
119
# File 'lib/storazzo/ric_disk.rb', line 117

def to_s
  "RicDisk(paz=#{path}, r/w=#{writeable?}, size=#{size}B, f=#{ricdisk_file}, v#{ricdisk_version}, ard=#{@ard})"
end

#to_verbose_sObject



153
154
155
156
157
158
159
160
161
# File 'lib/storazzo/ric_disk.rb', line 153

def to_verbose_s
  h = {}
  h[:to_s] = to_s
  h[:wr] = wr
  h[:inspect] = inspect
  h[:writeable] = writeable?
  h[:ard] = @ard
  h
end

#write_config_yaml_to_disk(subdir, _opts = {}) ⇒ Object

FORMER SBRODOLA, now write_config_yaml_to_disk def self.write_config_yaml_to_disk(subdir, opts={}) # sbrodola_ricdisk(subdir) sbrodola_ricdisk(subdir)



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/storazzo/ric_disk.rb', line 284

def write_config_yaml_to_disk(subdir, _opts = {})
  # given a path, if .ricdisk exists i do stuff with it..
  disk_info = nil
  unless ok_dir? # self.ok_dir?(subdir)
    warn("[write_config_yaml_to_disk] Nothing for me here: '#{subdir}'. Existing")
    return
  end
  ConfigFiles.each do |papable_configfile_name|
    if File.exist?("#{subdir}/#{papable_configfile_name}") && File.empty?("#{subdir}/#{papable_configfile_name}")
      deb("Interesting. Empty file '#{papable_configfile_name}'! Now I write YAML with it.")
      disk_info = RicDisk.new(subdir, papable_configfile_name)
    end
  end
  # if File.exists?( "#{subdir}/.ricdisk") and File.empty?( "#{subdir}/.ricdisk")
  #   deb("Interesting1. Empty file! Now I write YAML with it.")
  #   disk_info = RicDisk.new(subdir, '.ricdisk')
  # end
  # if File.exists?( "#{subdir}/.ricdisk.yaml") and File.empty?( "#{subdir}/.ricdisk.yaml")
  #   deb("Interesting2. Empty file! TODO write YAML with it.")
  #   disk_info = RicDisk.new(subdir, '.ricdisk.yaml')
  #   puts(yellow disk_info.to_yaml)
  # end
  if disk_info.is_a?(RicDisk)
    deb yellow("disk_info.class: #{disk_info.class}")
    if File.empty?(disk_info.absolute_path) # and (disk_info.wr)
      puts(green("yay, we can now write the file '#{disk_info.absolute_path}' (which is R/W, I just checked!) with proper YAML content.."))
      if disk_info.wr
        ret = File.write(disk_info.absolute_path, disk_info.obj_to_yaml)
        puts green("Written file! ret=#{ret}")
      else
        raise 'TODO_IMPLEMENT: write in proper place in config dir'
        puts red('TODO implement me')
      end
    else
      puts(red("Something not right here: either file is NOT empty or disk is NOT writeable.. #{File.empty?(disk_info.absolute_path)}"))
      puts("File size: #{File.size(disk_info.absolute_path)}")
      puts(disk_info.to_s)
      puts(disk_info.obj_to_hash)
      puts(disk_info.obj_to_yaml)
    end
  else # not a RicDisk..
    puts "[write_config_yaml_to_disk] No DiskInfo found across #{ConfigFiles}. I leave this function empty-handed."
  end

  # disk_info.absolute_path
  # if File.exists?( "#{subdir}/.ricdisk") and ! File.empty?( "#{subdir}/.ricdisk")
  # if File.exists?(disk_info.absolute_path) and ! File.empty?(disk_info.absolute_path)
  #   puts("Config File found with old-style name: '#{subdir}/.ricdisk' ! Please move it to .ricdisk.yaml!")
  #   puts(white `cat "#{disk_info.absolute_path}"`)
  # else
  #   puts "WRITING NOW. [I BELIEVE THIS IS DUPE CODE - see a few lines above!] disk_info.obj_to_yaml .. to #{compute_ricdisk_file}"
  #   File.open(ricdisk_file_full, 'w').write(disk_info.obj_to_yaml)
  # end
end

#writeable?Boolean

Returns:

  • (Boolean)


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/storazzo/ric_disk.rb', line 131

def writeable?
  # memoize
  return @wr unless @wr.nil?

  # NOW: CALCULATE it
  # Now I can do ONCE an EXPENSIVE calculation
  puts yellow("[RicDisk.writeable] TODO(ricc): Do expensive calculation if this FS is writeable: #{path} and write/memoize it on @wr once and for all")
  puts yellow('[RicDisk.writeable]             I have a feeling this should be delegated to praecipuus Storazzo::Media::Object we refer to (WR is different on GCS vs Local):') # infinite loop dammit #{self.to_verbose_s}")
  puts("Dir: #{azure path}")
  puts("absolute_path: #{azure absolute_path}")
  puts("File.writable?(absolute_path): #{azure File.writable?(absolute_path)}")
  bash_output = `if [ -w "#{absolute_path}" ]; then echo "WRITABLE"; else echo "NOT WRITABLE"; fi`
  puts("bash_output: #{azure bash_output}")
  # @wr = File.writable?(File.expand_path(@ricdisk_file)) # rescue false
  raise "for some reason an important info (ricdisk_file='#{absolute_path}') is missing!" if ricdisk_file.nil?

  @wr = File.writable?(absolute_path) # rescue false
  @wr
  # :boh_todo_fix_me_and_compute
  # false
end