Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Sat, May 17, 11:36 PM
diff --git a/app/models/bacula_file.rb b/app/models/bacula_file.rb
index abbab57..14a7cd5 100644
--- a/app/models/bacula_file.rb
+++ b/app/models/bacula_file.rb
@@ -1,19 +1,20 @@
+# ActiveRecord class for Bacula's File resource
class BaculaFile < ActiveRecord::Base
self.table_name = :File
self.primary_key = :FileId
alias_attribute :file_index, :FileIndex
alias_attribute :job_id, :JobId
alias_attribute :path_id, :PathId
alias_attribute :filename_id, :FilenameId
alias_attribute :delta_seq, :DeltaSeq
alias_attribute :mark_id, :MarkId
alias_attribute :l_stat, :LStat
alias_attribute :md5, :MD5
belongs_to :path, foreign_key: :PathId
belongs_to :filename, foreign_key: :FilenameId
belongs_to :job, foreign_key: :JobId
has_many :base_files, foreign_key: :FileId
end
diff --git a/app/models/client.rb b/app/models/client.rb
index efd0405..e8a9a36 100644
--- a/app/models/client.rb
+++ b/app/models/client.rb
@@ -1,99 +1,102 @@
+# Bacula Client class.
+# All hosts that are getting backed up with Bacula have a Client entry, with
+# attributes concerning the Client.
class Client < ActiveRecord::Base
self.table_name = :Client
self.primary_key = :ClientId
alias_attribute :name, :Name
alias_attribute :uname, :Uname
alias_attribute :auto_prune, :AutoPrune
alias_attribute :file_retention, :FileRetention
alias_attribute :job_retention, :JobRetention
has_many :jobs, foreign_key: :ClientId
has_one :host, foreign_key: :name, primary_key: :Name
scope :for_user, ->(user_id) { joins(host: :users).where(users: { id: user_id }) }
DAY_SECS = 60 * 60 * 24
# Fetches the client's job_templates that are already persisted to
# Bacula's configuration
#
# @return [ActiveRecord::Relation] of `JobTemplate`
def persisted_jobs
host.job_templates.where(baculized: true).includes(:fileset, :schedule)
end
# Fetches the client's performed jobs in reverse chronological order
#
# @return [ActiveRecord::Relation] of `Job`
def recent_jobs
jobs.order(EndTime: :desc).includes(:file_set)
end
# Helper method. It shows the client's job retention,
# (which is expressed in seconds) in days.
#
# @return [Integer]
def job_retention_days
job_retention / DAY_SECS
end
# Helper method. It shows the client's file retention,
# (which is expressed in seconds) in days.
#
# @return [Integer]
def file_retention_days
file_retention / DAY_SECS
end
# Helper method for auto_prune
#
# @return [String] 'yes' or 'no'
def auto_prune_human
auto_prune == 1 ? 'yes' : 'no'
end
# Helper method for displayin the last job's datetime in a nice format.
def last_job_date_formatted
if job_time = jobs.backup_type.last.try(:end_time)
I18n.l(job_time, format: :long)
end
end
# Shows if a client has any backup jobs to Bacule config
#
# @return [Boolean]
def is_backed_up?
jobs.backup_type.any?
end
# Shows the total file size of the jobs that run for a specific client
#
# @return [Integer] Size in Bytes
def backup_jobs_size
jobs.backup_type.map(&:job_bytes).sum
end
# Shows the total files' count for the jobs that run for a specific client
#
# @return [Integer] File count
def files_count
jobs.map(&:job_files).sum
end
# Fetches the client's jobs that are running at the moment
#
# @return [Integer]
def running_jobs
jobs.running.count
end
# Displays the bacula config that is generated from the client's
# host
#
# @return [String]
def bacula_config
return unless host
host.baculize_config.join("\n")
end
end
diff --git a/app/models/counter.rb b/app/models/counter.rb
index 99d15a7..01a08aa 100644
--- a/app/models/counter.rb
+++ b/app/models/counter.rb
@@ -1,10 +1,13 @@
+# Bacula Counter table
+#
+# The Counter table contains one entry for each permanent counter defined by the user.
class Counter < ActiveRecord::Base
self.table_name = :Counters
self.primary_key = :Counter
alias_attribute :counter, :Counter
alias_attribute :min_value, :MinValue
alias_attribute :max_value, :MaxValue
alias_attribute :current_value, :CurrentValue
alias_attribute :wrap_coounter, :WrapCounter
end
diff --git a/app/models/file_set.rb b/app/models/file_set.rb
index 9896de0..a5b4adf 100644
--- a/app/models/file_set.rb
+++ b/app/models/file_set.rb
@@ -1,11 +1,19 @@
+# Bacula FileSet table.
+#
+# The FileSet table contains one entry for each FileSet that is used.
+# The MD5 signature is kept to ensure that if the user changes anything inside the FileSet,
+# it will be detected and the new FileSet will be used.
+# This is particularly important when doing an incremental update.
+# If the user deletes a file or adds a file, we need to ensure that a Full backup is done
+# prior to the next incremental.
class FileSet < ActiveRecord::Base
self.table_name = :FileSet
self.primary_key = :FileSetId
alias_attribute :file_set_id, :FileSetId
alias_attribute :file_set, :FileSet
alias_attribute :md5, :MD5
alias_attribute :create_time, :CreateTime
has_many :jobs, foreign_key: :FileSetId
end
diff --git a/app/models/filename.rb b/app/models/filename.rb
index a612570..63f2590 100644
--- a/app/models/filename.rb
+++ b/app/models/filename.rb
@@ -1,9 +1,14 @@
+# Bacula Filename
+#
+# The Filename table contains the name of each file backed up with the path removed.
+# If different directories or machines contain the same filename,
+# only one copy will be saved in this table.
class Filename < ActiveRecord::Base
self.table_name = :Filename
self.primary_key = :FilenameId
alias_attribute :filename_id, :FilenameId
alias_attribute :name, :Name
has_many :bacula_files, foreign_key: :FilenameId
end
diff --git a/app/models/job.rb b/app/models/job.rb
index 21f404a..10cbaa4 100644
--- a/app/models/job.rb
+++ b/app/models/job.rb
@@ -1,99 +1,126 @@
+# Bacula Job table.
+#
+# The Job table contains one record for each Job run by Bacula.
+# Thus normally, there will be one per day per machine added to the database.
+# Note, the JobId is used to index Job records in the database, and it often is shown to the user
+# in the Console program.
+# However, care must be taken with its use as it is not unique from database to database.
+# For example, the user may have a database for Client data saved on machine Rufus and another
+# database for Client data saved on machine Roxie.
+# In this case, the two database will each have JobIds that match those in another database.
+# For a unique reference to a Job, see Job below.
+#
+# The Name field of the Job record corresponds to the Name resource record given in the
+# Director's configuration file.
+# Thus it is a generic name, and it will be normal to find many Jobs (or even all Jobs)
+# with the same Name.
+#
+# The Job field contains a combination of the Name and the schedule time of the Job by the Director.
+# Thus for a given Director, even with multiple Catalog databases, the Job will contain a unique
+# name that represents the Job.
+#
+# For a given Storage daemon, the VolSessionId and VolSessionTime form a unique identification
+# of the Job.
+#
+# This will be the case even if multiple Directors are using the same Storage daemon.
+#
+# The Job Type (or simply Type) can have one of the following values:
class Job < ActiveRecord::Base
self.table_name = :Job
self.primary_key = :JobId
alias_attribute :job_id, :JobId
alias_attribute :job, :Job
alias_attribute :name, :Name
alias_attribute :type, :Type
alias_attribute :level, :Level
alias_attribute :client_id, :ClientId
alias_attribute :job_status, :JobStatus
alias_attribute :sched_time, :SchedTime
alias_attribute :start_time, :StartTime
alias_attribute :end_time, :EndTime
alias_attribute :real_end_time, :RealEndTime
alias_attribute :job_t_date, :JobTDate
alias_attribute :vol_session_id, :VolSessionId
alias_attribute :vol_session_time, :VolSessionTime
alias_attribute :job_files, :JobFiles
alias_attribute :job_bytes, :JobBytes
alias_attribute :read_bytes, :ReadBytes
alias_attribute :job_errors, :JobErrors
alias_attribute :job_missing_files, :JobMissingFiles
alias_attribute :pool_id, :PoolId
alias_attribute :file_set_id, :FileSetId
alias_attribute :prior_job_id, :PriorJobId
alias_attribute :purged_files, :PurgedFiles
alias_attribute :has_base, :HasBase
alias_attribute :has_cache, :HasCache
alias_attribute :reviewed, :Reviewed
alias_attribute :comment, :Comment
belongs_to :pool, foreign_key: :PoolId
belongs_to :file_set, foreign_key: :FileSetId
belongs_to :client, foreign_key: :ClientId
has_many :bacula_files, foreign_key: :JobId
has_many :base_files, foreign_key: :BaseJobId
has_many :job_media, foreign_key: :JobId
has_many :logs, foreign_key: :JobId
scope :running, -> { where(job_status: 'R') }
scope :backup_type, -> { where(type: 'B') }
scope :restore_type, -> { where(type: 'R') }
HUMAN_STATUS = {
'A' => 'Canceled by user',
'B' => 'Blocked',
'C' => 'Created, not yet running',
'D' => 'Verify found differences',
'E' => 'Terminated with errors',
'F' => 'Waiting for Client',
'M' => 'Waiting for media mount',
'R' => 'Running',
'S' => 'Waiting for Storage daemon',
'T' => 'Completed successfully',
'a' => 'SD despooling attributes',
'c' => 'Waiting for client resource',
'd' => 'Waiting on maximum jobs',
'e' => 'Non-fatal error',
'f' => 'Fatal error',
'i' => 'Doing batch insert file records',
'j' => 'Waiting for job resource',
'm' => 'Waiting for new media',
'p' => 'Waiting on higher priority jobs',
's' => 'Waiting for storage resource',
't' => 'Waiting on start time'
}
paginates_per 20
def level_human
{
'F' => 'Full',
'D' => 'Differential',
'I' => 'Incremental'
}[level]
end
def status_human
HUMAN_STATUS[job_status]
end
def fileset
file_set.try(:file_set) || '-'
end
def start_time_formatted
if start_time
I18n.l(start_time, format: :long)
end
end
def end_time_formatted
if end_time
I18n.l(end_time, format: :long)
end
end
end
diff --git a/app/models/job_histo.rb b/app/models/job_histo.rb
index a74a775..af72743 100644
--- a/app/models/job_histo.rb
+++ b/app/models/job_histo.rb
@@ -1,35 +1,39 @@
+# Bacula JobHisto table.
+#
+# The bf JobHisto table is the same as the Job table,
+# but it keeps long term statistics (i.e. it is not pruned with the Job).
class JobHisto < ActiveRecord::Base
self.table_name = :JobHisto
alias_attribute :job_id, :JobId
alias_attribute :job, :Job
alias_attribute :name, :Name
alias_attribute :type, :Type
alias_attribute :level, :Level
alias_attribute :client_id, :ClientId
alias_attribute :job_status, :JobStatus
alias_attribute :sched_time, :SchedTime
alias_attribute :start_time, :StartTime
alias_attribute :end_time, :EndTime
alias_attribute :real_end_time, :RealEndTime
alias_attribute :job_t_date, :JobTDate
alias_attribute :vol_session_id, :VolSessionId
alias_attribute :vol_session_time, :VolSessionTime
alias_attribute :job_files, :JobFiles
alias_attribute :job_bytes, :JobBytes
alias_attribute :read_bytes, :ReadBytes
alias_attribute :job_errors, :JobErrors
alias_attribute :job_missing_files, :JobMissingFiles
alias_attribute :pool_id, :PoolId
alias_attribute :file_set_id, :FileSetId
alias_attribute :prior_job_id, :PriorJobId
alias_attribute :purged_files, :PurgedFiles
alias_attribute :has_base, :HasBase
alias_attribute :has_cache, :HasCache
alias_attribute :reviewed, :Reviewed
alias_attribute :comment, :Comment
belongs_to :client, foreign_key: :ClientId
belongs_to :pool, foreign_key: :PoolId
belongs_to :file_set, foreign_key: :FileSetId
end
diff --git a/app/models/job_media.rb b/app/models/job_media.rb
index 8f07497..7480f77 100644
--- a/app/models/job_media.rb
+++ b/app/models/job_media.rb
@@ -1,18 +1,35 @@
+# Bacula JobMedia table.
+#
+# The JobMedia table contains one entry at the following:
+#
+# * start of the job,
+# * start of each new tape file,
+# * start of each new tape,
+# * end of the job.
+#
+# Since by default, a new tape file is written every 2GB, in general, you will have more
+# than 2 JobMedia records per Job.
+# The number can be varied by changing the "Maximum File Size" specified in the Device resource.
+# This record allows Bacula to efficiently position close to (within 2GB) any given file in a backup.
+# For restoring a full Job, these records are not very important, but if you want to retrieve a
+# single file that was written near the end of a 100GB backup, the JobMedia records can speed it
+# up by orders of magnitude by permitting forward spacing files and blocks rather than reading
+# the whole 100GB backup.
class JobMedia < ActiveRecord::Base
self.table_name = :JobMedia
self.primary_key = :JobMediaId
alias_attribute :job_media_id, :JobMediaId
alias_attribute :job_id, :JobId
alias_attribute :media_id, :MediaId
alias_attribute :first_index, :FirstIndex
alias_attribute :last_index, :LastIndex
alias_attribute :start_file, :StartFile
alias_attribute :end_file, :EndFile
alias_attribute :start_block, :StartBlock
alias_attribute :end_block, :EndBlock
alias_attribute :vol_index, :VolIndex
belongs_to :Job, foreign_key: :JobId
belongs_to :Media, foreign_key: :MediaId
end
diff --git a/app/models/location.rb b/app/models/location.rb
index 4411af5..15abd8b 100644
--- a/app/models/location.rb
+++ b/app/models/location.rb
@@ -1,12 +1,15 @@
+# Bacula Location table.
+#
+# The Location table defines where a Volume is physically.
class Location < ActiveRecord::Base
self.table_name = :Location
self.primary_key = :LocationId
alias_attribute :location_id, :LocationId
alias_attribute :location, :Location
alias_attribute :cost, :Cost
alias_attribute :enabled, :Enabled
has_many :media, foreign_key: :LocationId
has_many :location_logs, foreign_key: :LocationId
end
diff --git a/app/models/location_log.rb b/app/models/location_log.rb
index c82ddd2..57119c8 100644
--- a/app/models/location_log.rb
+++ b/app/models/location_log.rb
@@ -1,15 +1,16 @@
+# Bacula LocationLog table
class LocationLog < ActiveRecord::Base
self.table_name = :LocationLog
self.primary_key = :LocLogId
alias_attribute :loc_log_id, :LocLogId
alias_attribute :date, :Date
alias_attribute :comment, :Comment
alias_attribute :media_id, :MediaId
alias_attribute :location_id, :LocationId
alias_attribute :new_vol_status, :NewVolStatus
alias_attribute :new_enabled, :NewEnabled
belongs_to :media, foreign_key: :MediaId
belongs_to :location, foreign_key: :LocationId
end
diff --git a/app/models/log.rb b/app/models/log.rb
index 2a67b3e..672d966 100644
--- a/app/models/log.rb
+++ b/app/models/log.rb
@@ -1,19 +1,22 @@
+# Bacula Log table.
+#
+# The Log table contains a log of all Job output.
class Log < ActiveRecord::Base
self.table_name = :Log
self.primary_key = :LogId
alias_attribute :log_id, :LogId
alias_attribute :job_id, :JobId
alias_attribute :time, :Time
alias_attribute :log_text, :LogText
belongs_to :job, foreign_key: :JobId
paginates_per 20
def time_formatted
if time
I18n.l(time, format: :long)
end
end
end
diff --git a/app/models/media.rb b/app/models/media.rb
index 339d4b7..7938be1 100644
--- a/app/models/media.rb
+++ b/app/models/media.rb
@@ -1,55 +1,61 @@
+# Bacula Media table (Volume)
+#
+# Media table contains one entry for each volume, that is each tape, cassette (8mm, DLT, DAT, ...),
+# or file on which information is or was backed up.
+# There is one Volume record created for each of the NumVols specified in the
+# Pool resource record.
class Media < ActiveRecord::Base
self.table_name = :Media
self.primary_key = :MediaId
alias_attribute :media_id, :MediaId
alias_attribute :volume_name, :VolumeName
alias_attribute :slot, :Slot
alias_attribute :pool_id, :PoolId
alias_attribute :media_type, :MediaType
alias_attribute :media_type_id, :MediaTypeId
alias_attribute :label_type, :LabelType
alias_attribute :first_written, :FirstWritten
alias_attribute :last_written, :LastWritten
alias_attribute :label_date, :LabelDate
alias_attribute :vol_jobs, :VolJobs
alias_attribute :vol_files, :VolFiles
alias_attribute :vol_blocks, :VolBlocks
alias_attribute :vol_mounts, :VolMounts
alias_attribute :vol_bytes, :VolBytes
alias_attribute :vol_parts, :VolParts
alias_attribute :vol_errors, :VolErrors
alias_attribute :vol_writes, :VolWrites
alias_attribute :vol_capacity_bytes, :VolCapacityBytes
alias_attribute :vol_status, :VolStatus
alias_attribute :enabled, :Enabled
alias_attribute :recycle, :Recycle
alias_attribute :action_on_purge, :ActionOnPurge
alias_attribute :vol_retention, :VolRetention
alias_attribute :vol_use_duration, :VolUseDuration
alias_attribute :max_vol_jobs, :MaxVolJobs
alias_attribute :max_vol_files, :MaxVolFiles
alias_attribute :max_vol_bytes, :MaxVolBytes
alias_attribute :in_changer, :InChanger
alias_attribute :storage_id, :StorageId
alias_attribute :device_id, :DeviceId
alias_attribute :media_addressing, :MediaAddressing
alias_attribute :vol_read_time, :VolReadTime
alias_attribute :vol_write_time, :VolWriteTime
alias_attribute :end_file, :EndFile
alias_attribute :end_block, :EndBlock
alias_attribute :location_id, :LocationId
alias_attribute :recycle_count, :RecycleCount
alias_attribute :initial_write, :InitialWrite
alias_attribute :scratch_pool_id, :ScratchPoolId
alias_attribute :recycle_pool_id, :RecyclePoolId
alias_attribute :comment, :Comment
belongs_to :pool, foreign_key: :PoolId
belongs_to :storage, foreign_key: :StorageId
belongs_to :device, foreign_key: :DeviceId
belongs_to :location, foreign_key: :LocationId
has_many :job_media, foreign_key: :MediaId
has_many :location_logs, foreign_key: :MediaId
end
diff --git a/app/models/path.rb b/app/models/path.rb
index 847b32d..dd6eacd 100644
--- a/app/models/path.rb
+++ b/app/models/path.rb
@@ -1,9 +1,16 @@
+# Bacula Path table.
+#
+# The Path table contains shown above the path or directory names of all directories on
+# the system or systems.
+# As with the filename, only one copy of each directory name is kept regardless of how
+# many machines or drives have the same directory.
+# These path names should be stored in Unix path name format.
class Path < ActiveRecord::Base
self.table_name = :Path
self.primary_key = :PathId
alias_attribute :path_id, :PathId
alias_attribute :path, :Path
has_many :bacula_files, foreign_key: :PathId
end
diff --git a/app/models/pool.rb b/app/models/pool.rb
index 301263a..8061ea9 100644
--- a/app/models/pool.rb
+++ b/app/models/pool.rb
@@ -1,37 +1,45 @@
+# Bacula Pool
+#
+# The Pool table contains one entry for each media pool controlled by Bacula in
+# this database. One media record exists for each of the NumVols contained in the Pool.
+# The PoolType is a Bacula defined keyword.
+# The MediaType is defined by the administrator, and corresponds to the MediaType
+# specified in the Director's Storage definition record.
+# The CurrentVol is the sequence number of the Media record for the current volume.
class Pool < ActiveRecord::Base
self.table_name = :Pool
self.primary_key = :PoolId
alias_attribute :pool_id, :PoolId
alias_attribute :name, :Name
alias_attribute :num_vols, :NumVols
alias_attribute :max_vols, :MaxVols
alias_attribute :use_once, :UseOnce
alias_attribute :use_catalog, :UseCatalog
alias_attribute :accept_any_volume, :AcceptAnyVolume
alias_attribute :vol_retention, :VolRetention
alias_attribute :vol_use_duration, :VolUseDuration
alias_attribute :max_vol_jobs, :MaxVolJobs
alias_attribute :max_vol_files, :MaxVolFiles
alias_attribute :max_vol_bytes, :MaxVolBytes
alias_attribute :auto_prune, :AutoPrune
alias_attribute :recycle, :Recycle
alias_attribute :action_on_purge, :ActionOnPurge
alias_attribute :pool_type, :PoolType
alias_attribute :label_type, :LabelType
alias_attribute :label_format, :LabelFormat
alias_attribute :enabled, :Enabled
alias_attribute :scratch_pool_id, :ScratchPoolId
alias_attribute :recycle_pool_id, :RecyclePoolId
alias_attribute :next_pool_id, :NextPoolId
alias_attribute :migration_high_bytes, :MigrationHighBytes
alias_attribute :migration_low_bytes, :MigrationLowBytes
alias_attribute :migration_time, :MigrationTime
has_many :jobs, foreign_key: :PoolId
has_many :media, foreign_key: :PoolId
def self.available_options
pluck(:Name)
end
end
diff --git a/app/models/status.rb b/app/models/status.rb
index 9ced15a..c6667ed 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -1,8 +1,14 @@
+# Bacula Status table.
+#
+# Status table is a lookup table linking:
+#
+# * jobs' status codes and
+# * status codes' messages
class Status < ActiveRecord::Base
self.table_name = :Status
self.primary_key = :JobStatus
alias_attribute :job_status, :JobStatus
alias_attribute :job_status_long, :JobStatusLong
alias_attribute :severity, :Severity
end
diff --git a/app/models/storage.rb b/app/models/storage.rb
index f99950d..016e9f6 100644
--- a/app/models/storage.rb
+++ b/app/models/storage.rb
@@ -1,14 +1,17 @@
+# Bacula Storage table
+#
+# The Storage table contains one entry for each Storage used.
class Storage < ActiveRecord::Base
self.table_name = :Storage
self.primary_key = :StorageId
alias_attribute :storage_id, :StorageId
alias_attribute :name, :Name
alias_attribute :auto_changer, :AutoChanger
has_many :media, foreign_key: :StorageId
def self.available_options
pluck(:Name)
end
end
diff --git a/app/models/unsaved_file.rb b/app/models/unsaved_file.rb
index 56b4866..72501c4 100644
--- a/app/models/unsaved_file.rb
+++ b/app/models/unsaved_file.rb
@@ -1,9 +1,10 @@
+# Bacula UnsavedFile table
class UnsavedFile < ActiveRecord::Base
self.table_name = :UnsavedFiles
self.primary_key = :UnsavedId
alias_attribute :unsaved_id, :UnsavedId
alias_attribute :job_id, :JobId
alias_attribute :path_id, :PathId
alias_attribute :filename_id, :FilenameId
end
diff --git a/app/models/version.rb b/app/models/version.rb
index 1e17cc4..e823f49 100644
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -1,5 +1,10 @@
+# Bacula Version table
+#
+# The Version table defines the Bacula database version number.
+# Bacula checks this number before reading the database to ensure that it is
+# compatible with the Bacula binary file.
class Version < ActiveRecord::Base
self.table_name = :Version
alias_attribute :version_id, :VersionId
end

Event Timeline