File: file_system.rb

package info (click to toggle)
ruby-puppetserver-ca-cli 2.7.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 696 kB
  • sloc: ruby: 6,970; sh: 4; makefile: 3
file content (109 lines) | stat: -rw-r--r-- 3,057 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
require 'etc'
require 'fileutils'

module Puppetserver
  module Ca
    module Utils
      class FileSystem

        DIR_MODES = {
          :ssldir => 0771,
          :cadir => 0755,
          :certdir => 0755,
          :privatekeydir => 0750,
          :publickeydir => 0755,
          :signeddir => 0755
        }

        def self.instance
          @instance ||= new
        end

        def self.write_file(*args)
          instance.write_file(*args)
        end

        def self.ensure_dirs(one_or_more_dirs)
          Array(one_or_more_dirs).each do |directory|
            instance.ensure_dir(directory)
          end
        end

        def self.validate_file_paths(one_or_more_paths)
          errors = []
          Array(one_or_more_paths).each do |path|
            if !File.exist?(path) || !File.readable?(path)
              errors << "Could not read file '#{path}'"
            end
          end

          errors
        end

        def self.check_for_existing_files(one_or_more_paths)
          errors = []
          Array(one_or_more_paths).each do |path|
            if File.exist?(path)
              errors << "Existing file at '#{path}'"
            end
          end
          errors
        end

        def self.forcibly_symlink(source, link_target)
          FileUtils.remove_dir(link_target, true)
          FileUtils.symlink(source, link_target)
          # Ensure the symlink has the same ownership as the source.
          # This requires using `FileUtils.chown` rather than `File.chown`, as
          # the latter will update the ownership of the source rather than the
          # link itself.
          # Symlink permissions are ignored in favor of the source's permissions,
          # so we don't have to change those.
          source_info = File.stat(source)
          FileUtils.chown(source_info.uid, source_info.gid, link_target)
        end

        def initialize
          @user, @group = find_user_and_group
        end

        def find_user_and_group
          if !running_as_root?
            return Process.euid, Process.egid
          else
            if pe_puppet_exists?
              return 'pe-puppet', 'pe-puppet'
            else
              return 'puppet', 'puppet'
            end
          end
        end

        def running_as_root?
          !Gem.win_platform? && Process.euid == 0
        end

        def pe_puppet_exists?
          !!(Etc.getpwnam('pe-puppet') rescue nil)
        end

        def write_file(path, one_or_more_objects, mode)
          File.open(path, 'w', mode) do |f|
            Array(one_or_more_objects).each do |object|
              f.puts object.to_s
            end
          end
          FileUtils.chown(@user, @group, path)
        end

        # Warning: directory mode should be specified in DIR_MODES above
        def ensure_dir(directory)
          if !File.exist?(directory)
            FileUtils.mkdir_p(directory, mode: DIR_MODES[directory])
            FileUtils.chown(@user, @group, directory)
          end
        end
      end
    end
  end
end