Phase 2: Implement Execution Environment Abstraction (v0.3.0)
This commit implements Phase 2 of the CHORUS Task Execution Engine development plan, providing a comprehensive execution environment abstraction layer with Docker container sandboxing support. ## New Features ### Core Sandbox Interface - Comprehensive ExecutionSandbox interface with isolated task execution - Support for command execution, file I/O, environment management - Resource usage monitoring and sandbox lifecycle management - Standardized error handling with SandboxError types and categories ### Docker Container Sandbox Implementation - Full Docker API integration with secure container creation - Transparent repository mounting with configurable read/write access - Advanced security policies with capability dropping and privilege controls - Comprehensive resource limits (CPU, memory, disk, processes, file handles) - Support for tmpfs mounts, masked paths, and read-only bind mounts - Container lifecycle management with proper cleanup and health monitoring ### Security & Resource Management - Configurable security policies with SELinux, AppArmor, and Seccomp support - Fine-grained capability management with secure defaults - Network isolation options with configurable DNS and proxy settings - Resource monitoring with real-time CPU, memory, and network usage tracking - Comprehensive ulimits configuration for process and file handle limits ### Repository Integration - Seamless repository mounting from local paths to container workspaces - Git configuration support with user credentials and global settings - File inclusion/exclusion patterns for selective repository access - Configurable permissions and ownership for mounted repositories ### Testing Infrastructure - Comprehensive test suite with 60+ test cases covering all functionality - Docker integration tests with Alpine Linux containers (skipped in short mode) - Mock sandbox implementation for unit testing without Docker dependencies - Security policy validation tests with read-only filesystem enforcement - Resource usage monitoring and cleanup verification tests ## Technical Details ### Dependencies Added - github.com/docker/docker v28.4.0+incompatible - Docker API client - github.com/docker/go-connections v0.6.0 - Docker connection utilities - github.com/docker/go-units v0.5.0 - Docker units and formatting - Associated Docker API dependencies for complete container management ### Architecture - Interface-driven design enabling multiple sandbox implementations - Comprehensive configuration structures for all sandbox aspects - Resource usage tracking with detailed metrics collection - Error handling with retryable error classification - Proper cleanup and resource management throughout sandbox lifecycle ### Compatibility - Maintains backward compatibility with existing CHORUS architecture - Designed for future integration with Phase 3 Core Task Execution Engine - Extensible design supporting additional sandbox implementations (VM, process) This Phase 2 implementation provides the foundation for secure, isolated task execution that will be integrated with the AI model providers from Phase 1 in the upcoming Phase 3 development. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										193
									
								
								vendor/github.com/opencontainers/go-digest/algorithm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								vendor/github.com/opencontainers/go-digest/algorithm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| // Copyright 2019, 2020 OCI Contributors | ||||
| // Copyright 2017 Docker, Inc. | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     https://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package digest | ||||
|  | ||||
| import ( | ||||
| 	"crypto" | ||||
| 	"fmt" | ||||
| 	"hash" | ||||
| 	"io" | ||||
| 	"regexp" | ||||
| ) | ||||
|  | ||||
| // Algorithm identifies and implementation of a digester by an identifier. | ||||
| // Note the that this defines both the hash algorithm used and the string | ||||
| // encoding. | ||||
| type Algorithm string | ||||
|  | ||||
| // supported digest types | ||||
| const ( | ||||
| 	SHA256 Algorithm = "sha256" // sha256 with hex encoding (lower case only) | ||||
| 	SHA384 Algorithm = "sha384" // sha384 with hex encoding (lower case only) | ||||
| 	SHA512 Algorithm = "sha512" // sha512 with hex encoding (lower case only) | ||||
|  | ||||
| 	// Canonical is the primary digest algorithm used with the distribution | ||||
| 	// project. Other digests may be used but this one is the primary storage | ||||
| 	// digest. | ||||
| 	Canonical = SHA256 | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// TODO(stevvooe): Follow the pattern of the standard crypto package for | ||||
| 	// registration of digests. Effectively, we are a registerable set and | ||||
| 	// common symbol access. | ||||
|  | ||||
| 	// algorithms maps values to hash.Hash implementations. Other algorithms | ||||
| 	// may be available but they cannot be calculated by the digest package. | ||||
| 	algorithms = map[Algorithm]crypto.Hash{ | ||||
| 		SHA256: crypto.SHA256, | ||||
| 		SHA384: crypto.SHA384, | ||||
| 		SHA512: crypto.SHA512, | ||||
| 	} | ||||
|  | ||||
| 	// anchoredEncodedRegexps contains anchored regular expressions for hex-encoded digests. | ||||
| 	// Note that /A-F/ disallowed. | ||||
| 	anchoredEncodedRegexps = map[Algorithm]*regexp.Regexp{ | ||||
| 		SHA256: regexp.MustCompile(`^[a-f0-9]{64}$`), | ||||
| 		SHA384: regexp.MustCompile(`^[a-f0-9]{96}$`), | ||||
| 		SHA512: regexp.MustCompile(`^[a-f0-9]{128}$`), | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // Available returns true if the digest type is available for use. If this | ||||
| // returns false, Digester and Hash will return nil. | ||||
| func (a Algorithm) Available() bool { | ||||
| 	h, ok := algorithms[a] | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// check availability of the hash, as well | ||||
| 	return h.Available() | ||||
| } | ||||
|  | ||||
| func (a Algorithm) String() string { | ||||
| 	return string(a) | ||||
| } | ||||
|  | ||||
| // Size returns number of bytes returned by the hash. | ||||
| func (a Algorithm) Size() int { | ||||
| 	h, ok := algorithms[a] | ||||
| 	if !ok { | ||||
| 		return 0 | ||||
| 	} | ||||
| 	return h.Size() | ||||
| } | ||||
|  | ||||
| // Set implemented to allow use of Algorithm as a command line flag. | ||||
| func (a *Algorithm) Set(value string) error { | ||||
| 	if value == "" { | ||||
| 		*a = Canonical | ||||
| 	} else { | ||||
| 		// just do a type conversion, support is queried with Available. | ||||
| 		*a = Algorithm(value) | ||||
| 	} | ||||
|  | ||||
| 	if !a.Available() { | ||||
| 		return ErrDigestUnsupported | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Digester returns a new digester for the specified algorithm. If the algorithm | ||||
| // does not have a digester implementation, nil will be returned. This can be | ||||
| // checked by calling Available before calling Digester. | ||||
| func (a Algorithm) Digester() Digester { | ||||
| 	return &digester{ | ||||
| 		alg:  a, | ||||
| 		hash: a.Hash(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Hash returns a new hash as used by the algorithm. If not available, the | ||||
| // method will panic. Check Algorithm.Available() before calling. | ||||
| func (a Algorithm) Hash() hash.Hash { | ||||
| 	if !a.Available() { | ||||
| 		// Empty algorithm string is invalid | ||||
| 		if a == "" { | ||||
| 			panic(fmt.Sprintf("empty digest algorithm, validate before calling Algorithm.Hash()")) | ||||
| 		} | ||||
|  | ||||
| 		// NOTE(stevvooe): A missing hash is usually a programming error that | ||||
| 		// must be resolved at compile time. We don't import in the digest | ||||
| 		// package to allow users to choose their hash implementation (such as | ||||
| 		// when using stevvooe/resumable or a hardware accelerated package). | ||||
| 		// | ||||
| 		// Applications that may want to resolve the hash at runtime should | ||||
| 		// call Algorithm.Available before call Algorithm.Hash(). | ||||
| 		panic(fmt.Sprintf("%v not available (make sure it is imported)", a)) | ||||
| 	} | ||||
|  | ||||
| 	return algorithms[a].New() | ||||
| } | ||||
|  | ||||
| // Encode encodes the raw bytes of a digest, typically from a hash.Hash, into | ||||
| // the encoded portion of the digest. | ||||
| func (a Algorithm) Encode(d []byte) string { | ||||
| 	// TODO(stevvooe): Currently, all algorithms use a hex encoding. When we | ||||
| 	// add support for back registration, we can modify this accordingly. | ||||
| 	return fmt.Sprintf("%x", d) | ||||
| } | ||||
|  | ||||
| // FromReader returns the digest of the reader using the algorithm. | ||||
| func (a Algorithm) FromReader(rd io.Reader) (Digest, error) { | ||||
| 	digester := a.Digester() | ||||
|  | ||||
| 	if _, err := io.Copy(digester.Hash(), rd); err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return digester.Digest(), nil | ||||
| } | ||||
|  | ||||
| // FromBytes digests the input and returns a Digest. | ||||
| func (a Algorithm) FromBytes(p []byte) Digest { | ||||
| 	digester := a.Digester() | ||||
|  | ||||
| 	if _, err := digester.Hash().Write(p); err != nil { | ||||
| 		// Writes to a Hash should never fail. None of the existing | ||||
| 		// hash implementations in the stdlib or hashes vendored | ||||
| 		// here can return errors from Write. Having a panic in this | ||||
| 		// condition instead of having FromBytes return an error value | ||||
| 		// avoids unnecessary error handling paths in all callers. | ||||
| 		panic("write to hash function returned error: " + err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	return digester.Digest() | ||||
| } | ||||
|  | ||||
| // FromString digests the string input and returns a Digest. | ||||
| func (a Algorithm) FromString(s string) Digest { | ||||
| 	return a.FromBytes([]byte(s)) | ||||
| } | ||||
|  | ||||
| // Validate validates the encoded portion string | ||||
| func (a Algorithm) Validate(encoded string) error { | ||||
| 	r, ok := anchoredEncodedRegexps[a] | ||||
| 	if !ok { | ||||
| 		return ErrDigestUnsupported | ||||
| 	} | ||||
| 	// Digests much always be hex-encoded, ensuring that their hex portion will | ||||
| 	// always be size*2 | ||||
| 	if a.Size()*2 != len(encoded) { | ||||
| 		return ErrDigestInvalidLength | ||||
| 	} | ||||
| 	if r.MatchString(encoded) { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return ErrDigestInvalidFormat | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 anthonyrawlins
					anthonyrawlins