"Fossies" - the Fresh Open Source Software Archive

Member "ec2-api-12.0.0/ec2api/service.py" (14 Apr 2021, 5701 Bytes) of package /linux/misc/openstack/ec2-api-12.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "service.py" see the Fossies "Dox" file reference documentation.

    1 # Copyright 2014
    2 # The Cloudscaling Group, Inc.
    3 #
    4 # Licensed under the Apache License, Version 2.0 (the "License");
    5 # you may not use this file except in compliance with the License.
    6 # You may obtain a copy of the License at
    7 # http://www.apache.org/licenses/LICENSE-2.0
    8 #
    9 # Unless required by applicable law or agreed to in writing, software
   10 # distributed under the License is distributed on an "AS IS" BASIS,
   11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12 # See the License for the specific language governing permissions and
   13 # limitations under the License.
   14 
   15 """Generic Node base class for all workers that run on hosts."""
   16 
   17 from oslo_concurrency import processutils
   18 from oslo_config import cfg
   19 from oslo_log import log as logging
   20 from oslo_service import service
   21 from oslo_utils import importutils
   22 
   23 from ec2api import exception
   24 from ec2api.i18n import _
   25 from ec2api import wsgi
   26 
   27 LOG = logging.getLogger(__name__)
   28 
   29 service_opts = [
   30     cfg.StrOpt('ec2api_listen',
   31                default="0.0.0.0",
   32                help='The IP address on which the EC2 API will listen.'),
   33     cfg.IntOpt('ec2api_listen_port',
   34                default=8788,
   35                help='The port on which the EC2 API will listen.'),
   36     cfg.BoolOpt('ec2api_use_ssl',
   37                 default=False,
   38                 help='Enable ssl connections or not for EC2 API'),
   39     cfg.IntOpt('ec2api_workers',
   40                help='Number of workers for EC2 API service. The default will '
   41                     'be equal to the number of CPUs available.'),
   42     cfg.StrOpt('metadata_listen',
   43                default="0.0.0.0",
   44                help='The IP address on which the metadata API will listen.'),
   45     cfg.IntOpt('metadata_listen_port',
   46                default=8789,
   47                help='The port on which the metadata API will listen.'),
   48     cfg.BoolOpt('metadata_use_ssl',
   49                 default=False,
   50                 help='Enable ssl connections or not for EC2 API Metadata'),
   51     cfg.IntOpt('metadata_workers',
   52                help='Number of workers for metadata service. The default will '
   53                     'be the number of CPUs available.'),
   54 ]
   55 
   56 CONF = cfg.CONF
   57 CONF.register_opts(service_opts)
   58 
   59 
   60 class WSGIService(service.ServiceBase):
   61     """Provides ability to launch API from a 'paste' configuration."""
   62 
   63     def __init__(self, name, loader=None, max_url_len=None):
   64         """Initialize, but do not start the WSGI server.
   65 
   66         :param name: The name of the WSGI server given to the loader.
   67         :param loader: Loads the WSGI application using the given name.
   68         :returns: None
   69 
   70         """
   71         self.name = name
   72         self.manager = self._get_manager()
   73         self.loader = loader or wsgi.Loader()
   74         self.app = self.loader.load_app(name)
   75         self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0")
   76         self.port = getattr(CONF, '%s_listen_port' % name, 0)
   77         self.use_ssl = getattr(CONF, '%s_use_ssl' % name, False)
   78         self.workers = (getattr(CONF, '%s_workers' % name, None) or
   79                         processutils.get_worker_count())
   80         if self.workers and self.workers < 1:
   81             worker_name = '%s_workers' % name
   82             msg = (_("%(worker_name)s value of %(workers)s is invalid, "
   83                      "must be greater than 0") %
   84                    {'worker_name': worker_name,
   85                     'workers': str(self.workers)})
   86             raise exception.InvalidInput(msg)
   87         self.server = wsgi.Server(name,
   88                                   self.app,
   89                                   host=self.host,
   90                                   port=self.port,
   91                                   use_ssl=self.use_ssl,
   92                                   max_url_len=max_url_len)
   93         # Pull back actual port used
   94         self.port = self.server.port
   95 
   96     def reset(self):
   97         """Reset server greenpool size to default.
   98 
   99         :returns: None
  100 
  101         """
  102         self.server.reset()
  103 
  104     def _get_manager(self):
  105         """Initialize a Manager object appropriate for this service.
  106 
  107         Use the service name to look up a Manager subclass from the
  108         configuration and initialize an instance. If no class name
  109         is configured, just return None.
  110 
  111         :returns: a Manager instance, or None.
  112 
  113         """
  114         fl = '%s_manager' % self.name
  115         if fl not in CONF:
  116             return None
  117 
  118         manager_class_name = CONF.get(fl, None)
  119         if not manager_class_name:
  120             return None
  121 
  122         manager_class = importutils.import_class(manager_class_name)
  123         return manager_class()
  124 
  125     def start(self):
  126         """Start serving this service using loaded configuration.
  127 
  128         Also, retrieve updated port number in case '0' was passed in, which
  129         indicates a random port should be used.
  130 
  131         :returns: None
  132 
  133         """
  134         if self.manager:
  135             self.manager.init_host()
  136             self.manager.pre_start_hook()
  137         self.server.start()
  138         if self.manager:
  139             self.manager.post_start_hook()
  140 
  141     def stop(self):
  142         """Stop serving this API.
  143 
  144         :returns: None
  145 
  146         """
  147         self.server.stop()
  148 
  149     def wait(self):
  150         """Wait for the service to stop serving this API.
  151 
  152         :returns: None
  153 
  154         """
  155         self.server.wait()
  156 
  157 
  158 # NOTE(vish): the global launcher is to maintain the existing
  159 #             functionality of calling service.serve +
  160 #             service.wait
  161 _launcher = None
  162 
  163 
  164 def serve(server, workers=None):
  165     global _launcher
  166     if _launcher:
  167         raise RuntimeError(_('serve() can only be called once'))
  168 
  169     _launcher = service.launch(CONF, server, workers=workers)
  170 
  171 
  172 def wait():
  173     _launcher.wait()