# # # = Jeeves Disk # # == a single area to store files and part of a set of disks making up a store # # Author:: Robert Sharp # Copyright:: Copyright (c) 2013 Robert Sharp # License:: Open Software Licence v3.0 # # This software is licensed for use under the Open Software Licence v. 3.0 # The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php # and in the file copyright.txt. Under the terms of this licence, all derivative works # must themselves be licensed under the Open Software Licence v. 3.0 # # # require 'jeeves/errors' require 'jeeves/utils' module Jeeves # a unit of storage that can be added into a store class Partition #include Jeeves::Utils # create a partition, regardless of what state it is in def initialize(path, options={}) @path = File.expand_path(path) @key = options[:key] @key_file = File.join(@path, '.jeeves.key') @file_list = File.join(@path, '.jeeves_store.rb') @mount_point = options[:mount_point] || @path # assume the disk is not ready @mounted = false @ready = false # check status if FileTest.writable?(@path) then # seems to be there, but is it correct? if FileTest.exists?(@key_file) then # there is a key file so assume it is mounted @mounted = true @ready = key_ok? end else unless @path == @mount_point then # check if mount_point is mounted if FileTest.writable?(@mount_point) then @mounted = true end end end #if @total_space = 0 @free_space = 0 @device = '' update_space end # path to the partition attr_reader :path # boolean flag to indicate if the partition is mounted # @deprecated use {#mounted?} instead attr_reader :mounted # test if the partition is mounted def mounted? return @mounted end attr_reader :ready # test if the partition is ready to use def ready? return @ready end # return the device on which the partition resides (e.g. /dev/sda1) attr_reader :device # return the total space in the partition (in 1K blocks) attr_reader :total_space # return the free space in the partitions (in 1K blocks) attr_reader :free_space # return tha path to where the file list would be or is attr_reader :file_list # flag the partition as a duplicate attr_accessor :duplicate # return the date of the file_list if it exists or nil otherwise # The returned value is the modification time of the file def file_list_date return nil if @file_list.nil? return File.mtime(@file_list) end # test if the file list exists def file_list? return FileTest.exists?(@file_list) end # test that the key given at init is the same as the key # on the disk def key_ok? # get the key in the keyfile return false if @key.nil? return false unless File.exists?(@key_file) file_key = File.readlines(@key_file).first.chomp return file_key == @key end # return the free space in 1K blocks on the given path def update_space return unless @ready # use df to get the free space for path df_lines = `/bin/df -Pk #{@path}`.split("\n") df_fields = df_lines[1].split @device = df_fields[0] @total_space = df_fields[1].to_i @free_space = df_fields[3].to_i end def display(cols) return @path.ljust(cols.shift) + (@mounted ? 'OK' : 'No').ljust(cols.shift) + (@ready ? 'OK': 'No').ljust(cols.shift) + (@duplicate ? '*': '').ljust(cols.shift) + Jeeves.human_size(@total_space).rjust(cols.shift) + Jeeves.human_size(@free_space).rjust(cols.shift) end def to_a return [@path, (@mounted ? 'OK' : 'No'), (@ready ? 'OK': 'No'), (@duplicate ? '*': ''), Jeeves.human_size(@total_space), Jeeves.human_size(@free_space)] end # create a key and save it to the disk # # This will raise an exception if the key file already exists or cannot be written # but it can be forced to create the key anyway # # @param [Boolean] force the key file to be created if one already exists def create_key(force=false) # check that path is writable unless FileTest.writable?(@path) raise Jeeves::InvalidPartition, "Cannot write to #{path}" end if FileTest.exists?(@key_file) && !force then raise Jeeves::InvalidPartitionKey, "Keyfile already exists at #{path}" end @key = Digest::SHA1.hexdigest(Time.now.to_s + rand(12341234).to_s) File.open(@key_file, 'w') do |kfile| kfile.puts @key end return @key end end end