0
  
   7358ο f    7<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<p>Additionally, a 403 Forbidden
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>
  9   9li~e8EpOe1hhai~e8EpOe1h      9auto
  #   ;lY>d
n-jvOe1hM8 8}    ;#
# Copyright (c) 2018 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. 
#

"""
  Configuration - VDO manager configuration file handling

  $Id: //eng/vdo-releases/magnesium/src/python/vdo/vdomgmnt/Configuration.py#7 $

"""
from . import ArgumentError, MgmntLogger
from . import StateExitStatus
from . import VDOService
from utils import Command, runCommand
from utils import FileLock, YAMLObject

import errno
import os
from stat import ST_MTIME
import time
import yaml


class BadConfigurationFileError(StateExitStatus, Exception):
  """Exception raised to indicate an error in processing the
  configuration file, such as a parse error or missing data.
  """

  ######################################################################
  # Overridden methods
  ######################################################################
  def __init__(self, msg, *args, **kwargs):
    super(BadConfigurationFileError, self).__init__(*args, **kwargs)
    self._msg = msg

  ######################################################################
  def __str__(self):
    return self._msg

########################################################################
class Configuration(YAMLObject):
  """Configuration of VDO volumes and associated Albireo servers.

  This class is designed for use with the "with" statement. If
  Command.noRunMode is True, the file will still be opened and read
  but writes will not be performed.

  The Configuration is stored in a simple XML format; see
  vdoconfig.dtd.

  Attributes:
    _vdos: A dictionary of VDOServices, indexed by name.
    _filename: The name of the configuration file.
    _readonly: True iff this Configuration is read-only.
    _dirty: True iff this Configuration has been modified but the
      changes have not been persisted.
    _mustExist: If True, the file must exist (otherwise a missing
      file is treated as an empty configuration).
  """
  log = MgmntLogger.getLogger(MgmntLogger.myname + '.Configuration')
  supportedSchemaVersions = [0x20170907]
  modifiableSingltons = {}
  singletonLock = '/var/lock/vdo-config-singletons'
  yaml_tag = u"!Configuration"

  ######################################################################
  # Public methods
  ######################################################################
  @classmethod
  def modifiableSingleton(cls, filepath):
    """Allocates, as necessary, and returns a modifiable, singleton
    Configuration instance for the specified filepath.  Separate entities can
    thus share one in memory copy of the configuration file allowing for
    encapsulation of per-entity manipulation of the configuration.

    Args:
      filepath (str):   path to config file
    """
    config = None
    with FileLock(cls.singletonLock, "r+") as f:
      config = cls.modifiableSingltons.get(filepath)
      if config is None:
        config = Configuration(filepath, readonly = Fals