implement basic exec [ci skip]
This commit is contained in:
@@ -67,7 +67,7 @@ func (c *daemonCommand) run(*kingpin.ParseContext) error {
|
||||
),
|
||||
)
|
||||
|
||||
engine, err := engine.New(config.Keypair.Public, config.Keypair.Private)
|
||||
engine, err := engine.NewEnv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ func (c *execCommand) run(*kingpin.ParseContext) error {
|
||||
),
|
||||
)
|
||||
|
||||
engine, err := engine.New(c.PublicKey, c.PrivateKey)
|
||||
engine, err := engine.NewEnv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -369,6 +369,30 @@ func (c *Compiler) Compile(ctx context.Context, args Args) *engine.Spec {
|
||||
}
|
||||
}
|
||||
|
||||
// append volumes
|
||||
for _, v := range args.Pipeline.Volumes {
|
||||
id := random()
|
||||
src := new(engine.Volume)
|
||||
if v.EmptyDir != nil {
|
||||
src.EmptyDir = &engine.VolumeEmptyDir{
|
||||
ID: id,
|
||||
Name: v.Name,
|
||||
Medium: v.EmptyDir.Medium,
|
||||
SizeLimit: int64(v.EmptyDir.SizeLimit),
|
||||
Labels: labels,
|
||||
}
|
||||
} else if v.HostPath != nil {
|
||||
src.HostPath = &engine.VolumeHostPath{
|
||||
ID: id,
|
||||
Name: v.Name,
|
||||
Path: v.HostPath.Path,
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
spec.Volumes = append(spec.Volumes, src)
|
||||
}
|
||||
|
||||
return spec
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,6 @@ func setupScriptWindows(src *resource.Step, dst *engine.Step) {
|
||||
|
||||
func setupScriptPosix(src *resource.Step, dst *engine.Step) {
|
||||
dst.Entrypoint = []string{"/bin/sh", "-c"}
|
||||
dst.Command = []string{"echo $DRONE_SCRIPT | /bin/sh -e"}
|
||||
dst.Command = []string{`echo "$DRONE_SCRIPT" | /bin/sh`}
|
||||
dst.Envs["DRONE_SCRIPT"] = shell.Script(src.Commands)
|
||||
}
|
||||
|
||||
@@ -34,9 +34,8 @@ func Script(commands []string) string {
|
||||
// optionScript is a helper script this is added to the build
|
||||
// to set shell options, in this case, to exit on error.
|
||||
const optionScript = `
|
||||
if [[ ! -z "${DRONE_NETRC_FILE}" ]]; then
|
||||
if [ ! -z "${DRONE_NETRC_FILE}" ]; then
|
||||
echo $DRONE_NETRC_FILE > $HOME/.netrc
|
||||
EOF
|
||||
fi
|
||||
|
||||
unset DRONE_SCRIPT
|
||||
|
||||
@@ -43,7 +43,7 @@ func createStep(spec *resource.Pipeline, src *resource.Step) *engine.Step {
|
||||
Networks: nil, // set in compiler.go
|
||||
Files: nil, // set below
|
||||
Volumes: nil, // set below
|
||||
// Devices: nil, // TODO
|
||||
Devices: nil, // see below
|
||||
// Resources: toResources(src), // TODO
|
||||
}
|
||||
|
||||
@@ -55,6 +55,14 @@ func createStep(spec *resource.Pipeline, src *resource.Step) *engine.Step {
|
||||
})
|
||||
}
|
||||
|
||||
// appends the devices to the container def.
|
||||
for _, vol := range src.Devices {
|
||||
dst.Devices = append(dst.Devices, &engine.VolumeDevice{
|
||||
Name: vol.Name,
|
||||
DevicePath: vol.DevicePath,
|
||||
})
|
||||
}
|
||||
|
||||
// appends the settings variables to the
|
||||
// container definition.
|
||||
for key, value := range src.Settings {
|
||||
@@ -82,19 +90,6 @@ func createStep(spec *resource.Pipeline, src *resource.Step) *engine.Step {
|
||||
}
|
||||
}
|
||||
|
||||
// // if the step specifies shell commands we generate a
|
||||
// // script. The script is copied to the container at
|
||||
// // runtime (or mounted as a config map) and then executed
|
||||
// // as the entrypoint.
|
||||
// if len(src.Commands) > 0 {
|
||||
// switch spec.Platform.OS {
|
||||
// case "windows":
|
||||
// setupScriptWin(spec, dst, src)
|
||||
// default:
|
||||
// setupScript(spec, dst, src)
|
||||
// }
|
||||
// }
|
||||
|
||||
// set the pipeline step run policy. steps run on
|
||||
// success by default, but may be optionally configured
|
||||
// to run on failure.
|
||||
|
||||
@@ -22,8 +22,13 @@ func createWorkspace(from *resource.Pipeline) (base, path, full string) {
|
||||
base = from.Workspace.Base
|
||||
path = from.Workspace.Path
|
||||
if base == "" {
|
||||
if strings.HasPrefix(path, "/") {
|
||||
base = path
|
||||
path = ""
|
||||
} else {
|
||||
base = workspacePath
|
||||
}
|
||||
}
|
||||
full = stdpath.Join(base, path)
|
||||
|
||||
if from.Platform.OS == "windows" {
|
||||
|
||||
@@ -36,7 +36,7 @@ func toConfig(spec *Spec, step *Step) *container.Config {
|
||||
}
|
||||
|
||||
if len(step.Entrypoint) != 0 {
|
||||
config.Cmd = step.Entrypoint
|
||||
config.Entrypoint = step.Entrypoint
|
||||
}
|
||||
if len(step.Command) != 0 {
|
||||
config.Cmd = step.Command
|
||||
@@ -117,7 +117,7 @@ func toNetConfig(spec *Spec, proc *Step) *network.NetworkingConfig {
|
||||
func toDeviceSlice(spec *Spec, step *Step) []container.DeviceMapping {
|
||||
var to []container.DeviceMapping
|
||||
for _, mount := range step.Devices {
|
||||
device, ok := LookupVolume(spec, mount.Name)
|
||||
device, ok := lookupVolume(spec, mount.Name)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@@ -141,7 +141,7 @@ func toDeviceSlice(spec *Spec, step *Step) []container.DeviceMapping {
|
||||
func toVolumeSet(spec *Spec, step *Step) map[string]struct{} {
|
||||
set := map[string]struct{}{}
|
||||
for _, mount := range step.Volumes {
|
||||
volume, ok := LookupVolume(spec, mount.Name)
|
||||
volume, ok := lookupVolume(spec, mount.Name)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@@ -166,7 +166,7 @@ func toVolumeSlice(spec *Spec, step *Step) []string {
|
||||
// to get it working with data volumes.
|
||||
var to []string
|
||||
for _, mount := range step.Volumes {
|
||||
volume, ok := LookupVolume(spec, mount.Name)
|
||||
volume, ok := lookupVolume(spec, mount.Name)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@@ -174,7 +174,7 @@ func toVolumeSlice(spec *Spec, step *Step) []string {
|
||||
continue
|
||||
}
|
||||
if isDataVolume(volume) {
|
||||
path := volume.Metadata.UID + ":" + mount.Path
|
||||
path := volume.EmptyDir.ID + ":" + mount.Path
|
||||
to = append(to, path)
|
||||
}
|
||||
if isBindMount(volume) {
|
||||
@@ -190,7 +190,7 @@ func toVolumeSlice(spec *Spec, step *Step) []string {
|
||||
func toVolumeMounts(spec *Spec, step *Step) []mount.Mount {
|
||||
var mounts []mount.Mount
|
||||
for _, target := range step.Volumes {
|
||||
source, ok := LookupVolume(spec, target.Name)
|
||||
source, ok := lookupVolume(spec, target.Name)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@@ -284,3 +284,16 @@ func isNamedPipe(volume *Volume) bool {
|
||||
return volume.HostPath != nil &&
|
||||
strings.HasPrefix(volume.HostPath.Path, `\\.\pipe\`)
|
||||
}
|
||||
|
||||
// helper function returns the named volume.
|
||||
func lookupVolume(spec *Spec, name string) (*Volume, bool) {
|
||||
for _, v := range spec.Volumes {
|
||||
if v.HostPath != nil && v.HostPath.Name == name {
|
||||
return v, true
|
||||
}
|
||||
if v.EmptyDir != nil && v.EmptyDir.Name == name {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -139,6 +139,8 @@ func checkVolumes(pipeline *resource.Pipeline, trusted bool) error {
|
||||
}
|
||||
}
|
||||
switch volume.Name {
|
||||
case "":
|
||||
return fmt.Errorf("linter: missing volume name")
|
||||
case "workspace", "_workspace", "_docker_socket":
|
||||
return fmt.Errorf("linter: invalid volume name: %s", volume.Name)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,12 @@ func TestLint(t *testing.T) {
|
||||
message: "linter: invalid or missing image",
|
||||
},
|
||||
// user should not use reserved volume names.
|
||||
{
|
||||
path: "testdata/volume_missing_name.yml",
|
||||
trusted: false,
|
||||
invalid: true,
|
||||
message: "linter: missing volume name",
|
||||
},
|
||||
{
|
||||
path: "testdata/volume_invalid_name.yml",
|
||||
trusted: false,
|
||||
|
||||
18
engine/linter/testdata/volume_missing_name.yml
vendored
Normal file
18
engine/linter/testdata/volume_missing_name.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: linux
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: golang
|
||||
commands:
|
||||
- go build
|
||||
- go test
|
||||
|
||||
services:
|
||||
- name: database
|
||||
image: redis
|
||||
|
||||
volumes:
|
||||
- temp: {}
|
||||
@@ -32,7 +32,8 @@ func parse(r *manifest.RawResource) (manifest.Resource, bool, error) {
|
||||
|
||||
// match returns true if the resource matches the kind and type.
|
||||
func match(r *manifest.RawResource) bool {
|
||||
return r.Kind == Kind && r.Type == Type
|
||||
return (r.Kind == Kind && r.Type == Type) ||
|
||||
(r.Kind == Kind && r.Type == "")
|
||||
}
|
||||
|
||||
func lint(pipeline *Pipeline) error {
|
||||
|
||||
@@ -27,6 +27,7 @@ type (
|
||||
CPUSet []string `json:"cpu_set,omitempty"`
|
||||
Detach bool `json:"detach,omitempty"`
|
||||
DependsOn []string `json:"depends_on,omitempty"`
|
||||
Devices []*VolumeDevice `json:"devices,omitempty"`
|
||||
DNS []string `json:"dns,omitempty"`
|
||||
DNSSearch []string `json:"dns_search,omitempty"`
|
||||
Entrypoint []string `json:"entrypoint,omitempty"`
|
||||
@@ -119,39 +120,11 @@ type (
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
// XVolume that is mounted into the container
|
||||
XVolume struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Source string `json:"source,omitempty"`
|
||||
Target string `json:"target,omitempty"`
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
volumeDevice struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
volumeData struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
// VolumeDevice describes a mapping of a raw block
|
||||
// device within a container.
|
||||
VolumeDevice struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Path string `json:"target,omitempty"`
|
||||
Mode uint32 `json:"mode,omitempty"`
|
||||
}
|
||||
|
||||
volumeBind struct {
|
||||
Source string `json:"source,omitempty"`
|
||||
Target string `json:"target,omitempty"`
|
||||
Readonly bool `json:"readonly,omitempty"`
|
||||
}
|
||||
|
||||
volumePipe struct {
|
||||
Source string `json:"source,omitempty"`
|
||||
Target string `json:"target,omitempty"`
|
||||
}
|
||||
|
||||
volumeTemp struct {
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
DevicePath string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// Network that is created and attached to containers
|
||||
|
||||
0
engine/testdata/network_bridge.yml
vendored
Normal file
0
engine/testdata/network_bridge.yml
vendored
Normal file
21
engine/testdata/network_default.yml
vendored
Normal file
21
engine/testdata/network_default.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
pull: if-not-exists
|
||||
image: redis
|
||||
commands:
|
||||
- sleep 5
|
||||
- redis-cli -h redis ping
|
||||
- redis-cli -h redis set FOO bar
|
||||
- redis-cli -h redis get FOO
|
||||
|
||||
services:
|
||||
- name: redis
|
||||
pull: if-not-exists
|
||||
image: redis
|
||||
0
engine/testdata/network_host.yml
vendored
Normal file
0
engine/testdata/network_host.yml
vendored
Normal file
15
engine/testdata/status_failure.yml
vendored
Normal file
15
engine/testdata/status_failure.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- echo hello
|
||||
- echo world
|
||||
- exit 1
|
||||
15
engine/testdata/status_success.yml
vendored
Normal file
15
engine/testdata/status_success.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- echo hello
|
||||
- echo world
|
||||
- exit 0
|
||||
32
engine/testdata/volume_host.yml
vendored
Normal file
32
engine/testdata/volume_host.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: write
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
volumes:
|
||||
- name: test
|
||||
path: /tmp
|
||||
commands:
|
||||
- pwd
|
||||
- echo "hello" > /tmp/greetings.txt
|
||||
|
||||
- name: read
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
volumes:
|
||||
- name: test
|
||||
path: /tmp
|
||||
commands:
|
||||
- pwd
|
||||
- cat /tmp/greetings.txt
|
||||
|
||||
volumes:
|
||||
- name: test
|
||||
host:
|
||||
path: /tmp/drone/test
|
||||
24
engine/testdata/volume_mem.yml
vendored
Normal file
24
engine/testdata/volume_mem.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: write
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
volumes:
|
||||
- name: test
|
||||
path: /tmp/memory
|
||||
commands:
|
||||
- ls -la /tmp
|
||||
- ls -la /tmp/memory
|
||||
- touch /tmp/memory/hello.txt
|
||||
- df -T /tmp/memory
|
||||
|
||||
volumes:
|
||||
- name: test
|
||||
temp:
|
||||
medium: memory
|
||||
31
engine/testdata/volume_temp.yml
vendored
Normal file
31
engine/testdata/volume_temp.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: write
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
volumes:
|
||||
- name: test
|
||||
path: /tmp
|
||||
commands:
|
||||
- pwd
|
||||
- echo "hello" > /tmp/greetings.txt
|
||||
|
||||
- name: read
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
volumes:
|
||||
- name: test
|
||||
path: /tmp
|
||||
commands:
|
||||
- pwd
|
||||
- cat /tmp/greetings.txt
|
||||
|
||||
volumes:
|
||||
- name: test
|
||||
temp: {}
|
||||
24
engine/testdata/workspace_custom.yml
vendored
Normal file
24
engine/testdata/workspace_custom.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
workspace:
|
||||
path: /drone/custom/path
|
||||
|
||||
steps:
|
||||
- name: write
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- pwd
|
||||
- echo "hello" > greetings.txt
|
||||
|
||||
- name: read
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- pwd
|
||||
- cat greetings.txt
|
||||
21
engine/testdata/workspace_default.yml
vendored
Normal file
21
engine/testdata/workspace_default.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: write
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- echo "hello" > greetings.txt
|
||||
- df -T /drone/src
|
||||
|
||||
- name: read
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- pwd
|
||||
- cat greetings.txt
|
||||
25
engine/testdata/workspace_legacy.yml
vendored
Normal file
25
engine/testdata/workspace_legacy.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
workspace:
|
||||
base: /tmp
|
||||
path: /drone
|
||||
|
||||
steps:
|
||||
- name: write
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- pwd
|
||||
- echo "hello" > /tmp/greetings.txt
|
||||
|
||||
- name: read
|
||||
pull: if-not-exists
|
||||
image: alpine
|
||||
commands:
|
||||
- pwd
|
||||
- cat /tmp/greetings.txt
|
||||
Reference in New Issue
Block a user