orca 0.1.0
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.
- data/.gitignore +2 -0
 - data/Gemfile +6 -0
 - data/Gemfile.lock +29 -0
 - data/LICENSE +7 -0
 - data/README.md +109 -0
 - data/Rakefile +9 -0
 - data/bin/orca +6 -0
 - data/config/template/files/.empty_directory +0 -0
 - data/config/template/orca.rb +28 -0
 - data/lib/orca.rb +48 -0
 - data/lib/orca/cli.rb +53 -0
 - data/lib/orca/dsl.rb +18 -0
 - data/lib/orca/execution_context.rb +89 -0
 - data/lib/orca/extensions/apt.rb +54 -0
 - data/lib/orca/extensions/file_sync.rb +100 -0
 - data/lib/orca/local_file.rb +77 -0
 - data/lib/orca/node.rb +83 -0
 - data/lib/orca/package.rb +52 -0
 - data/lib/orca/package_index.rb +37 -0
 - data/lib/orca/remote_file.rb +104 -0
 - data/lib/orca/resolver.rb +37 -0
 - data/lib/orca/runner.rb +81 -0
 - data/lib/orca/suite.rb +18 -0
 - data/orca.gemspec +18 -0
 - data/test/dsl_test.rb +35 -0
 - data/test/fixtures/example.txt +1 -0
 - data/test/local_file_test.rb +59 -0
 - data/test/package_index_test.rb +48 -0
 - data/test/package_test.rb +51 -0
 - data/test/remote_file_test.rb +91 -0
 - data/test/resolver_test.rb +61 -0
 - data/test/test_helper.rb +8 -0
 - metadata +150 -0
 
| 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Orca.extension :file_sync do
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Orca::Package
         
     | 
| 
      
 3 
     | 
    
         
            +
                def file(config)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  Orca::FileSync.new(self, config).configure
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            class Orca::FileSync
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(parent, config)
         
     | 
| 
      
 11 
     | 
    
         
            +
                @parent = parent
         
     | 
| 
      
 12 
     | 
    
         
            +
                @config = config
         
     | 
| 
      
 13 
     | 
    
         
            +
                raise ArgumentError.new('A file :source must be provided') unless local_path
         
     | 
| 
      
 14 
     | 
    
         
            +
                raise ArgumentError.new('A file :destination must be provided') unless remote_path
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def local_path
         
     | 
| 
      
 18 
     | 
    
         
            +
                @config[:source]
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              def remote_path
         
     | 
| 
      
 22 
     | 
    
         
            +
                @config[:destination]
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def permissions
         
     | 
| 
      
 26 
     | 
    
         
            +
                @config[:permissions]
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def user
         
     | 
| 
      
 30 
     | 
    
         
            +
                @config[:user]
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def group
         
     | 
| 
      
 34 
     | 
    
         
            +
                @config[:group]
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              def create_dir
         
     | 
| 
      
 38 
     | 
    
         
            +
                @config[:create_dir] || @config[:create_dirs]
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              def package_name(suffix)
         
     | 
| 
      
 42 
     | 
    
         
            +
                "file-#{suffix}[#{remote_path}]"
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              def configure
         
     | 
| 
      
 46 
     | 
    
         
            +
                fs = self
         
     | 
| 
      
 47 
     | 
    
         
            +
                add_content_package
         
     | 
| 
      
 48 
     | 
    
         
            +
                add_permissions_package unless permissions.nil? and user.nil? and group.nil?
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              def add_content_package
         
     | 
| 
      
 52 
     | 
    
         
            +
                fs = self
         
     | 
| 
      
 53 
     | 
    
         
            +
                add_package('content') do |package|
         
     | 
| 
      
 54 
     | 
    
         
            +
                  package.command :apply do
         
     | 
| 
      
 55 
     | 
    
         
            +
                    if fs.create_dir
         
     | 
| 
      
 56 
     | 
    
         
            +
                      mk_dir = fs.create_dir == true ? File.dirname(fs.remote_path) : fs.create_dir
         
     | 
| 
      
 57 
     | 
    
         
            +
                      sudo("mkdir -p #{mk_dir}")
         
     | 
| 
      
 58 
     | 
    
         
            +
                      sudo("chown #{fs.user}:#{fs.group || fs.user} #{mk_dir}") if fs.user
         
     | 
| 
      
 59 
     | 
    
         
            +
                    end
         
     | 
| 
      
 60 
     | 
    
         
            +
                    local_file = local(fs.local_path)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    tmp_path = "orca-upload-#{local_file.hash}"
         
     | 
| 
      
 62 
     | 
    
         
            +
                    local_file.copy_to(remote(tmp_path))
         
     | 
| 
      
 63 
     | 
    
         
            +
                    sudo("mv #{tmp_path} #{fs.remote_path}")
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  package.command :remove do
         
     | 
| 
      
 67 
     | 
    
         
            +
                    remote(fs.remote_path).delete!
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  package.command :validate do
         
     | 
| 
      
 71 
     | 
    
         
            +
                    local(fs.local_path).matches?(remote(fs.remote_path))
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              def add_permissions_package
         
     | 
| 
      
 77 
     | 
    
         
            +
                fs = self
         
     | 
| 
      
 78 
     | 
    
         
            +
                add_package('permissions') do |package|
         
     | 
| 
      
 79 
     | 
    
         
            +
                  package.command :apply do
         
     | 
| 
      
 80 
     | 
    
         
            +
                    remote(fs.remote_path).set_owner(fs.user, fs.group) unless fs.user.nil? and fs.group.nil?
         
     | 
| 
      
 81 
     | 
    
         
            +
                    remote(fs.remote_path).set_permissions(fs.permissions) unless fs.permissions.nil?
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  package.command :validate do
         
     | 
| 
      
 85 
     | 
    
         
            +
                    r_file = remote(fs.remote_path)
         
     | 
| 
      
 86 
     | 
    
         
            +
                    valid = r_file.permissions == fs.permissions
         
     | 
| 
      
 87 
     | 
    
         
            +
                    valid = valid && r_file.user == fs.user if fs.user
         
     | 
| 
      
 88 
     | 
    
         
            +
                    valid = valid && r_file.group == fs.group if fs.group
         
     | 
| 
      
 89 
     | 
    
         
            +
                    valid
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              def add_package(suffix)
         
     | 
| 
      
 95 
     | 
    
         
            +
                package = Orca.add_package(package_name(suffix))
         
     | 
| 
      
 96 
     | 
    
         
            +
                yield(package)
         
     | 
| 
      
 97 
     | 
    
         
            +
                @parent.triggers(package.name)
         
     | 
| 
      
 98 
     | 
    
         
            +
                package
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,77 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'digest/sha1'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class Orca::LocalFile
         
     | 
| 
      
 5 
     | 
    
         
            +
              attr_reader :path
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def initialize(path)
         
     | 
| 
      
 8 
     | 
    
         
            +
                @path = resolve(path)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def resolve(path)
         
     | 
| 
      
 12 
     | 
    
         
            +
                if path =~ /^\//
         
     | 
| 
      
 13 
     | 
    
         
            +
                  path
         
     | 
| 
      
 14 
     | 
    
         
            +
                else
         
     | 
| 
      
 15 
     | 
    
         
            +
                  File.join(Orca.root, path)
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def hash
         
     | 
| 
      
 20 
     | 
    
         
            +
                return nil unless exists?
         
     | 
| 
      
 21 
     | 
    
         
            +
                Digest::SHA1.file(path).hexdigest
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              def exists?
         
     | 
| 
      
 25 
     | 
    
         
            +
                File.exists?(@path)
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              # deosnt check permissions or user. should it?
         
     | 
| 
      
 29 
     | 
    
         
            +
              def matches?(other)
         
     | 
| 
      
 30 
     | 
    
         
            +
                self.exists? && other.exists? && self.hash == other.hash
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def copy_to(destination)
         
     | 
| 
      
 34 
     | 
    
         
            +
                if destination.is_local?
         
     | 
| 
      
 35 
     | 
    
         
            +
                  duplicate(destination)
         
     | 
| 
      
 36 
     | 
    
         
            +
                else
         
     | 
| 
      
 37 
     | 
    
         
            +
                  upload(destination)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
                destination
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def copy_from(destination)
         
     | 
| 
      
 43 
     | 
    
         
            +
                destination.copy_to(self)
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              def duplicate(destination)
         
     | 
| 
      
 47 
     | 
    
         
            +
                FileUtils.cp(path, destination.path)
         
     | 
| 
      
 48 
     | 
    
         
            +
                destination
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              def upload(destination)
         
     | 
| 
      
 52 
     | 
    
         
            +
                destination.upload(self)
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              def delete!
         
     | 
| 
      
 56 
     | 
    
         
            +
                FileUtils.rm(path) if exists?
         
     | 
| 
      
 57 
     | 
    
         
            +
                self
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def set_permissions(mask)
         
     | 
| 
      
 61 
     | 
    
         
            +
                FileUtils.chmod_R(mask, path)
         
     | 
| 
      
 62 
     | 
    
         
            +
                self
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              def permissions
         
     | 
| 
      
 66 
     | 
    
         
            +
                 File.stat(path).mode & 0777
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              def set_owner(user, group=nil)
         
     | 
| 
      
 70 
     | 
    
         
            +
                FileUtils.chown_R(user, group, path)
         
     | 
| 
      
 71 
     | 
    
         
            +
                self
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              def is_local?
         
     | 
| 
      
 75 
     | 
    
         
            +
                true
         
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/orca/node.rb
    ADDED
    
    | 
         @@ -0,0 +1,83 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'net/ssh'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'net/sftp'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class Orca::Node
         
     | 
| 
      
 5 
     | 
    
         
            +
              attr_reader :name, :host
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def self.find(name)
         
     | 
| 
      
 8 
     | 
    
         
            +
                return name if name.is_a?(Orca::Node)
         
     | 
| 
      
 9 
     | 
    
         
            +
                @nodes[name]
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def self.register(node)
         
     | 
| 
      
 13 
     | 
    
         
            +
                @nodes ||= {}
         
     | 
| 
      
 14 
     | 
    
         
            +
                @nodes[node.name] = node
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def initialize(name, host, options={})
         
     | 
| 
      
 18 
     | 
    
         
            +
                @name = name
         
     | 
| 
      
 19 
     | 
    
         
            +
                @host = host
         
     | 
| 
      
 20 
     | 
    
         
            +
                @options = options
         
     | 
| 
      
 21 
     | 
    
         
            +
                @connection = nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                Orca::Node.register(self)
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def upload(from, to)
         
     | 
| 
      
 26 
     | 
    
         
            +
                log('sftp', "UPLOAD: #{from} => #{to}")
         
     | 
| 
      
 27 
     | 
    
         
            +
                sftp.upload!(from, to)
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def download(from, to)
         
     | 
| 
      
 31 
     | 
    
         
            +
                log('sftp', "DOWLOAD: #{from} => #{to}")
         
     | 
| 
      
 32 
     | 
    
         
            +
                sftp.download!(from, to)
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def remove(path)
         
     | 
| 
      
 36 
     | 
    
         
            +
                log('sftp', "REMOVE: #{path}")
         
     | 
| 
      
 37 
     | 
    
         
            +
                sftp.remove!(path)
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def stat(path)
         
     | 
| 
      
 41 
     | 
    
         
            +
                log('sftp', "STAT: #{path}")
         
     | 
| 
      
 42 
     | 
    
         
            +
                sftp.stat!(path)
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              def setstat(path, opts)
         
     | 
| 
      
 46 
     | 
    
         
            +
                log('sftp', "SET: #{path} - #{opts.inspect}")
         
     | 
| 
      
 47 
     | 
    
         
            +
                sftp.setstat!(path, opts)
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def sftp
         
     | 
| 
      
 51 
     | 
    
         
            +
                @sftp ||= connection.sftp.connect
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              def execute(cmd)
         
     | 
| 
      
 55 
     | 
    
         
            +
                log('execute', cmd.cyan)
         
     | 
| 
      
 56 
     | 
    
         
            +
                output = ""
         
     | 
| 
      
 57 
     | 
    
         
            +
                connection.exec! cmd do |channel, stream, data|
         
     | 
| 
      
 58 
     | 
    
         
            +
                  output += data if stream == :stdout
         
     | 
| 
      
 59 
     | 
    
         
            +
                  data.split("\n").each do |line|
         
     | 
| 
      
 60 
     | 
    
         
            +
                    msg = stream == :stdout ? line.green : line.red
         
     | 
| 
      
 61 
     | 
    
         
            +
                    log(stream, msg)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
                output
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              def sudo(cmd)
         
     | 
| 
      
 68 
     | 
    
         
            +
                execute("sudo #{cmd}")
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              def log(context, msg)
         
     | 
| 
      
 72 
     | 
    
         
            +
                puts "#{self.to_s} [#{context.to_s.bold}] #{msg}"
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              def connection
         
     | 
| 
      
 76 
     | 
    
         
            +
                return @connection if @connection
         
     | 
| 
      
 77 
     | 
    
         
            +
                @connetion = Net::SSH.start(@host, (@options[:user] || 'root'), @options)
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
              def to_s
         
     | 
| 
      
 81 
     | 
    
         
            +
                "#{name}(#{host})"
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/orca/package.rb
    ADDED
    
    | 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Orca::Package
         
     | 
| 
      
 2 
     | 
    
         
            +
              attr_reader :name, :dependancies, :actions, :children
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize(name)
         
     | 
| 
      
 5 
     | 
    
         
            +
                @name = name
         
     | 
| 
      
 6 
     | 
    
         
            +
                @dependancies = []
         
     | 
| 
      
 7 
     | 
    
         
            +
                @children = []
         
     | 
| 
      
 8 
     | 
    
         
            +
                @actions = {}
         
     | 
| 
      
 9 
     | 
    
         
            +
                @commands = {}
         
     | 
| 
      
 10 
     | 
    
         
            +
                @remove = nil
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def depends_on(*pkg_names)
         
     | 
| 
      
 14 
     | 
    
         
            +
                pkg_names.each do |pkg_name|
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @dependancies << pkg_name
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def triggers(*pkg_names)
         
     | 
| 
      
 20 
     | 
    
         
            +
                pkg_names.each do |pkg_name|
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @children << pkg_name
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def validate(&definition)
         
     | 
| 
      
 26 
     | 
    
         
            +
                command(:validate, &definition)
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def apply(&definition)
         
     | 
| 
      
 30 
     | 
    
         
            +
                command(:apply, &definition)
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def remove(&definition)
         
     | 
| 
      
 34 
     | 
    
         
            +
                command(:remove, &definition)
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              def action(name, &definition)
         
     | 
| 
      
 38 
     | 
    
         
            +
                @actions[name] = definition
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              def command(name, &definition)
         
     | 
| 
      
 42 
     | 
    
         
            +
                if block_given?
         
     | 
| 
      
 43 
     | 
    
         
            +
                  (@commands[name.to_sym] ||= []) << definition
         
     | 
| 
      
 44 
     | 
    
         
            +
                else
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @commands[name.to_sym]
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              def provides_command?(name)
         
     | 
| 
      
 50 
     | 
    
         
            +
                @commands.has_key?(name.to_sym)
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Orca::PackageIndex
         
     | 
| 
      
 2 
     | 
    
         
            +
              attr_reader :index_name
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize(index_name)
         
     | 
| 
      
 5 
     | 
    
         
            +
                @index_name = index_name
         
     | 
| 
      
 6 
     | 
    
         
            +
                @packages = {}
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def self.default
         
     | 
| 
      
 10 
     | 
    
         
            +
                @default ||= new('default')
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def add(pkg)
         
     | 
| 
      
 14 
     | 
    
         
            +
                @packages[pkg.name] = pkg
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def get(pkg_name)
         
     | 
| 
      
 18 
     | 
    
         
            +
                pkg = @packages[pkg_name]
         
     | 
| 
      
 19 
     | 
    
         
            +
                raise MissingPackageError.new(index_name, pkg_name) if pkg.nil?
         
     | 
| 
      
 20 
     | 
    
         
            +
                pkg
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def clear!
         
     | 
| 
      
 24 
     | 
    
         
            +
                @packages = {}
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              class MissingPackageError < StandardError
         
     | 
| 
      
 28 
     | 
    
         
            +
                def initialize(index_name, package_name)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @index_name = index_name
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @package_name = package_name
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def message
         
     | 
| 
      
 34 
     | 
    
         
            +
                  "package #{@package_name} could not be found in the index #{@index_name}"
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,104 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'digest/sha1'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class Orca::RemoteFile
         
     | 
| 
      
 5 
     | 
    
         
            +
              attr_reader :path
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def initialize(context, path)
         
     | 
| 
      
 8 
     | 
    
         
            +
                @context = context
         
     | 
| 
      
 9 
     | 
    
         
            +
                @path = path
         
     | 
| 
      
 10 
     | 
    
         
            +
                @exists = nil
         
     | 
| 
      
 11 
     | 
    
         
            +
                @permissions = nil
         
     | 
| 
      
 12 
     | 
    
         
            +
                @owner = nil
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def hash
         
     | 
| 
      
 16 
     | 
    
         
            +
                return nil unless exists?
         
     | 
| 
      
 17 
     | 
    
         
            +
                @hash ||= @context.run("sha1sum #{path}")[0...40]
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def exists?
         
     | 
| 
      
 21 
     | 
    
         
            +
                return @exists unless @exists.nil?
         
     | 
| 
      
 22 
     | 
    
         
            +
                result = @context.run(%[if [ -f #{path} ]; then echo "true"; else echo "false"; fi])
         
     | 
| 
      
 23 
     | 
    
         
            +
                @exists = result.strip == 'true'
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              # deosnt check permissions or user. should it?
         
     | 
| 
      
 27 
     | 
    
         
            +
              def matches?(other)
         
     | 
| 
      
 28 
     | 
    
         
            +
                self.exists? && other.exists? && self.hash == other.hash
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def copy_to(destination)
         
     | 
| 
      
 32 
     | 
    
         
            +
                if destination.is_local?
         
     | 
| 
      
 33 
     | 
    
         
            +
                  download(destination)
         
     | 
| 
      
 34 
     | 
    
         
            +
                else
         
     | 
| 
      
 35 
     | 
    
         
            +
                  duplicate(destination)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
                destination
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def copy_from(destination)
         
     | 
| 
      
 41 
     | 
    
         
            +
                destination.copy_to(self)
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              def duplicate(destination)
         
     | 
| 
      
 45 
     | 
    
         
            +
                @context.sudo("cp #{path} #{destination.path}")
         
     | 
| 
      
 46 
     | 
    
         
            +
                destination
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              def download(destination)
         
     | 
| 
      
 50 
     | 
    
         
            +
                @context.download(path, destination.path)
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              def upload(source)
         
     | 
| 
      
 54 
     | 
    
         
            +
                @context.upload(source.path, path)
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              def delete!
         
     | 
| 
      
 58 
     | 
    
         
            +
                @context.remove(path)
         
     | 
| 
      
 59 
     | 
    
         
            +
                invalidate!
         
     | 
| 
      
 60 
     | 
    
         
            +
                self
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              def set_permissions(mask)
         
     | 
| 
      
 64 
     | 
    
         
            +
                @context.sudo("chmod -R #{sprintf("%o",mask)} #{path}")
         
     | 
| 
      
 65 
     | 
    
         
            +
                invalidate!
         
     | 
| 
      
 66 
     | 
    
         
            +
                self
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              def permissions
         
     | 
| 
      
 70 
     | 
    
         
            +
                @permissions ||= @context.run("stat --format=%a #{path}").strip.to_i(8)
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              def set_owner(user, group=nil)
         
     | 
| 
      
 74 
     | 
    
         
            +
                @context.sudo("chown -R #{user}:#{group} #{path}")
         
     | 
| 
      
 75 
     | 
    
         
            +
                invalidate!
         
     | 
| 
      
 76 
     | 
    
         
            +
                self
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              def owner
         
     | 
| 
      
 80 
     | 
    
         
            +
                @owner ||= begin
         
     | 
| 
      
 81 
     | 
    
         
            +
                  user, group = @context.run("stat --format=%U:%G #{path}").chomp.split(":")
         
     | 
| 
      
 82 
     | 
    
         
            +
                  {:user => user, :group => group}
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
              def user
         
     | 
| 
      
 87 
     | 
    
         
            +
                owner[:user]
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              def group
         
     | 
| 
      
 91 
     | 
    
         
            +
                owner[:group]
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              def is_local?
         
     | 
| 
      
 95 
     | 
    
         
            +
                false
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
              private
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              def invalidate!
         
     | 
| 
      
 101 
     | 
    
         
            +
                @permissions = nil
         
     | 
| 
      
 102 
     | 
    
         
            +
                @owner = nil
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
            end
         
     |