superhosting 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
 - data/.gitignore +10 -0
 - data/.rspec +2 -0
 - data/.travis.yml +11 -0
 - data/Gemfile +5 -0
 - data/Gemfile.lock +117 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +23 -0
 - data/Rakefile +6 -0
 - data/Vagrantfile +10 -0
 - data/bin/sx +10 -0
 - data/bootstrap.sh +31 -0
 - data/lib/superhosting.rb +40 -0
 - data/lib/superhosting/base.rb +37 -0
 - data/lib/superhosting/cli/base.rb +227 -0
 - data/lib/superhosting/cli/cmd/admin_add.rb +11 -0
 - data/lib/superhosting/cli/cmd/admin_container_add.rb +16 -0
 - data/lib/superhosting/cli/cmd/admin_container_delete.rb +16 -0
 - data/lib/superhosting/cli/cmd/admin_container_list.rb +12 -0
 - data/lib/superhosting/cli/cmd/admin_delete.rb +11 -0
 - data/lib/superhosting/cli/cmd/admin_passwd.rb +16 -0
 - data/lib/superhosting/cli/cmd/container_add.rb +21 -0
 - data/lib/superhosting/cli/cmd/container_admin_add.rb +16 -0
 - data/lib/superhosting/cli/cmd/container_admin_delete.rb +16 -0
 - data/lib/superhosting/cli/cmd/container_admin_list.rb +12 -0
 - data/lib/superhosting/cli/cmd/container_change.rb +21 -0
 - data/lib/superhosting/cli/cmd/container_delete.rb +11 -0
 - data/lib/superhosting/cli/cmd/container_list.rb +9 -0
 - data/lib/superhosting/cli/cmd/container_reconfig.rb +11 -0
 - data/lib/superhosting/cli/cmd/container_restore.rb +24 -0
 - data/lib/superhosting/cli/cmd/container_save.rb +14 -0
 - data/lib/superhosting/cli/cmd/container_update.rb +11 -0
 - data/lib/superhosting/cli/cmd/mysql_db_add.rb +9 -0
 - data/lib/superhosting/cli/cmd/mysql_db_delete.rb +9 -0
 - data/lib/superhosting/cli/cmd/mysql_db_dump.rb +9 -0
 - data/lib/superhosting/cli/cmd/mysql_db_sql.rb +9 -0
 - data/lib/superhosting/cli/cmd/mysql_grant.rb +9 -0
 - data/lib/superhosting/cli/cmd/mysql_user_add.rb +12 -0
 - data/lib/superhosting/cli/cmd/mysql_user_delete.rb +9 -0
 - data/lib/superhosting/cli/cmd/site_add.rb +16 -0
 - data/lib/superhosting/cli/cmd/site_alias_add.rb +16 -0
 - data/lib/superhosting/cli/cmd/site_alias_delete.rb +16 -0
 - data/lib/superhosting/cli/cmd/site_delete.rb +11 -0
 - data/lib/superhosting/cli/cmd/site_rename.rb +16 -0
 - data/lib/superhosting/cli/cmd/user_add.rb +24 -0
 - data/lib/superhosting/cli/cmd/user_change.rb +24 -0
 - data/lib/superhosting/cli/cmd/user_delete.rb +16 -0
 - data/lib/superhosting/cli/cmd/user_list.rb +9 -0
 - data/lib/superhosting/cli/cmd/user_passwd.rb +16 -0
 - data/lib/superhosting/cli/error/ambiguous_command.rb +11 -0
 - data/lib/superhosting/cli/error/base.rb +8 -0
 - data/lib/superhosting/cli/error/controller.rb +8 -0
 - data/lib/superhosting/controller/admin.rb +21 -0
 - data/lib/superhosting/controller/admin/container.rb +24 -0
 - data/lib/superhosting/controller/container.rb +174 -0
 - data/lib/superhosting/controller/container/admin.rb +24 -0
 - data/lib/superhosting/controller/mysql.rb +17 -0
 - data/lib/superhosting/controller/mysql/db.rb +23 -0
 - data/lib/superhosting/controller/mysql/user.rb +15 -0
 - data/lib/superhosting/controller/site.rb +106 -0
 - data/lib/superhosting/controller/site/alias.rb +21 -0
 - data/lib/superhosting/controller/user.rb +25 -0
 - data/lib/superhosting/docker_api.rb +31 -0
 - data/lib/superhosting/helpers.rb +30 -0
 - data/lib/superhosting/script_executor/base.rb +26 -0
 - data/lib/superhosting/script_executor/container.rb +36 -0
 - data/lib/superhosting/script_executor/site.rb +13 -0
 - data/lib/superhosting/version.rb +3 -0
 - data/superhosting.gemspec +32 -0
 - metadata +341 -0
 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Superhosting
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Cli
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Cmd
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class UserAdd < Base
         
     | 
| 
      
 5 
     | 
    
         
            +
                    option :no_ssh,
         
     | 
| 
      
 6 
     | 
    
         
            +
                           :long  => '--no-ssh',
         
     | 
| 
      
 7 
     | 
    
         
            +
                           :boolean => true
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    option :no_ftp,
         
     | 
| 
      
 10 
     | 
    
         
            +
                           :long  => '--no-ftp',
         
     | 
| 
      
 11 
     | 
    
         
            +
                           :boolean => true
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    option :container_name,
         
     | 
| 
      
 14 
     | 
    
         
            +
                           :short => '-c NAME',
         
     | 
| 
      
 15 
     | 
    
         
            +
                           :long  => '--container NAME',
         
     | 
| 
      
 16 
     | 
    
         
            +
            							 :required => true
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    def self.has_required_param?
         
     | 
| 
      
 19 
     | 
    
         
            +
                      true
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Superhosting
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Cli
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Cmd
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class UserChange < Base
         
     | 
| 
      
 5 
     | 
    
         
            +
                    option :no_ssh,
         
     | 
| 
      
 6 
     | 
    
         
            +
                           :long  => '--no-ssh',
         
     | 
| 
      
 7 
     | 
    
         
            +
                           :boolean => true
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    option :no_ftp,
         
     | 
| 
      
 10 
     | 
    
         
            +
                           :long  => '--no-ftp',
         
     | 
| 
      
 11 
     | 
    
         
            +
                           :boolean => true
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    option :container_name,
         
     | 
| 
      
 14 
     | 
    
         
            +
                           :short => '-c NAME',
         
     | 
| 
      
 15 
     | 
    
         
            +
                           :long  => '--container NAME',
         
     | 
| 
      
 16 
     | 
    
         
            +
            							 :required => true
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    def self.has_required_param?
         
     | 
| 
      
 19 
     | 
    
         
            +
                      true
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Superhosting
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Controller
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Admin < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def add(name:)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def delete(name:)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def passwd(name:, generate: nil)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def container(name:, logger: @logger)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    Container.new(name: name, logger: logger)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Superhosting
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Controller
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Admin
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class Container < Base
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def initialize(name:, **kvargs)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      @admin_name = name
         
     | 
| 
      
 7 
     | 
    
         
            +
                      super(kvargs)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def list
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    def add(name:)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    def delete(name:)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,174 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Superhosting
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Controller
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Container < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  CONTAINER_NAME_FORMAT = /[a-zA-Z0-9][a-zA-Z0-9_.-]+/
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  def list
         
     | 
| 
      
 7 
     | 
    
         
            +
                    docker = @docker_api.container_list.map {|c| c['Names'].first.slice(1..-1) }.to_set
         
     | 
| 
      
 8 
     | 
    
         
            +
                    sx = @config.containers._grep_dirs.map {|n| n._name }.to_set
         
     | 
| 
      
 9 
     | 
    
         
            +
                    containers = (docker & sx)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    { data: containers.to_a }
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def add(name:, mail: 'model', admin_mail: nil, model: nil)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    return { error: :input_error, message: "Invalid container name '#{name}' - only '#{CONTAINER_NAME_FORMAT}' are allowed" } if name !~ CONTAINER_NAME_FORMAT
         
     | 
| 
      
 16 
     | 
    
         
            +
                    return { error: :logical_error, message: 'Container already running.' } if @docker_api.container_info(name)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    return { error: :input_error, message: 'No model given.' } unless (model_ = model || @config.default_model(default: nil))
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    # config
         
     | 
| 
      
 20 
     | 
    
         
            +
                    config_path_ = "#{@config_path}/containers/#{name}"
         
     | 
| 
      
 21 
     | 
    
         
            +
                    config_path_mapper = PathMapper.new(config_path_)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    FileUtils.mkdir_p config_path_
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    # model
         
     | 
| 
      
 25 
     | 
    
         
            +
                    create_conf("#{config_path_}/model", model) unless model.nil?
         
     | 
| 
      
 26 
     | 
    
         
            +
                    model_mapper = @config.models.f(:"#{model_}")
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    # image
         
     | 
| 
      
 29 
     | 
    
         
            +
                    return { error: :input_error, message: "No docker_image specified in model '#{model_}.'" } unless (image = model_mapper.docker_image(default: nil))
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    # mail
         
     | 
| 
      
 32 
     | 
    
         
            +
                    unless mail != 'no'
         
     | 
| 
      
 33 
     | 
    
         
            +
                      if mail == 'yes'
         
     | 
| 
      
 34 
     | 
    
         
            +
                        create_conf("#{config_path_}/mail", mail)
         
     | 
| 
      
 35 
     | 
    
         
            +
                        admin_mail_ = admin_mail
         
     | 
| 
      
 36 
     | 
    
         
            +
                        create_conf("#{config_path_}/admin_mail", admin_mail_) unless admin_mail_.nil?
         
     | 
| 
      
 37 
     | 
    
         
            +
                        return { error: :input_error, message: 'Admin mail required.' } if admin_mail_.nil?
         
     | 
| 
      
 38 
     | 
    
         
            +
                      elsif mail == 'model'
         
     | 
| 
      
 39 
     | 
    
         
            +
                        if model_mapper.default_mail == 'yes'
         
     | 
| 
      
 40 
     | 
    
         
            +
                          admin_mail_ = admin_mail || model_mapper.default_admin_mail(default: nil)
         
     | 
| 
      
 41 
     | 
    
         
            +
                          return { error: :input_error, message: 'Admin mail required.' } if admin_mail_.nil?
         
     | 
| 
      
 42 
     | 
    
         
            +
                        end
         
     | 
| 
      
 43 
     | 
    
         
            +
                      end
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    # lib
         
     | 
| 
      
 47 
     | 
    
         
            +
                    lib_path_ = "#{@lib_path}/containers/#{name}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                    lib_path_mapper = PathMapper.new(lib_path_)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    FileUtils.rm_rf "#{lib_path_}/configs"
         
     | 
| 
      
 50 
     | 
    
         
            +
                    FileUtils.mkdir_p "#{lib_path_}/configs"
         
     | 
| 
      
 51 
     | 
    
         
            +
                    FileUtils.mkdir_p "#{lib_path_}/web"
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    # user/group
         
     | 
| 
      
 54 
     | 
    
         
            +
                    self.command("groupadd #{name}")
         
     | 
| 
      
 55 
     | 
    
         
            +
                    self.command("useradd #{name} -g #{name} -d #{lib_path_}/web/")
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    user = Etc.getpwnam(name)
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    write_if_not_exist("#{lib_path_}/configs/etc-group", "#{name}:x:#{user.gid}:")
         
     | 
| 
      
 60 
     | 
    
         
            +
                    write_if_not_exist("#{lib_path_}/configs/etc-passwd", "#{name}:x:#{user.uid}:#{user.gid}::/web/:/usr/sbin/nologin")
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    # system users
         
     | 
| 
      
 63 
     | 
    
         
            +
                    users = [config_path_mapper.system_users, model_mapper.system_users].find {|f| f.is_a? PathMapper::FileNode }
         
     | 
| 
      
 64 
     | 
    
         
            +
                    users.lines.each {|u| self.command("useradd #{name}_#{u.strip} -g #{name} -d #{lib_path_}/web/") } unless users.nil?
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    # services
         
     | 
| 
      
 67 
     | 
    
         
            +
                    cserv = @config.containers.f(name).services._grep(/.*\.erb/).map {|n| [n._name, n]}.to_h
         
     | 
| 
      
 68 
     | 
    
         
            +
                    mserv = model_mapper.services._grep(/.*\.erb/).map {|n| [n._name, n]}.to_h
         
     | 
| 
      
 69 
     | 
    
         
            +
                    services = mserv.merge!(cserv)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    supervisor_path = "#{lib_path_}/supervisor"
         
     | 
| 
      
 72 
     | 
    
         
            +
                    FileUtils.mkdir_p supervisor_path
         
     | 
| 
      
 73 
     | 
    
         
            +
                    services.each do |_name, node|
         
     | 
| 
      
 74 
     | 
    
         
            +
                      text = erb(node, model: model_, container: config_path_mapper)
         
     | 
| 
      
 75 
     | 
    
         
            +
                      create_conf("#{supervisor_path}/#{_name[/.*[^\.erb]/]}", text)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                    # container
         
     | 
| 
      
 79 
     | 
    
         
            +
                    unless model_mapper.f('container.rb').nil?
         
     | 
| 
      
 80 
     | 
    
         
            +
                      registry_path = lib_path_mapper.registry.f('container')._path
         
     | 
| 
      
 81 
     | 
    
         
            +
                      ex = ScriptExecutor::Container.new(
         
     | 
| 
      
 82 
     | 
    
         
            +
                          container: config_path_mapper, container_name: name, container_lib: lib_path_mapper, registry_path: registry_path,
         
     | 
| 
      
 83 
     | 
    
         
            +
                          model: model_mapper, config: @config, lib: @lib
         
     | 
| 
      
 84 
     | 
    
         
            +
                      )
         
     | 
| 
      
 85 
     | 
    
         
            +
                      ex.execute(model_mapper.f('container.rb'))
         
     | 
| 
      
 86 
     | 
    
         
            +
                      ex.commands.each {|c| self.command c }
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    # docker
         
     | 
| 
      
 90 
     | 
    
         
            +
                    write_if_not_exist('/etc/security/docker.conf', "@#{name} #{name}")
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                    # run container
         
     | 
| 
      
 93 
     | 
    
         
            +
                    self.command "docker run --detach --name #{name} -v #{lib_path_}/configs/:/.configs:ro
         
     | 
| 
      
 94 
     | 
    
         
            +
                                  -v #{lib_path_}/web:/web #{image} /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf".split
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                    { error: :error, message: 'Unable to run docker container.' } unless @docker_api.container_info(name)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  def delete(name:)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    config_path_mapper = @config.containers.f(name)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    lib_path_mapper = PathMapper.new("#{@lib_path}/containers/#{name}")
         
     | 
| 
      
 102 
     | 
    
         
            +
                    model = config_path_mapper.model(default: @config.default_model)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    model_mapper = @config.models.f(:"#{model}")
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                    sites = config_path_mapper.sites._grep_dirs.map { |n| n._name }
         
     | 
| 
      
 106 
     | 
    
         
            +
                    sites.each do |s|
         
     | 
| 
      
 107 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 108 
     | 
    
         
            +
                        Site.new(instance_variables_to_hash(self)).delete(s)
         
     | 
| 
      
 109 
     | 
    
         
            +
                      rescue NetStatus::Exception => e
         
     | 
| 
      
 110 
     | 
    
         
            +
                        raise Error::Controller, e.net_status
         
     | 
| 
      
 111 
     | 
    
         
            +
                      end
         
     | 
| 
      
 112 
     | 
    
         
            +
                    end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    unless (container = lib_path_mapper.registry.f('container')).nil?
         
     | 
| 
      
 115 
     | 
    
         
            +
                      FileUtils.rm container.lines
         
     | 
| 
      
 116 
     | 
    
         
            +
                      FileUtils.rm container._path
         
     | 
| 
      
 117 
     | 
    
         
            +
                    end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                    unless model_mapper.f('container.rb').nil?
         
     | 
| 
      
 120 
     | 
    
         
            +
                      registry_path = lib_path_mapper.registry.f('container')._path
         
     | 
| 
      
 121 
     | 
    
         
            +
                      ex = ScriptExecutor::Container.new(
         
     | 
| 
      
 122 
     | 
    
         
            +
                          container: config_path_mapper, container_name: name, container_lib: lib_path_mapper,
         
     | 
| 
      
 123 
     | 
    
         
            +
                          registry_path: registry_path, on_reconfig_only: true,
         
     | 
| 
      
 124 
     | 
    
         
            +
                          model: model_mapper, config: @config, lib: @lib
         
     | 
| 
      
 125 
     | 
    
         
            +
                      )
         
     | 
| 
      
 126 
     | 
    
         
            +
                      ex.execute(model_mapper.f('container.rb'))
         
     | 
| 
      
 127 
     | 
    
         
            +
                      ex.commands.each {|c| self.command c }
         
     | 
| 
      
 128 
     | 
    
         
            +
                    end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                    @docker_api.container_kill(name)
         
     | 
| 
      
 131 
     | 
    
         
            +
                    @docker_api.container_rm(name)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    remove_line_from_file('/etc/security/docker.conf', "@#{name} #{name}")
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 135 
     | 
    
         
            +
                      gid = Etc.getgrnam(name).gid
         
     | 
| 
      
 136 
     | 
    
         
            +
                      Etc.passwd do |user|
         
     | 
| 
      
 137 
     | 
    
         
            +
                        self.command("userdel #{user.name}") if user.gid == gid
         
     | 
| 
      
 138 
     | 
    
         
            +
                      end
         
     | 
| 
      
 139 
     | 
    
         
            +
                      self.command("groupdel #{name}")
         
     | 
| 
      
 140 
     | 
    
         
            +
                    rescue ArgumentError => e
         
     | 
| 
      
 141 
     | 
    
         
            +
                      # repeated command execution: group name already does not exist
         
     | 
| 
      
 142 
     | 
    
         
            +
                    end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                    FileUtils.rm_rf "#{@lib_path}/containers/#{name}/configs"
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                    {}
         
     | 
| 
      
 147 
     | 
    
         
            +
                  end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                  def change(name:, mail: 'model', admin_mail: nil, model: nil)
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                  def update(name:)
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                  end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                  def reconfig(name:)
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                  def save(name:, to:)
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                  def restore(name:, from:, mail: 'model', admin_mail: nil, model: nil)
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  end
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                  def admin(name:, logger: @logger)
         
     | 
| 
      
 170 
     | 
    
         
            +
                    Admin.new(name: name, logger: logger)
         
     | 
| 
      
 171 
     | 
    
         
            +
                  end
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
      
 173 
     | 
    
         
            +
              end
         
     | 
| 
      
 174 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Superhosting
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Controller
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Container
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class Admin < Base
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def initialize(name:, **kvargs)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      @container_name = name
         
     | 
| 
      
 7 
     | 
    
         
            +
                      super(kvargs)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def list
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    def add(name:)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    def delete(name:)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,106 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Superhosting
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Controller
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Site < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_reader :site_index
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  DOMAIN_NAME_FORMAT = /^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,6}$/
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def site_index
         
     | 
| 
      
 9 
     | 
    
         
            +
                    def generate
         
     | 
| 
      
 10 
     | 
    
         
            +
                      @site_index = {}
         
     | 
| 
      
 11 
     | 
    
         
            +
                      @config.containers._grep_dirs.each do |c|
         
     | 
| 
      
 12 
     | 
    
         
            +
                        c.sites._grep_dirs.each do |s|
         
     | 
| 
      
 13 
     | 
    
         
            +
                          names = []
         
     | 
| 
      
 14 
     | 
    
         
            +
                          names << s._name
         
     | 
| 
      
 15 
     | 
    
         
            +
                          s.aliases.lines {|n| names << n.strip } unless s.aliases.nil?
         
     | 
| 
      
 16 
     | 
    
         
            +
                          raise NetStatus::Exception.new(error: :error, message: "Conflict between container_sites: '#{@site_index[s._name][:site]._path}' and '#{s._path}'") if @site_index.key? s._name
         
     | 
| 
      
 17 
     | 
    
         
            +
                          names.each {|n| @site_index[n] = { container: c, site: s } }
         
     | 
| 
      
 18 
     | 
    
         
            +
                        end
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                      @site_index
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    @site_index ||= self.generate
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def add(name:, container_name:)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    return { error: :input_error, message: "Invalid site name '#{name}' only '#{DOMAIN_NAME_FORMAT}'" } if name !~ DOMAIN_NAME_FORMAT
         
     | 
| 
      
 28 
     | 
    
         
            +
                    return { error: :logical_error, message: 'Site already exists.' } if self.site_index.include? name
         
     | 
| 
      
 29 
     | 
    
         
            +
                    return { error: :logical_error, message: "Container '#{container_name}' doesn\'t exists." } if (config_path_mapper = @config.containers.f(container_name)).nil?
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    site_mapper = config_path_mapper.sites.f(name)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    FileUtils.mkdir_p site_mapper._path
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    lib_path_mapper = PathMapper.new("#{@lib_path}/containers/#{container_name}")
         
     | 
| 
      
 35 
     | 
    
         
            +
                    model = config_path_mapper.model(default: @config.default_model)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    model_mapper = @config.models.f(:"#{model}")
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    lib_sites_path = lib_path_mapper.registry.sites
         
     | 
| 
      
 39 
     | 
    
         
            +
                    unless model_mapper.f('site.rb').nil?
         
     | 
| 
      
 40 
     | 
    
         
            +
                      registry_path = lib_sites_path.f(name)._path
         
     | 
| 
      
 41 
     | 
    
         
            +
                      FileUtils.mkdir_p lib_sites_path._path
         
     | 
| 
      
 42 
     | 
    
         
            +
                      ex = ScriptExecutor::Site.new(
         
     | 
| 
      
 43 
     | 
    
         
            +
                          site: site_mapper, site_name: name,
         
     | 
| 
      
 44 
     | 
    
         
            +
                          container: config_path_mapper, container_name: name, container_lib: lib_path_mapper, registry_path: registry_path,
         
     | 
| 
      
 45 
     | 
    
         
            +
                          model: model_mapper, config: @config, lib: @lib
         
     | 
| 
      
 46 
     | 
    
         
            +
                      )
         
     | 
| 
      
 47 
     | 
    
         
            +
                      ex.execute(model_mapper.f('site.rb'))
         
     | 
| 
      
 48 
     | 
    
         
            +
                      ex.commands.each {|c| self.command c }
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    {}
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def delete(name:)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    if site = self.site_index[name]
         
     | 
| 
      
 56 
     | 
    
         
            +
                      FileUtils.rm_rf site[:site]._path
         
     | 
| 
      
 57 
     | 
    
         
            +
                      container_sites = site[:container].sites
         
     | 
| 
      
 58 
     | 
    
         
            +
                      FileUtils.rm_rf container_sites._path if container_sites.nil?
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                      config_path_mapper = site[:container]
         
     | 
| 
      
 61 
     | 
    
         
            +
                      lib_path_mapper = PathMapper.new("#{@lib_path}/containers/#{config_path_mapper._name}")
         
     | 
| 
      
 62 
     | 
    
         
            +
                      model = config_path_mapper.model(default: @config.default_model)
         
     | 
| 
      
 63 
     | 
    
         
            +
                      model_mapper = @config.models.f(:"#{model}")
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                      lib_sites_path = lib_path_mapper.registry.sites
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                      unless (registry_site = lib_sites_path.f(name)).nil?
         
     | 
| 
      
 68 
     | 
    
         
            +
                        FileUtils.rm registry_site.lines
         
     | 
| 
      
 69 
     | 
    
         
            +
                        FileUtils.rm registry_site._path
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                      unless model_mapper.f('site.rb').nil?
         
     | 
| 
      
 73 
     | 
    
         
            +
                        registry_path = lib_sites_path.f(name)._path
         
     | 
| 
      
 74 
     | 
    
         
            +
                        FileUtils.mkdir_p lib_sites_path._path
         
     | 
| 
      
 75 
     | 
    
         
            +
                        ex = ScriptExecutor::Site.new(
         
     | 
| 
      
 76 
     | 
    
         
            +
                            site: site[:site], site_name: name,
         
     | 
| 
      
 77 
     | 
    
         
            +
                            container: config_path_mapper, container_name: name, container_lib: lib_path_mapper,
         
     | 
| 
      
 78 
     | 
    
         
            +
                            registry_path: registry_path, on_reconfig_only: true,
         
     | 
| 
      
 79 
     | 
    
         
            +
                            model: model_mapper, config: @config, lib: @lib
         
     | 
| 
      
 80 
     | 
    
         
            +
                        )
         
     | 
| 
      
 81 
     | 
    
         
            +
                        ex.execute(model_mapper.f('site.rb'))
         
     | 
| 
      
 82 
     | 
    
         
            +
                        ex.commands.each {|c| self.command c }
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                      {}
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  def rename(name:, new_name:)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    return { error: :logical_error, message: "Site '#{name}' doesn't exists." } unless site = self.site_index[name]
         
     | 
| 
      
 91 
     | 
    
         
            +
                    return { error: :logical_error, message: "Site '#{new_name}' already exists." } if self.site_index[new_name]
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                    FileUtils.mv site[:container].sites.f(name)._path, site[:container].sites.f(new_name)._path
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                    lib_path_mapper = PathMapper.new("#{@lib_path}/containers/#{site[:container]._name}")
         
     | 
| 
      
 96 
     | 
    
         
            +
                    unless (lib_sites_path = lib_path_mapper.registry.sites).nil?
         
     | 
| 
      
 97 
     | 
    
         
            +
                      FileUtils.mv lib_sites_path.f(name), lib_sites_path.f(new_name)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    end
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                  def alias(name:, logger: @logger)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    Alias.new(name: name, logger: logger)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
            end
         
     |