Class: Xolo::Server::Title
- Inherits:
-
Core::BaseClasses::Title
- Object
- Core::BaseClasses::Title
- Xolo::Server::Title
- Includes:
- Helpers::JamfPro, Helpers::Log, Helpers::Notification, Helpers::TitleEditor, Mixins::Changelog, Mixins::TitleJamfAccess, Mixins::TitleTedAccess
- Defined in:
- lib/xolo/server/title.rb
Overview
A Title in Xolo, as used on the server
The code in this file mostly deals with the data on the Xolo server itself, and general methods for manipulating the title.
Code for interacting with the Title Editor and Jamf Pro are in the helpers and mixins.
NOTE be sure to only instantiate these using the servers 'instantiate_title' method, or else they might not have all the correct innards
Constant Summary collapse
- TITLES_DIR =
On the server, xolo titles are represented by directories in this directory, named with the title name.
So a title 'foobar' would have a directory (Xolo::Server::DATA_DIR)/titles/foobar/ and in there will be a file foobar.json with the data for the Title instance itself
Also in there will be a 'versions' dir containing json files for each version of the title. See Version
Xolo::Server::DATA_DIR + 'titles'
- NEW_TITLE_CURRENT_VERSION =
when creating new titles in the title editor, This is the 'currentVersion', which is required when creating. When the first version/patch is added, the title's value for this will be updated.
'0.0.0'- VERSION_SCRIPT_FILENAME =
If a title has a 'version_script' the the contents are stored in the title dir in a file with this name
'version-script'- UNINSTALL_SCRIPT_FILENAME =
If a title is uninstallable, it will have a script in Jamf, which is also saved in this file on the xolo server.
'uninstall-script'- JAMF_INSTALLED_GROUP_NAME_SUFFIX =
'installed'- JAMF_FROZEN_GROUP_NAME_SUFFIX =
'frozen'- JAMF_MANUAL_INSTALL_RELEASED_POL_SUFFIX =
'install'- JAMF_UNINSTALL_SUFFIX =
'uninstall'- JAMF_EXPIRE_SUFFIX =
'expire'- CLIENT_EXPIRE_COMMAND =
the expire policy will run this client command, appending the title We don't specify a full path so that localized installations will work as long as its in roots default path e.g. /usr/local/bin vs /usr/local/pixar/bin
'xolo expire'- SELF_SERVICE_ICON_FILENAME =
When we are given a Self Service icon for the title, we might not be ready to upload it to jamf, cuz until we have a version to pilot, there's nothing IN jamf. So we always store it locally in this file inside the title dir. The extension from the original file will be appended, e.g. '.png'
'self-service-icon'- JPAPI_PATCH_TITLE_RSRC =
The JPAPI endpoint for Patch Titles.
ruby-jss still uses the Classic API for Patch Titles, and won't by migrated to JPAPI until Jamf fully implements all aspects of patch management to JPAPI. As of this writing, that's not the case. But, the JPAPI endpoint for Patch Title Reporting returns more detailed data than the Classic API, so we use it here, and will keep using it as we move forward.
This is the top-level endpoint for all patch titles, see JPAPI_PATCH_REPORT_RSRC for the reporting endpoint below it.
TODO: Remove this and update relevant methods when ruby-jss is updated to use JPAPI for Patch Titles..
'v2/patch-software-title-configurations'- JPAPI_PATCH_REPORT_RSRC =
The JPAPI endpoint for patch reporting. The JPAPI_PATCH_TITLE_RSRC is appended with "/
/#JPAPI_PATCH_REPORT_RSRC" to get the URL for the patch report for a specific title. TODO: Remove this and update relevant methods when ruby-jss is updated to use JPAPI for Patch Titles..
'patch-report'- SELF_SERVICE_INSTALL_BTN_TEXT =
'Install'
Constants included from Mixins::Changelog
Mixins::Changelog::TITLE_CHANGELOG_FILENAME
Constants included from Helpers::Notification
Helpers::Notification::ALERT_TOOL_EMAIL_PREFIX, Helpers::Notification::DFT_EMAIL_FROM
Constants included from Helpers::JamfPro
Helpers::JamfPro::PATCH_REPORT_JPAPI_PAGE_SIZE, Helpers::JamfPro::PATCH_REPORT_UNKNOWN_VERSION
Instance Attribute Summary collapse
-
#changes_for_update ⇒ Hash
readonly
Also when applying updates, this will hold the changes being made: the differences between tne current attributes and the new_data_for_update We'll figure this out at the start of the update and can use it later to 1) avoid doing things we don't need to 2) log the changes in the change log at the very end.
-
#current_action ⇒ Symbol
The current action being taken on this title one of :creating, :updating, :deleting.
-
#jamf_expire_policy_name ⇒ String
readonly
If a title is expirable, it will have a policy in Jamf named 'xolo-
-expire' that will run the expiration process daily, at checkin or using a trigger of the same name. -
#jamf_frozen_group_name ⇒ String
readonly
For each title there will be a static group containing macs that should not get any automatic installs or updates, They should be 'frozen' at whatever version was installed when they were added to the group.
-
#jamf_installed_group_name ⇒ String
readonly
For each title there will be a smart group containing all macs that have any version of the title installed.
-
#jamf_manual_install_released_policy_name ⇒ Object
readonly
The name of the policy that does initial manual or self-service installs of the currently-released version of this title.
-
#jamf_obj_name_pfx ⇒ String
readonly
The prefix for all jamf objects for this title, which is 'xolo-
' or 'xolotest- ' for test server. -
#jamf_patch_source_id ⇒ String
The jamf ID of the patch source for this title if the title is subscribed.
-
#jamf_uninstall_policy_name ⇒ String
readonly
If a title is uninstallable, it will have a policy in Jamf named 'xolo-
-uninstall' that will run the script of the same name, using a trigger of the same name. -
#jamf_uninstall_script_name ⇒ String
readonly
If a title is uninstallable, it will have a script in Jamf named 'xolo-
-uninstall'. -
#new_data_for_update ⇒ Hash
readonly
when applying updates, the new data from xadm is stored here so it can be accessed by update-methods and compared to the current instance values both for updating the title, and the versions.
-
#releasing_version ⇒ String
If current action is :releasing, this is the version being released.
-
#server_app_instance ⇒ Xolo::Server::App
The instance of Xolo::Server::App that instantiated this title object.
-
#ssvc_icon_id ⇒ Integer
The Jamf Pro ID for the self-service icon once it has been uploaded.
Class Method Summary collapse
-
.all_titles ⇒ Array<String>
A list of all known titles, just the basenames of all the title_dirs.
-
.in_ted?(title, cnx:) ⇒ Boolean
Does this title exist in the title editor.
-
.load(title) ⇒ Xolo::Server::Title
Instantiate from the local JSON file containing the current values for the given title.
-
.locked?(title) ⇒ Boolean
Is a title locked for updates?.
-
.ssvc_icon_file(title) ⇒ Pathname
The the local file containing the self-service icon.
-
.title_data_file(title) ⇒ Pathname
The the local JSON file containing the current values for the given title.
-
.title_dir(title) ⇒ Pathname
The title dir for a given title on the server, which may or may not exist.
-
.title_dirs ⇒ Array<Pathname>
A list of all known title dirs.
-
.uninstall_script_file(title) ⇒ Pathname
The the local file containing the code of the version script.
-
.version_script_file(title) ⇒ Pathname
The the local file containing the code of the version script.
Instance Method Summary collapse
-
#admin ⇒ String
This can be manually set earlier in the request handling to use a non-standard admin username.
-
#autopkg_enabled? ⇒ Boolean
Is AutoPkg integration enabled for the server and title? This overrides the method in core title, which just checks for the presence of the recipe and dir.
-
#create ⇒ void
Save a new title, adding to the local filesystem, Jamf Pro, and the Title Editor as needed.
-
#creating? ⇒ Boolean
Are we creating this title?.
-
#delete ⇒ void
Delete the title and all of its version.
-
#delete_version_script_file ⇒ void
Delete the version script file.
-
#deleting? ⇒ Boolean
Are we deleting this title?.
-
#deprecate_or_skip_version(vobj) ⇒ void
Deprecate or skip a version.
-
#generate_uninstall_script(script_or_pkg_ids) ⇒ String, Array
The uninstall script, provided or generated from the given pkg ids.
-
#initialize(data_hash) ⇒ Title
constructor
NOTE: be sure to only instantiate these using the servers 'instantiate_title' method, or else they might not have all the correct innards.
-
#jamf_cnx(refresh: false) ⇒ Jamf::Connection
A single Jamf Pro API connection to use for the life of this instance.
-
#jamf_patch_title_id ⇒ Object
TODO: Remove this when everything has been repaired for v2 and all json files know this value.
-
#lock ⇒ Object
Lock this title for updates.
-
#locked? ⇒ Boolean
Is this title locked for updates?.
-
#patch_report_rsrc ⇒ String
The URL path for the patch report for this title.
-
#prepend_version(version) ⇒ void
prepend a new version to the version_order.
-
#progress(msg, log: :debug, alert: false) ⇒ void
Append a message to the progress stream file, optionally sending it also to the log.
-
#release(version_to_release) ⇒ void
Release a version of this title.
-
#release_version(vobj, rollback:) ⇒ void
release a specific version.
-
#releasing? ⇒ Boolean
Are we releasing a version this title?.
-
#remove_version(version) ⇒ void
remove a version from the version_order.
-
#repair(repair_versions: false) ⇒ void
Repair this title, and optionally all of its versions.
-
#repairing? ⇒ Boolean
Are we repairing this title?.
-
#reset_version_to_pilot(vobj) ⇒ void
reset a version to pilot status, this happens when rolling back (releasing a version older than the current release).
-
#save_local_data ⇒ void
Save our current data out to our JSON data file This overwrites the existing data.
-
#save_ssvc_icon(tempfile, orig_filename) ⇒ void
Save the self_service_icon from the upload tmpfile to the file in the data dir.
-
#save_uninstall_script ⇒ void
Save our current uninstall script out to our local file.
-
#save_version_script ⇒ void
Save our current version script out to our local file, but only if we aren't using app_name and app_bundle_id and only if it's changed.
- #session ⇒ Hash
-
#ssvc_icon_file ⇒ Pathname
The the local file containing the self-service icon.
-
#ted_cnx ⇒ Windoo::Connection
A single Title Editor connection to use for the life of this instance.
-
#title_data_file ⇒ Pathname
The title data file for this title on the server.
-
#title_dir ⇒ Pathname
The title dir for this title on the server.
-
#to_h ⇒ Object
Add more server-specific data to our hash.
-
#uninstall_script_contents ⇒ String
The code of the uninstall_script , if any, considering the new data of any changes being made.
-
#uninstall_script_file ⇒ Pathname
The the local file containing the code of the uninstall script.
-
#uninstall_script_template ⇒ String
The template zsh script for uninstalling via pkgutil.
-
#uninstallable? ⇒ Boolean
are we uninstallable?.
-
#unlock ⇒ Object
Unlock this v for updates.
-
#update(new_data) ⇒ void
Update this title, updating to the local filesystem, Jamf Pro, and the Title Editor, and applying any changes to existing versions as needed.
-
#update_local_instance_values ⇒ void
Update our instance attributes with any new data before saving the changes back out to the file system.
-
#update_versions_for_release(version_to_release) ⇒ void
Update all versions when releasing one.
-
#updating? ⇒ Boolean
Are we updating this title?.
-
#validate_release(version_to_release) ⇒ void
are we OK releasing a given version?.
-
#version_object(version) ⇒ Xolo::Server::Version
instantiate a version if this title.
-
#version_objects(refresh: false) ⇒ Array<Xolo::Server::Version>
An array of all current version objects NOTE: This might not be wise if hundreds of versions, but automated cleanup should help with that.
-
#version_script_contents ⇒ String
The code of the version script, if any, considering the new data of any changes being made.
-
#version_script_file ⇒ Pathname
The the local file containing the code of the version script.
Methods included from Mixins::TitleTedAccess
#any_ted_changes?, #apply_requirement_changes, #create_and_enable_stub_patch_in_ted, #create_ted_ea, #create_ted_title_requirements, #create_title_in_ted, #delete_ted_ea, #delete_title_from_ted, #enable_ted_title, included, #reenable_all_ted_patches, #repair_ted_title, #requirement_change, #set_app_requirement, #set_ea_requirement, #set_ted_patch_component_criteria_after_update, #set_ted_title_requirement, #ted_ea_key, #ted_title, #ted_title_url, #update_ted_ea, #update_title_in_ted
Methods included from Mixins::TitleJamfAccess
#accept_jamf_patch_ea, #accept_jamf_patch_ea_via_api, #activate_jamf_patch_title, #add_title_to_self_service, #auto_accept_patch_ea_in_thread, #configure_jamf_expire_policy, #configure_jamf_installed_group, #configure_jamf_manual_install_released_policy, #configure_jamf_uninstall_policy, #configure_jamf_uninstall_script, #configure_pol_for_self_service, #create_jamf_manual_install_released_policy, #create_title_in_jamf, #delete_jamf_expire_policy, #delete_jamf_frozen_group, #delete_jamf_installed_group, #delete_jamf_manual_install_released_policy, #delete_jamf_patch_title, #delete_jamf_uninstall_policy, #delete_jamf_uninstall_script, #delete_title_from_jamf, #freeze_computers, #freeze_or_thaw_computers, #frozen_computers, included, #jamf_active_managed_titles, #jamf_active_subscribed_titles, #jamf_available_managed_titles, #jamf_expire_policy, #jamf_expire_policy_exist?, #jamf_expire_policy_url, #jamf_frozen_group, #jamf_frozen_group_exist?, #jamf_frozen_group_url, #jamf_gui_url, #jamf_installed_group, #jamf_installed_group_criteria, #jamf_installed_group_exist?, #jamf_installed_group_url, #jamf_managed_patch_source, #jamf_managed_title_available?, #jamf_manual_install_released_policy, #jamf_manual_install_released_policy_exist?, #jamf_manual_install_released_policy_url, #jamf_patch_ea_awaiting_acceptance?, #jamf_patch_ea_contents, #jamf_patch_ea_data, #jamf_patch_ea_matches_version_script?, #jamf_patch_ea_url, #jamf_patch_title, #jamf_patch_title_url, #jamf_title_active?, #jamf_uninstall_policy, #jamf_uninstall_policy_exist?, #jamf_uninstall_policy_url, #jamf_uninstall_script, #jamf_uninstall_script_exist?, #jamf_uninstall_script_url, #jp_api_filter_string_for_version, #need_to_accept_jamf_patch_ea?, #need_to_delete_jamf_uninstall_script?, #need_to_update_description?, #need_to_update_expiration?, #need_to_update_jamf_uninstall_script?, #patch_report, #patch_versions, #remove_title_from_self_service, #repair_frozen_group, #repair_jamf_expire_policy, #repair_jamf_manual_install_released_policy, #repair_jamf_title_objects, #repair_jamf_uninstall_policy, #repair_jamf_uninstall_script, #run_autopkg_recipe, #thaw_computers, #toggle_jamf_manual_install_released_policy, #update_description_in_jamf, #update_ssvc, #update_title_in_jamf, #update_versions_for_title_changes_in_jamf, #wait_for_managed_title_to_become_available
Methods included from Mixins::Changelog
#backup_changelog, backup_file_dir, #changelog, #changelog_backup_file, #changelog_file, #changelog_lock, changelog_locks, #delete_changelog, #hostname_from_ip, included, #log_change, #log_update_changes, #note_changes_for_update_and_log
Methods included from Helpers::Notification
#email_from, included, #send_alert, #send_email, #send_email_alert, #server_fqdn, #server_name
Methods included from Helpers::Log
included, #log_debug, #log_error, #log_fatal, #log_info, #log_unknown, #log_warn, #logger, #session_svr_obj_id
Methods included from Helpers::TitleEditor
Methods included from Helpers::JamfPro
extended, included, #jamf_gui_url, #jamf_obj_name_pfx_base, #jamf_xolo_category_id, #valid_forced_exclusion_group_name
Constructor Details
#initialize(data_hash) ⇒ Title
NOTE: be sure to only instantiate these using the servers 'instantiate_title' method, or else they might not have all the correct innards
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/xolo/server/title.rb', line 344 def initialize(data_hash) super # ted_id_number and jamf_patch_title_id are now defined in parent classes ATTRIBUTES so are set by super @version_order ||= [] @new_data_for_update = {} @changes_for_update = {} @jamf_obj_name_pfx = "#{jamf_obj_name_pfx_base}#{data_hash[:title]}" @jamf_installed_group_name = "#{jamf_obj_name_pfx}-#{JAMF_INSTALLED_GROUP_NAME_SUFFIX}" @jamf_frozen_group_name = "#{jamf_obj_name_pfx}-#{JAMF_FROZEN_GROUP_NAME_SUFFIX}" @jamf_manual_install_released_policy_name = "#{jamf_obj_name_pfx}-#{JAMF_MANUAL_INSTALL_RELEASED_POL_SUFFIX}" @jamf_uninstall_script_name = "#{jamf_obj_name_pfx}-#{JAMF_UNINSTALL_SUFFIX}" @jamf_uninstall_policy_name = "#{jamf_obj_name_pfx}-#{JAMF_UNINSTALL_SUFFIX}" @jamf_expire_policy_name = "#{jamf_obj_name_pfx}-#{JAMF_EXPIRE_SUFFIX}" # DO NOT USE jamf_cnx here, it comes from the server app instance, which is not set until after initialization. end |
Instance Attribute Details
#changes_for_update ⇒ Hash (readonly)
Also when applying updates, this will hold the changes being made: the differences between tne current attributes and the new_data_for_update We'll figure this out at the start of the update and can use it later to
- avoid doing things we don't need to
- log the changes in the change log at the very end
This is a Hash with keys of the attribute names that have changed the values are Hashes with keys of :old and :new e.g. { release_groups: { old: ['foo'], new: ['bar'] } }
313 314 315 |
# File 'lib/xolo/server/title.rb', line 313 def changes_for_update @changes_for_update end |
#current_action ⇒ Symbol
Returns The current action being taken on this title one of :creating, :updating, :deleting.
321 322 323 |
# File 'lib/xolo/server/title.rb', line 321 def current_action @current_action end |
#jamf_expire_policy_name ⇒ String (readonly)
If a title is expirable, it will have a policy in Jamf named 'xolo-
283 284 285 |
# File 'lib/xolo/server/title.rb', line 283 def jamf_expire_policy_name @jamf_expire_policy_name end |
#jamf_frozen_group_name ⇒ String (readonly)
For each title there will be a static group containing macs that should not get any automatic installs or updates, They should be 'frozen' at whatever version was installed when they were added to the group. It will be named 'xolo-
It will be used as an exclusion for the installation policies and the patch policy for each version.
Membership is maintained using xadm freeze <title> <computer> [<computer> ...]
and xadm thaw <title> <computer> [<computer> ...]
Use xadm report <title> frozen to see a list.
If computer groups are used with freeze/thaw, they are expanded and their members added/removed individually in the static group
Since there is one such group per title, it's name is stored here
258 259 260 |
# File 'lib/xolo/server/title.rb', line 258 def jamf_frozen_group_name @jamf_frozen_group_name end |
#jamf_installed_group_name ⇒ String (readonly)
For each title there will be a smart group containing all macs that have any version of the title installed. The smart group will be named 'xolo-
It will be used as an exclusion for the initial auto-installation policy for each version since if the title is installed at all, any installation is not 'initial' but an update, and will be handled by the Patch Policy.
Since there is one such group per title, it's name is stored here
237 238 239 |
# File 'lib/xolo/server/title.rb', line 237 def jamf_installed_group_name @jamf_installed_group_name end |
#jamf_manual_install_released_policy_name ⇒ Object (readonly)
The name of the policy that does initial manual or self-service installs of the currently-released version of this title. It will be named 'xolo-
263 264 265 |
# File 'lib/xolo/server/title.rb', line 263 def jamf_manual_install_released_policy_name @jamf_manual_install_released_policy_name end |
#jamf_obj_name_pfx ⇒ String (readonly)
Returns The prefix for all jamf objects for this title, which is 'xolo-
332 333 334 |
# File 'lib/xolo/server/title.rb', line 332 def jamf_obj_name_pfx @jamf_obj_name_pfx end |
#jamf_patch_source_id ⇒ String
Returns The jamf ID of the patch source for this title if the title is subscribed. Managed titles are all in the Title Editor source.
329 330 331 |
# File 'lib/xolo/server/title.rb', line 329 def jamf_patch_source_id @jamf_patch_source_id end |
#jamf_uninstall_policy_name ⇒ String (readonly)
If a title is uninstallable, it will have a policy in Jamf named 'xolo-
276 277 278 |
# File 'lib/xolo/server/title.rb', line 276 def jamf_uninstall_policy_name @jamf_uninstall_policy_name end |
#jamf_uninstall_script_name ⇒ String (readonly)
If a title is uninstallable, it will have a script in Jamf named 'xolo-
269 270 271 |
# File 'lib/xolo/server/title.rb', line 269 def jamf_uninstall_script_name @jamf_uninstall_script_name end |
#new_data_for_update ⇒ Hash (readonly)
when applying updates, the new data from xadm is stored here so it can be accessed by update-methods and compared to the current instance values both for updating the title, and the versions
298 299 300 |
# File 'lib/xolo/server/title.rb', line 298 def new_data_for_update @new_data_for_update end |
#releasing_version ⇒ String
Returns If current action is :releasing, this is the version being released.
325 326 327 |
# File 'lib/xolo/server/title.rb', line 325 def releasing_version @releasing_version end |
#server_app_instance ⇒ Xolo::Server::App
The instance of Xolo::Server::App that instantiated this title object. This is how we access things that are available in routes and helpers, like the single Jamf and TEd connections for this App instance.
290 291 292 |
# File 'lib/xolo/server/title.rb', line 290 def server_app_instance @server_app_instance end |
#ssvc_icon_id ⇒ Integer
Returns The Jamf Pro ID for the self-service icon once it has been uploaded.
317 318 319 |
# File 'lib/xolo/server/title.rb', line 317 def ssvc_icon_id @ssvc_icon_id end |
Class Method Details
.all_titles ⇒ Array<String>
Returns A list of all known titles, just the basenames of all the title_dirs.
136 137 138 |
# File 'lib/xolo/server/title.rb', line 136 def self.all_titles title_dirs.map(&:basename).map(&:to_s) end |
.in_ted?(title, cnx:) ⇒ Boolean
Does this title exist in the title editor. WARNING: Being in the title editor doesn't necessarily mean that this title is managed
210 211 212 |
# File 'lib/xolo/server/title.rb', line 210 def self.in_ted?(title, cnx:) Windoo::SoftwareTitle.all_ids(cnx: cnx).include? title end |
.load(title) ⇒ Xolo::Server::Title
Instantiate from the local JSON file containing the current values for the given title
NOTE: All instantiation should happen using the #instantiate_title method in the server app instance, or related methods like all_title_objects. Please don't call this method directly
197 198 199 200 |
# File 'lib/xolo/server/title.rb', line 197 def self.load(title) Xolo::Server.logger.debug "Loading title '#{title}' from file" new parse_json(title_data_file(title).read) end |
.locked?(title) ⇒ Boolean
Is a title locked for updates?
216 217 218 219 |
# File 'lib/xolo/server/title.rb', line 216 def self.locked?(title) curr_lock = Xolo::Server.object_locks.dig title, :expires curr_lock && curr_lock > Time.now end |
.ssvc_icon_file(title) ⇒ Pathname
Returns The the local file containing the self-service icon.
182 183 184 |
# File 'lib/xolo/server/title.rb', line 182 def self.ssvc_icon_file(title) title_dir(title).children.select { |c| c.basename.to_s.start_with? SELF_SERVICE_ICON_FILENAME }.first end |
.title_data_file(title) ⇒ Pathname
The the local JSON file containing the current values for the given title
158 159 160 |
# File 'lib/xolo/server/title.rb', line 158 def self.title_data_file(title) title_dir(title) + "#{title}.json" end |
.title_dir(title) ⇒ Pathname
The title dir for a given title on the server, which may or may not exist.
147 148 149 |
# File 'lib/xolo/server/title.rb', line 147 def self.title_dir(title) TITLES_DIR + title end |
.title_dirs ⇒ Array<Pathname>
Returns A list of all known title dirs.
129 130 131 |
# File 'lib/xolo/server/title.rb', line 129 def self.title_dirs TITLES_DIR.children end |
.uninstall_script_file(title) ⇒ Pathname
Returns The the local file containing the code of the version script.
174 175 176 |
# File 'lib/xolo/server/title.rb', line 174 def self.uninstall_script_file(title) title_dir(title) + UNINSTALL_SCRIPT_FILENAME end |
.version_script_file(title) ⇒ Pathname
Returns The the local file containing the code of the version script.
166 167 168 |
# File 'lib/xolo/server/title.rb', line 166 def self.version_script_file(title) title_dir(title) + VERSION_SCRIPT_FILENAME end |
Instance Method Details
#admin ⇒ String
This can be manually set earlier in the request handling to use a non-standard admin username
382 383 384 |
# File 'lib/xolo/server/title.rb', line 382 def admin @admin ||= session[:admin] end |
#autopkg_enabled? ⇒ Boolean
Is AutoPkg integration enabled for the server and title? This overrides the method in core title, which just checks for the presence of the recipe and dir.
848 849 850 851 852 853 854 |
# File 'lib/xolo/server/title.rb', line 848 def autopkg_enabled? return @autopkg_enabled if defined?(@autopkg_enabled) @autopkg_enabled = server_app_instance.autopkg_enabled? && \ autopkg_recipe && \ autopkg_dir end |
#create ⇒ void
This method returns an undefined value.
Save a new title, adding to the local filesystem, Jamf Pro, and the Title Editor as needed
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 |
# File 'lib/xolo/server/title.rb', line 645 def create lock @current_action = :creating self.creation_date = Time.now self.created_by = admin log_debug "creation_date: #{creation_date}, created_by: #{created_by}" log_debug "TitleData at #create: #{to_h}" # this will create the title as needed in the Title Editor log_debug "Display Name before creating in ted: #{display_name}" create_title_in_ted log_debug "Display Name before creating in jamf: #{display_name}" create_title_in_jamf # save to file last, because saving to TitleEd and Jamf will # add some data progress 'Saving title data to Xolo server' save_local_data if subscribed? # create version for latest available # - either autopkg or notification to upload. # See also Helpers::Subscriptions.process_patch_title_updated_webhook Xolo::Server::Version.add_version_via_subscription( title_object: self, new_version: patch_versions(version: :latest)[0][:version] ) end # if subscribed log_change msg: 'Title Created' # we don't need to update client data when titles are created # because they don't have any versions yet, so there's nothing a # client can do with them. It'll be updated when the version is created # ssvc icon is uploaded in a separate process, and the # title data file will be updated as needed then. ensure unlock end |
#creating? ⇒ Boolean
Returns Are we creating this title?.
388 389 390 |
# File 'lib/xolo/server/title.rb', line 388 def creating? current_action == :creating end |
#delete ⇒ void
This method returns an undefined value.
Delete the title and all of its version
915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 |
# File 'lib/xolo/server/title.rb', line 915 def delete lock @current_action = :deleting progress "Deleting all versions of #{title}...", log: :debug # Delete them in reverse order (oldest first) so the jamf server doesn't # see each older version as being 'released' again as newer # ones are deleted. version_objects.reverse.each do |vers| # vers might be nil if it was already deleted # e.g. a prev. attempt to delete the title failed partway through vers&.delete update_title: false, deleting_title: true end delete_title_from_ted unless subscribed? delete_title_from_jamf delete_changelog progress "Deleting Xolo server data for title '#{title}'", log: :info title_dir.rmtree server_app_instance.update_client_data ensure unlock end |
#delete_version_script_file ⇒ void
This method returns an undefined value.
Delete the version script file
904 905 906 907 908 909 910 |
# File 'lib/xolo/server/title.rb', line 904 def delete_version_script_file return unless version_script_file.file? log_debug "Deleting version script file: #{version_script_file}" version_script_file.delete end |
#deleting? ⇒ Boolean
Returns Are we deleting this title?.
406 407 408 |
# File 'lib/xolo/server/title.rb', line 406 def deleting? current_action == :deleting end |
#deprecate_or_skip_version(vobj) ⇒ void
This method returns an undefined value.
Deprecate or skip a version
1043 1044 1045 1046 1047 1048 1049 1050 1051 |
# File 'lib/xolo/server/title.rb', line 1043 def deprecate_or_skip_version(vobj) # don't do anything if the status is already deprecated or skipped # but if its released, we need to deprecate it vobj.deprecate if vobj.status == Xolo::Server::Version::STATUS_RELEASED # and skip it if its in pilot vobj.skip if vobj.status == Xolo::Server::Version::STATUS_PILOT end |
#generate_uninstall_script(script_or_pkg_ids) ⇒ String, Array
Returns The uninstall script, provided or generated from the given pkg ids.
564 565 566 567 568 569 |
# File 'lib/xolo/server/title.rb', line 564 def generate_uninstall_script(script_or_pkg_ids) # Its already a script, validated by xadm to start with #! return script_or_pkg_ids if script_or_pkg_ids.is_a? String uninstall_script_template.sub 'PKG_IDS_FROM_XOLO_GO_HERE', script_or_pkg_ids.join(' ') end |
#jamf_cnx(refresh: false) ⇒ Jamf::Connection
Returns a single Jamf Pro API connection to use for the life of this instance.
456 457 458 |
# File 'lib/xolo/server/title.rb', line 456 def jamf_cnx(refresh: false) server_app_instance.jamf_cnx refresh: refresh end |
#jamf_patch_title_id ⇒ Object
TODO: Remove this when everything has been repaired for v2 and all json files know this value
419 420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/xolo/server/title.rb', line 419 def jamf_patch_title_id return @jamf_patch_title_id if @jamf_patch_title_id log_debug "Getting jamf_patch_title_id for title '#{title}'" self.jamf_patch_title_id = if managed? jamf_active_managed_titles[title] else jamf_active_subscribed_titles[title] end end |
#lock ⇒ Object
Lock this title for updates
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 |
# File 'lib/xolo/server/title.rb', line 1131 def lock raise Xolo::ServerError, 'Server is shutting down' if Xolo::Server.shutting_down? while locked? log_debug "Waiting for update lock on title '#{title}'..." if (Time.now.to_i % 5).zero? sleep 0.33 end Xolo::Server.object_locks[title] ||= { versions: {} } exp = Time.now + Xolo::Server::ObjectLocks::OBJECT_LOCK_LIMIT Xolo::Server.object_locks[title][:expires] = exp log_debug "Locked title '#{title}' for updates until #{exp}, by method #{caller_locations.first.label}" end |
#locked? ⇒ Boolean
Is this title locked for updates?
1125 1126 1127 |
# File 'lib/xolo/server/title.rb', line 1125 def locked? self.class.locked?(title) end |
#patch_report_rsrc ⇒ String
Returns The URL path for the patch report for this title.
636 637 638 |
# File 'lib/xolo/server/title.rb', line 636 def patch_report_rsrc @patch_report_rsrc ||= "#{JPAPI_PATCH_TITLE_RSRC}/#{jamf_patch_title_id}/#{JPAPI_PATCH_REPORT_RSRC}" end |
#prepend_version(version) ⇒ void
This method returns an undefined value.
prepend a new version to the version_order
589 590 591 592 |
# File 'lib/xolo/server/title.rb', line 589 def prepend_version(version) version_order.unshift version save_local_data end |
#progress(msg, log: :debug, alert: false) ⇒ void
This method returns an undefined value.
Append a message to the progress stream file, optionally sending it also to the log
442 443 444 |
# File 'lib/xolo/server/title.rb', line 442 def progress(msg, log: :debug, alert: false) server_app_instance.progress msg, log: log, alert: alert end |
#release(version_to_release) ⇒ void
This method returns an undefined value.
Release a version of this title
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 |
# File 'lib/xolo/server/title.rb', line 948 def release(version_to_release) lock @current_action = :releasing @releasing_version = version_to_release validate_release(version_to_release) progress "Releasing version #{version_to_release} of title '#{title}'", log: :info update_versions_for_release version_to_release # update the title self.released_version = version_to_release save_local_data server_app_instance.update_client_data ensure unlock end |
#release_version(vobj, rollback:) ⇒ void
This method returns an undefined value.
release a specific version
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 |
# File 'lib/xolo/server/title.rb', line 1020 def release_version(vobj, rollback:) vobj.release rollback: rollback # update the jamf_manual_install_released_policy to install this version msg = "Jamf: Setting policy #{jamf_manual_install_released_policy_name} to install the package for version '#{vobj.version}'" progress msg, log: :info pol = jamf_manual_install_released_policy toggle_jamf_manual_install_released_policy pol, vobj if self_service? add_title_to_self_service(pol) else remove_title_from_self_service(pol) end pol.save end |
#releasing? ⇒ Boolean
Returns Are we releasing a version this title?.
412 413 414 |
# File 'lib/xolo/server/title.rb', line 412 def releasing? current_action == :releasing end |
#remove_version(version) ⇒ void
This method returns an undefined value.
remove a version from the version_order
600 601 602 603 604 605 606 |
# File 'lib/xolo/server/title.rb', line 600 def remove_version(version) lock version_order.delete version save_local_data ensure unlock end |
#repair(repair_versions: false) ⇒ void
This method returns an undefined value.
Repair this title, and optionally all of its versions.
Look at the Title Editor title object, and ensure it's correct based on the local data file.
- display name
- publisher
- EA or app-data
- ea name 'xolo-
'
- ea name 'xolo-
- requirement criteria
- stub version if needed
- enabled
Then look at the various Jamf objects pertaining to this title, and ensure they are correct
- Accept Patch EA
- title-installed smart group 'xolo-
-installed' - frozen static group 'xolo-
-frozen' - manual/SSvc install-current-release policy 'xolo-
-install' - trigger 'xolo-
-install' - ssvc icon
- ssvc category
- description
- trigger 'xolo-
- if uninstallable
- uninstall script 'xolo-
-uninstall' - uninstall policy 'xolo-
-uninstall' - if expirable
- expire policy 'xolo-
-expire' - trigger 'xolo-
-expire'
- trigger 'xolo-
- expire policy 'xolo-
- uninstall script 'xolo-
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 |
# File 'lib/xolo/server/title.rb', line 1101 def repair(repair_versions: false) lock @current_action = :repairing chg_log_msg = repair_versions ? 'Repairing title and all versions' : 'Repairing title only' log_change msg: chg_log_msg progress "Starting repair of title '#{title}'" repair_ted_title repair_jamf_title_objects save_local_data return unless repair_versions version_objects.each do |vobj| progress '#########' vobj.repair end server_app_instance.update_client_data ensure unlock end |
#repairing? ⇒ Boolean
Returns Are we repairing this title?.
400 401 402 |
# File 'lib/xolo/server/title.rb', line 400 def repairing? current_action == :repairing end |
#reset_version_to_pilot(vobj) ⇒ void
This method returns an undefined value.
reset a version to pilot status, this happens when rolling back (releasing a version older than the current release)
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 |
# File 'lib/xolo/server/title.rb', line 1058 def reset_version_to_pilot(vobj) # do nothing if its in pilot return if vobj.status == Xolo::Server::Version::STATUS_PILOT # this should be redundant with the above? return unless rollback # if we're here, we're rolling back to something older than this # version, and this version is currently released, deprecated or skipped. # We need to reset it to pilot. vobj.reset_to_pilot end |
#save_local_data ⇒ void
This method returns an undefined value.
Save our current data out to our JSON data file This overwrites the existing data.
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 |
# File 'lib/xolo/server/title.rb', line 779 def save_local_data # If we don't have a patch source id yet, get it now self.jamf_patch_source_id ||= Jamf::PatchSource.valid_id(patch_source, cnx: jamf_cnx) if patch_source # create the dirs for the title title_dir.mkpath vdir = title_dir + Xolo::Server::Version::VERSIONS_DIRNAME vdir.mkpath save_version_script save_uninstall_script self.modification_date = Time.now self.modified_by = admin log_debug "Title '#{title}' noting modification by #{modified_by}" # do we have a stored self service icon? self.self_service_icon = ssvc_icon_file ? Xolo::ITEM_UPLOADED : nil log_debug "Saving local title data to: #{title_data_file}" title_data_file.pix_atomic_write to_json end |
#save_ssvc_icon(tempfile, orig_filename) ⇒ void
This method returns an undefined value.
Save the self_service_icon from the upload tmpfile to the file in the data dir.
This is run by the upload route, not the create or update methods here. xadm does the upload after creating or updating the title
875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 |
# File 'lib/xolo/server/title.rb', line 875 def save_ssvc_icon(tempfile, orig_filename) lock # here's where we'll store it on the server ext_for_file = orig_filename.split(Xolo::DOT).last new_basename = "#{SELF_SERVICE_ICON_FILENAME}.#{ext_for_file}" new_icon_file = title_dir + new_basename # delete any previous icon files existing_icon_file = ssvc_icon_file if existing_icon_file&.file? log_debug "Deleting older icon file: #{existing_icon_file.basename}" existing_icon_file.delete end log_debug "Saving self_service_icon '#{orig_filename}' to: #{new_basename}" tempfile.rename new_icon_file # the json file only stores 'uploaded' in the self_service_icon # attr. self.self_service_icon = Xolo::ITEM_UPLOADED save_local_data ensure unlock end |
#save_uninstall_script ⇒ void
This method returns an undefined value.
Save our current uninstall script out to our local file.
This won't delete the script if it's being removed, that happens elsewhere.
This overwrites the existing data.
833 834 835 836 837 838 839 840 841 842 843 |
# File 'lib/xolo/server/title.rb', line 833 def save_uninstall_script return if uninstall_script == Xolo::ITEM_UPLOADED || uninstall_ids == Xolo::ITEM_UPLOADED return if uninstall_script_contents.nil? log_debug "Saving uninstall script to: #{uninstall_script_file}" uninstall_script_file.pix_atomic_write uninstall_script_contents # the json file only stores 'uploaded' in uninstall_script # The actual script is saved in its own file. self.uninstall_script &&= Xolo::ITEM_UPLOADED end |
#save_version_script ⇒ void
This method returns an undefined value.
Save our current version script out to our local file, but only if we aren't using app_name and app_bundle_id and only if it's changed
This won't delete the script if it's being removed, that happens elsewhere.
This overwrites the existing data.
813 814 815 816 817 818 819 820 821 822 |
# File 'lib/xolo/server/title.rb', line 813 def save_version_script return if app_name || app_bundle_id return if version_script_contents.nil? log_debug "Saving version_script to: #{version_script_file}" version_script_file.pix_atomic_write version_script_contents # the json file only stores 'uploaded' in the version_script attr. self.version_script = Xolo::ITEM_UPLOADED end |
#session ⇒ Hash
373 374 375 376 |
# File 'lib/xolo/server/title.rb', line 373 def session server_app_instance&.session || {} # @session ||= {} end |
#ssvc_icon_file ⇒ Pathname
Returns The the local file containing the self-service icon.
476 477 478 |
# File 'lib/xolo/server/title.rb', line 476 def ssvc_icon_file @ssvc_icon_file ||= self.class.ssvc_icon_file title end |
#ted_cnx ⇒ Windoo::Connection
Returns a single Title Editor connection to use for the life of this instance.
449 450 451 |
# File 'lib/xolo/server/title.rb', line 449 def ted_cnx server_app_instance.ted_cnx end |
#title_data_file ⇒ Pathname
The title data file for this title on the server
470 471 472 |
# File 'lib/xolo/server/title.rb', line 470 def title_data_file @title_data_file ||= self.class.title_data_file title end |
#title_dir ⇒ Pathname
The title dir for this title on the server
463 464 465 |
# File 'lib/xolo/server/title.rb', line 463 def title_dir @title_dir ||= self.class.title_dir title end |
#to_h ⇒ Object
Add more server-specific data to our hash
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 |
# File 'lib/xolo/server/title.rb', line 1157 def to_h hash = super # TODO: remove these after 'repairing' everything for v2 hash[:ted_id_number] = ted_id_number hash[:jamf_patch_title_id] = jamf_patch_title_id hash[:ssvc_icon_id] = ssvc_icon_id hash end |
#uninstall_script_contents ⇒ String
The code of the uninstall_script , if any, considering the new data of any changes being made
Returns nil if there is no uninstall_script, or if we are in the process of deleting it.
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/xolo/server/title.rb', line 533 def uninstall_script_contents return @uninstall_script_contents if defined? @uninstall_script_contents # use any new/incoming value if we have any # this might still be nil or an empty array if we are removing uninstallability curr_script = changes_for_update.dig(:uninstall_script, :new) || changes_for_update.dig(:uninstall_ids, :new) curr_script = nil if curr_script.pix_empty? # otherwise use the existing value curr_script ||= uninstall_script || uninstall_ids # now get the actual script @uninstall_script_contents = if curr_script.pix_empty? # removing uninstallability, or it was never added nil elsif curr_script == Xolo::ITEM_UPLOADED # nothing changed, use the one we have saved on disk uninstall_script_file.read else # this will be a new one from the changes_for_update generate_uninstall_script curr_script end # log_debug "Uninstall script contents: #{@uninstall_script_contents}" @uninstall_script_contents end |
#uninstall_script_file ⇒ Pathname
Returns The the local file containing the code of the uninstall script.
521 522 523 |
# File 'lib/xolo/server/title.rb', line 521 def uninstall_script_file @uninstall_script_file ||= self.class.uninstall_script_file title end |
#uninstall_script_template ⇒ String
Returns The template zsh script for uninstalling via pkgutil.
573 574 575 576 577 578 579 580 581 |
# File 'lib/xolo/server/title.rb', line 573 def uninstall_script_template # parent 1 = server # parent 2 = xolo # parent 3 = lib # parent 4 = xolo gem data_dir = Pathname.new(__FILE__).parent.parent.parent.parent + 'data' template_file = data_dir + 'uninstall-pkgs-by-id.zsh' template_file.read end |
#uninstallable? ⇒ Boolean
are we uninstallable?
860 861 862 |
# File 'lib/xolo/server/title.rb', line 860 def uninstallable? uninstall_script || !uninstall_ids.pix_empty? end |
#unlock ⇒ Object
Unlock this v for updates
1147 1148 1149 1150 1151 1152 1153 |
# File 'lib/xolo/server/title.rb', line 1147 def unlock curr_lock = Xolo::Server.object_locks.dig title, :expires return unless curr_lock Xolo::Server.object_locks[title].delete :expires log_debug "Unlocked title '#{title}' for updates" end |
#update(new_data) ⇒ void
This method returns an undefined value.
Update this title, updating to the local filesystem, Jamf Pro, and the Title Editor, and applying any changes to existing versions as needed.
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 |
# File 'lib/xolo/server/title.rb', line 697 def update(new_data) lock @current_action = :updating @new_data_for_update = new_data @changes_for_update = note_changes_for_update_and_log if @changes_for_update.pix_empty? progress 'No changes to make', log: :info return end log_info "Updating title '#{title}' for admin '#{admin}'" log_debug "Updating title with these changes: #{changes_for_update}" # changelog - log the changes now, and # if there is an error, we'll log that too # saying the above changes were not completed and to # look at the server log for details. log_update_changes # Do ted before doing things in Jamf update_title_in_ted update_title_in_jamf update_local_instance_values save_local_data # if we already have a version script, and it hasn't changed, the new data should # contain Xolo::ITEM_UPLOADED. If its nil, we shouldn't # have one at all and should remove the old one if its there delete_version_script_file unless new_data_for_update[:version_script] # Do This at the end - after all the versions/patches have been updated. # Jamf won't see the need for re-acceptance until after the title # (and at least one patch) have been re-enabled. accept_jamf_patch_ea if need_to_accept_jamf_patch_ea? # any new self svc icon will be uploaded in a separate process # and the local data will be updated again then server_app_instance.update_client_data rescue => e log_change msg: "ERROR: The update failed and the changes didn't all go through!\n#{e.class}: #{e.}\nSee server log for details." # re-raise for proper error handling in the server app raise ensure unlock end |
#update_local_instance_values ⇒ void
This method returns an undefined value.
Update our instance attributes with any new data before saving the changes back out to the file system
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
# File 'lib/xolo/server/title.rb', line 751 def update_local_instance_values # update instance data with new data before writing out to the filesystem. # Do this last so that the instance values can be compared to # new_data_for_update in the steps above. # Also, those steps might have updated some server-specific attributes # which will be saved to the file system as well. ATTRIBUTES.each do |attr, deets| # make sure these are updated elsewhere if needed, # e.g. modification data. next if deets[:read_only] next unless deets[:cli] new_val = new_data_for_update[attr] old_val = send(attr) next if new_val == old_val log_debug "Updating Xolo Title attribute '#{attr}': '#{old_val}' -> '#{new_val}'" send "#{attr}=", new_val end # update any other server-specific attributes here... end |
#update_versions_for_release(version_to_release) ⇒ void
This method returns an undefined value.
Update all versions when releasing one
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 |
# File 'lib/xolo/server/title.rb', line 986 def update_versions_for_release(version_to_release) # get the Version objects and figure out our starting point, but process # them in reverse order so that we don't have two released versions at once all_versions = version_objects.reverse vobj_to_release = all_versions.find { |v| v.version == version_to_release } vobj_current_release = all_versions.find { |v| v.version == released_version } rollback = vobj_current_release && vobj_to_release < vobj_current_release progress "Rolling back from version #{released_version}", log: :info if rollback all_versions.each do |vobj| # This is the one we are releasing if vobj == vobj_to_release release_version(vobj, rollback: rollback) # This one is older than the one we're releasing # so its either deprecated or skipped elsif vobj < vobj_to_release deprecate_or_skip_version(vobj) # this one is newer than the one we're releasing # revert to pilot if appropriate else reset_version_to_pilot(vobj) end # if vobj == vobj_to_release end # all_versions.each end |
#updating? ⇒ Boolean
Returns Are we updating this title?.
394 395 396 |
# File 'lib/xolo/server/title.rb', line 394 def updating? current_action == :updating end |
#validate_release(version_to_release) ⇒ void
This method returns an undefined value.
are we OK releasing a given version?
970 971 972 973 974 975 976 977 978 979 980 |
# File 'lib/xolo/server/title.rb', line 970 def validate_release(version_to_release) if released_version == version_to_release raise Xolo::InvalidDataError, "Version '#{version_to_release}' of title '#{title}' is already released" end return if versions.include? version_to_release raise Xolo::NoSuchItemError, "No version '#{version_to_release}' for title '#{title}'" end |
#version_object(version) ⇒ Xolo::Server::Version
instantiate a version if this title
612 613 614 615 |
# File 'lib/xolo/server/title.rb', line 612 def version_object(version) log_debug "Instantiating version #{version} from Title instance #{title}" server_app_instance.instantiate_version(title: self, version: version) end |
#version_objects(refresh: false) ⇒ Array<Xolo::Server::Version>
Returns An array of all current version objects NOTE: This might not be wise if hundreds of versions, but automated cleanup should help with that.
621 622 623 624 625 626 627 628 629 630 631 632 |
# File 'lib/xolo/server/title.rb', line 621 def version_objects(refresh: false) @version_objects = nil if refresh return @version_objects if @version_objects @version_objects = version_order.map do |v| version_object v rescue Xolo::Core::Exceptions::NoSuchItemError next if deleting? raise end end |
#version_script_contents ⇒ String
The code of the version script, if any, considering the new data of any changes being made
Returns nil if there is no version script, or if we are in the process of deleting it.
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
# File 'lib/xolo/server/title.rb', line 494 def version_script_contents return @version_script_contents if defined? @version_script_contents curr_script = if changes_for_update&.key? :version_script # new, incoming script changes_for_update[:version_script][:new] else # the current attribute value, might be Xolo::ITEM_UPLOADED version_script end @version_script_contents = if curr_script.pix_empty? # no script, or deleting script nil elsif curr_script == Xolo::ITEM_UPLOADED # use the one we have saved on disk version_script_file.read else # this will be a new one from the changes_for_update curr_script end end |
#version_script_file ⇒ Pathname
Returns The the local file containing the code of the version script.
482 483 484 |
# File 'lib/xolo/server/title.rb', line 482 def version_script_file @version_script_file ||= self.class.version_script_file title end |