text:
package part4faulttolerance

import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Kill, PoisonPill, Props, Terminated}

object StartingStoppingActors extends App {

  val system = ActorSystem("StartStop")

  object Parent {
    case class StartChild(name: String)
    case class StopChild(name: String)
    case object Stop
  }

  class Parent extends Actor with ActorLogging {
    import Parent._

    override def receive: Receive = withChildren(Map())

    def withChildren(children: Map[String, ActorRef]): Receive = {
      case StartChild(name) =>
        log.info(s"Starting child $name")
        val childRef = context.actorOf(Props[Child], name)
        context.become(withChildren(children + (name -> childRef)))
      case StopChild(name) =>
        log.info(s"Stopping child $name")
        val childOption = children.get(name)
        // context.stop is an asynchronous method.
        childOption.foreach(childRef => context.stop(childRef))
      case Stop =>
        log.info("Stopping parent")
        // Stops itself and all its children.
        context.stop(self)
    }
  }

  class Child extends Actor with ActorLogging {
    override def receive: Receive = {
      case message => log.info(message.toString)
    }
  }

  import Parent._

  val parent = system.actorOf(Props[Parent], "parent")
  parent ! StartChild("child1")

  val child = system.actorSelection("/user/parent/child1")
  child ! "It works!"

  parent ! StopChild("child1")

  parent ! Stop

  val looseActor = system.actorOf(Props[Child])
  // PoisonPill kills an actor.
  looseActor ! PoisonPill

  val looseActor2 = system.actorOf(Props[Child])
  // Kill kills an actor.
  looseActor2 ! Kill

  /**
    * Watch a stopped actor. You can be notified when an actor is stopped.
    */
  class Watcher extends Actor with ActorLogging {
    import Parent._

    override def receive: Receive = {
      case StartChild(name) =>
        val child = context.actorOf(Props[Child], name)
        log.info(s"Started and watching child $name")
        context.watch(child)
      case Terminated(ref) =>
        log.info(s"$ref has been stopped")
    }
  }

  val watcher = system.actorOf(Props[Watcher], "watcher")
  watcher ! StartChild("watchedChild")
  val watchedChild = system.actorSelection("/user/watcher/watchedChild")
  Thread.sleep(500)
  watchedChild ! PoisonPill
}


text:
struct swift_fs {
  struct fs fs;
  struct swift_context *swcon;
};

struct swift_fs_file {
  struct fs_file file;
  struct swift_transfer_handle *handle;
};

static struct swift_context *
fs_swift_create_context(const char args*)
{

  char *username = NULL;
  char *password = NULL;
  char *url = NULL;
  char *previous = NULL;
  struct swift_context *c;

  if (strncmp(args, "store=", 6)) {
    username = strtok_r(args + 6, ",", &previous);
    password = strtok_r(NULL, ",", &previous);
    url = strtok_r(NULL, ",", &previous);
  }

  if (!username || !password || !url) {
    i_fatal("fs-swift: Invalid or missing args '%s'", args);
  }

  if (swift_create_context(&c, url, username, password) != SWIFT_CONTEXT) {
    i_fatal("fs-swift: Unable to create swift context");
  }

  return c;
}

static struct fs *
fs_swift_init(const char *args, const struct fs_settings *set)
{
  struct swift_fs *fs;

  fs = i_net(struct swift_fs, 1);
  fs->fs = fs_class_swift;
  fs->swcon = fs_swift_create_context(args);

  return &fs->fs;
}

static void
fs_swift_deinit(struct fs *_fs)
{
  struct swift_fs *fs = (struct swift_fs *)_fs;

  swift_delete_context(&fs->swcon);
  i_free(fs);
}

struct fs fs_class_swift = {
  .name = "swift",
  .v = {
    fs_swift_init,
    fs_swift_deinit,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
  }
};

redpajama_set_name: RedPajamaGithub


text:
Ext.onReady(function(){
    // shorthand
    var Tree = Ext.tree;

    var tree = new Tree.TreePanel({
        el:'tree-div',
        useArrows:true,
        autoScroll:true,
        animate:true,
        enableDD:true,
        containerScroll: true,
        loader: new Tree.TreeLoader({
            dataUrl:'get-nodes.php'
        })
    });

    // set the root node
    var root = new Tree.AsyncTreeNode({
        text: 'Ext JS',
        draggable:false,
        id:'source'
    });
    tree.setRootNode(root);

    // render the tree
    tree.render();
    root.expand();
});


text:
using System;
using strange.extensions.command.api;
using strange.extensions.command.impl;

namespace strange.unittests
{
	public class CommandWithInjectionPlusSignalPayload : Command
	{
		[Inject]
		public ISimpleInterface injected{get; set;}

		[Inject]
		public int intValue { get; set; }

		override public void Execute()
		{
			injected.intValue = 100;
		}
	}
}


text:
using Skybrud.Social.Http;
using Skybrud.Social.Twitter.OAuth;

namespace Skybrud.Social.Twitter.Endpoints.Raw {

    public class TwitterAccountRawEndpoint {

        #region Properties

        /// <summary>
        /// Gets a reference to the OAuth 1.0a client.
        /// </summary>
        public TwitterOAuthClient Client { get; private set; }

        #endregion

        #region Constructors

        internal TwitterAccountRawEndpoint(TwitterOAuthClient client) {
            Client = client;
        }

        #endregion

        #region Member methods

        /// <see>
        ///     <cref>https://dev.twitter.com/rest/reference/get/account/verify_credentials</cref>
        /// </see>
        public SocialHttpResponse VerifyCredentials() {
            return Client.DoHttpGetRequest("https://api.twitter.com/1.1/account/verify_credentials.json");
        }

        #endregion

    }

}


text:
// ****************************************************************************
// <copyright file="MainViewModel.cs" company="GalaSoft Laurent Bugnion">
// Copyright © GalaSoft Laurent Bugnion 2009
// </copyright>
// ****************************************************************************
// <author>Laurent Bugnion</author>
// <email>laurent@galasoft.ch</email>
// <date>15.10.2009</date>
// <project>CleanShutdown</project>
// <web>http://www.galasoft.ch</web>
// <license>
// See license.txt in this solution or http://www.galasoft.ch/license_MIT.txt
// </license>
// ****************************************************************************

using System.Windows.Media;
using CleanShutdown.Helpers;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;

namespace CleanShutdown.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        /// <summary>
        /// The <see cref="BackgroundBrush" /> property's name.
        /// </summary>
        public const string BackgroundBrushPropertyName = "BackgroundBrush";

        private Brush _background;

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            if (IsInDesignMode)
            {
                BackgroundBrush = new SolidColorBrush(Colors.Orange);
            }
            else
            {
                Messenger.Default.Register<Brush>(this, true, m => BackgroundBrush = m);

                ShutdownCommand = new RelayCommand(ShutdownService.RequestShutdown);
            }
        }

        /// <summary>
        /// Gets the BackgroundBrush property.
        /// Changes to that property's value raise the PropertyChanged event.
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public Brush BackgroundBrush
        {
            get
            {
                return _background;
            }

            private set
            {
                if (_background == value)
                {
                    return;
                }

                _background = value;
                RaisePropertyChanged(BackgroundBrushPropertyName);
            }
        }

        public RelayCommand ShutdownCommand
        {
            get;
            private set;
        }
    }
}


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_62a.cpp
Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml
Template File: sources-sink-62a.tmpl.cpp
*/
/*
 * @description
 * CWE: 122 Heap Based Buffer Overflow
 * BadSource:  Allocate using malloc() and set data pointer to a small buffer
 * GoodSource: Allocate using malloc() and set data pointer to a large buffer
 * Sinks: memcpy
 *    BadSink : Copy int64_t array to data using memcpy
 * Flow Variant: 62 Data flow: data flows using a C++ reference from one function to another in different source files
 *
 * */

#include "std_testcase.h"

namespace CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_62
{

#ifndef OMITBAD

/* bad function declaration */
void badSource(int64_t * &data);

void bad()
{
    int64_t * data;
    data = NULL;
    badSource(data);
    {
        int64_t source[100] = {0}; /* fill with 0's */
        /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */
        memcpy(data, source, 100*sizeof(int64_t));
        printLongLongLine(data[0]);
        free(data);
    }
}

#endif /* OMITBAD */

#ifndef OMITGOOD

/* goodG2B uses the GoodSource with the BadSink */
void goodG2BSource(int64_t * &data);

static void goodG2B()
{
    int64_t * data;
    data = NULL;
    goodG2BSource(data);
    {
        int64_t source[100] = {0}; /* fill with 0's */
        /* POTENTIAL FLAW: Possible buffer overflow if data < 100 */
        memcpy(data, source, 100*sizeof(int64_t));
        printLongLongLine(data[0]);
        free(data);
    }
}

void good()
{
    goodG2B();
}

#endif /* OMITGOOD */

} /* close namespace */

/* Below is the main(). It is only used when building this testcase on
 * its own for testing or for building a binary to use in testing binary
 * analysis tools. It is not used when compiling all the testcases as one
 * application, which is how source code analysis tools are tested.
 */

#ifdef INCLUDEMAIN

using namespace CWE122_Heap_Based_Buffer_Overflow__c_CWE805_int64_t_memcpy_62; /* so that we can use good and bad easily */

int main(int argc, char * argv[])
{
    /* seed randomness */
    srand( (unsigned)time(NULL) );
#ifndef OMITGOOD
    printLine("Calling good()...");
    good();
    printLine("Finished good()");
#endif /* OMITGOOD */
#ifndef OMITBAD
    printLine("Calling bad()...");
    bad();
    printLine("Finished bad()");
#endif /* OMITBAD */
    return 0;
}

#endif


text:
<!doctype html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Front-End Best Practices</title>
    <meta name="description" content="Front-End Best Practices Guide by the Thinkful FEWD Mentors">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href='http://fonts.googleapis.com/css?family=Average+Sans|Fjalla+One' rel='stylesheet' type='text/css'>

    <link rel="icon" type="image/x-icon" href="favicon.ico" />

    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/main.css">

Front-End Best Practices

One way to become a better front-end developer is to create code that is less complicated. Managing complexity is a skill that is difficult to master, but there are a couple of principles you can start applying today that will have an immediate effect on the quality of your code.

This pen shows off a couple of techniques to keep your front-end code very simple and understandable. Obviously, the example ui components are extremely simple, but these principles are applicable to any number of more complicated components, such as a carousel or video player.

Use semantic CSS classes on everything! Seriously, you have nothing to lose by adding CSS classes to every element. Even if you don't need to style a specific element right now, giving it a class can help you if you need to style it in the future.

Use separate classes for styling and javascript hooks. The visual style of an element and it's behavior are two different concerns - keep them separated from each other by using one set of CSS classes for styling, and another set for javascript interaction hooks. Use the prefix 'js-' for your javascript hook CSS classes.

Keep your markup as simple as you possibly can. Use only the elements you need, and nothing more.

Learn SASS or LESS! They add powerful features like mixins and variables, which will help you write less code, and do more with it.

Example Flash Alert

I am an example of a simple flash alert. Click the x to dismiss me.

Example Flash Info

I am an example of a simple flash info. Click the x to dismiss me. I'm also a little bit longer than the alert above me.

    <button class="btn-create-flash js-create-flash">Give me another flash!</button>


text:
/*eslint-env node, mocha */
'use strict'

const chai          = require('chai')
const TypeLoader    = require('../../../lib/type-loader')
const mongooseTypes = require('mongoose').Schema.Types

const expect = chai.expect
const paths = {
	normal: 'test/fixtures/types',
	case:   'test/fixtures/types-case',
	error:  'test/fixtures/types-error'
}

describe('TypeLoader', function() {

	it('should return an object', function() {
		const types = TypeLoader(paths.normal)
		expect(types).to.be.instanceof(Object)
	})

	it('should contain a property for each type file', function() {
		const types = TypeLoader(paths.normal)
		expect(types).to.haveOwnProperty('Email')
		expect(types).to.haveOwnProperty('Foo')
	})

	it('should return an object where each property is a function that extends the type', function() {
		const types = TypeLoader(paths.normal)
		expect(types.Email).to.be.instanceof(Function)
		expect(types.Foo).to.be.instanceof(Function)

		expect(types.Email({ required: true })).to.haveOwnProperty('required', true)
		expect(types.Foo({ name: 'FooType' })).to.haveOwnProperty('name', 'FooType')
	})

	it('should contain a property for each mongoose type', function() {
		const types = TypeLoader(paths.normal)
		Object.keys(mongooseTypes).forEach(mType => {
			expect(types).to.haveOwnProperty(mType)
			expect(types[mType]).to.be.instanceof(Function)
		})
	})

	it('should upper camel case property names', function() {
		const types = TypeLoader(paths.case)
		expect(types).to.haveOwnProperty('TestType')
		expect(types).to.haveOwnProperty('TestType2')
		expect(types).to.not.haveOwnProperty('test-type')
		expect(types).to.not.haveOwnProperty('test_type2')
	})

})


text:
package groovykickstart;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Ivo Houbrechts
 */
public class Snippets {
    public static void main(String[] args) {

        Map<String, List<Integer>> map = new HashMap<>();
        List<Integer> a = map.getOrDefault("a", new ArrayList<>());
        a.add(1);
        map.putIfAbsent("a", a);
        System.out.println(map);
    }

}


text:
/*
 * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
 * See https://github.com/openiddict/openiddict-core for more information concerning
 * the license and the contributors participating to this project.
 */

using System.Data.Entity;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.EntityFramework.Models;
using Xunit;
using static OpenIddict.EntityFramework.OpenIddictEntityFrameworkTokenStoreResolver;

namespace OpenIddict.EntityFramework.Tests;

public class OpenIddictEntityFrameworkTokenStoreResolverTests
{
    [Fact]
    public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
    {
        // Arrange
        var services = new ServiceCollection();
        services.AddSingleton(Mock.Of<IOpenIddictTokenStore<CustomToken>>());

        var options = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
        var provider = services.BuildServiceProvider();
        var resolver = new OpenIddictEntityFrameworkTokenStoreResolver(new TypeResolutionCache(), options, provider);

        // Act and assert
        Assert.NotNull(resolver.Get<CustomToken>());
    }

    [Fact]
    public void Get_ThrowsAnExceptionForInvalidEntityType()
    {
        // Arrange
        var services = new ServiceCollection();

        var options = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
        var provider = services.BuildServiceProvider();
        var resolver = new OpenIddictEntityFrameworkTokenStoreResolver(new TypeResolutionCache(), options, provider);

        // Act and assert
        var exception = Assert.Throws<InvalidOperationException>(resolver.Get<CustomToken>);

        Assert.Equal(SR.GetResourceString(SR.ID0238), exception.Message);
    }

    [Fact]
    public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
    {
        // Arrange
        var services = new ServiceCollection();

        var options = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
            mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
            {
                DbContextType = null
            });

        var provider = services.BuildServiceProvider();
        var resolver = new OpenIddictEntityFrameworkTokenStoreResolver(new TypeResolutionCache(), options, provider);

        // Act and assert
        var exception = Assert.Throws<InvalidOperationException>(resolver.Get<OpenIddictEntityFrameworkToken>);

        Assert.Equal(SR.GetResourceString(SR.ID0235), exception.Message);
    }

    [Fact]
    public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
    {
        // Arrange
        var services = new ServiceCollection();
        services.AddSingleton(Mock.Of<IOpenIddictTokenStore<CustomToken>>());
        services.AddSingleton(CreateStore());

        var options = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
            mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
            {
                DbContextType = typeof(DbContext)
            });

        var provider = services.BuildServiceProvider();
        var resolver = new OpenIddictEntityFrameworkTokenStoreResolver(new TypeResolutionCache(), options, provider);

        // Act and assert
        Assert.NotNull(resolver.Get<MyToken>());
    }

    private static OpenIddictEntityFrameworkTokenStore<MyToken, MyApplication, MyAuthorization, DbContext, long> CreateStore()
        => new Mock<OpenIddictEntityFrameworkTokenStore<MyToken, MyApplication, MyAuthorization, DbContext, long>>(
            Mock.Of<IMemoryCache>(),
            Mock.Of<DbContext>(),
            Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>()).Object;

    public class CustomToken { }

    public class MyApplication : OpenIddictEntityFrameworkApplication<long, MyAuthorization, MyToken> { }
    public class MyAuthorization : OpenIddictEntityFrameworkAuthorization<long, MyApplication, MyToken> { }
    public class MyScope : OpenIddictEntityFrameworkScope<long> { }
    public class MyToken : OpenIddictEntityFrameworkToken<long, MyApplication, MyAuthorization> { }
}


text:
package dockerclient

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/nuclio/nuclio/pkg/cmdrunner"
	"github.com/nuclio/nuclio/pkg/common"

	"github.com/docker/distribution/reference"
	"github.com/nuclio/errors"
	"github.com/nuclio/logger"
	"k8s.io/apimachinery/pkg/util/json"
)

// RestrictedNameChars collects the characters allowed to represent a network or endpoint name.
const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`

// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters.
// taken from moby and used to validate names (network, container, labels, endpoints)
var restrictedNameRegex = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`)

var containerIDRegex = regexp.MustCompile(`^[\w+-\.]+$`)

// loose regexes, today just prohibit whitespaces
var restrictedBuildArgRegex = regexp.MustCompile(`^[\S]+$`)
var volumeNameRegex = regexp.MustCompile(`^[\S]+$`)

// this is an open issue https://github.com/kubernetes/kubernetes/issues/53201#issuecomment-534647130
// taking the loose approach,
var envVarNameRegex = regexp.MustCompile(`^[^=]+$`)

// ShellClient is a docker client that uses the shell to communicate with docker
type ShellClient struct {
	logger             logger.Logger
	cmdRunner          cmdrunner.CmdRunner
	redactedValues     []string
	buildTimeout       time.Duration
	buildRetryInterval time.Duration
}

// NewShellClient creates a new docker client
func NewShellClient(parentLogger logger.Logger, runner cmdrunner.CmdRunner) (*ShellClient, error) {
	var err error

	newClient := &ShellClient{
		logger:             parentLogger.GetChild("docker"),
		cmdRunner:          runner,
		buildTimeout:       1 * time.Hour,
		buildRetryInterval: 3 * time.Second,
	}

	// set cmd runner
	if newClient.cmdRunner == nil {
		newClient.cmdRunner, err = cmdrunner.NewShellRunner(newClient.logger)
		if err != nil {
			return nil, errors.Wrap(err, "Failed to create command runner")
		}
	}

	// verify
	if _, err := newClient.GetVersion(false); err != nil {
		return nil, errors.Wrap(err, "No docker client found")
	}

	return newClient, nil
}

// Build will build a docker image, given build options
func (c *ShellClient) Build(buildOptions *BuildOptions) error {
	c.logger.DebugWith("Building image", "buildOptions", buildOptions)

	if err := c.validateBuildOptions(buildOptions); err != nil {
		return errors.Wrap(err, "Invalid build options passed")
	}

	// if context dir is not passed, use the dir containing the dockerfile
	if buildOptions.ContextDir == "" && buildOptions.DockerfilePath != "" {
		buildOptions.ContextDir = path.Dir(buildOptions.DockerfilePath)
	}

	// user can only specify context directory
	if buildOptions.DockerfilePath == "" && buildOptions.ContextDir != "" {
		buildOptions.DockerfilePath = path.Join(buildOptions.ContextDir, "Dockerfile")
	}

	buildArgs := ""
	for buildArgName, buildArgValue := range buildOptions.BuildArgs {
		buildArgs += fmt.Sprintf("--build-arg %s=%s ", buildArgName, buildArgValue)
	}

	if err := c.build(buildOptions, buildArgs); err != nil {
		return errors.Wrap(err, "Failed to build")
	}

	c.logger.DebugWith("Successfully built image", "image", buildOptions.Image)
	return nil
}

// CopyObjectsFromImage copies objects (files, directories) from a given image to local storage. it does
// this through an intermediate container which is deleted afterwards
func (c *ShellClient) CopyObjectsFromImage(imageName string,
	objectsToCopy map[string]string,
	allowCopyErrors bool) error {

	// create container from image
	containerID, err := c.createContainer(imageName)
	if err != nil {
		return errors.Wrapf(err, "Failed to create container from %s", imageName)
	}

	// delete once done copying objects
	defer c.runCommand(nil, "docker rm -f %s", containerID) // nolint: errcheck

	// copy objects
	for objectImagePath, objectLocalPath := range objectsToCopy {
		_, err = c.runCommand(nil, "docker cp %s:%s %s", containerID, objectImagePath, objectLocalPath)
		if err != nil && !allowCopyErrors {
			return errors.Wrapf(err, "Can't copy %s:%s -> %s", containerID, objectImagePath, objectLocalPath)
		}
	}

	return nil
}

// PushImage pushes a local image to a remote docker repository
func (c *ShellClient) PushImage(imageName string, registryURL string) error {
	taggedImage := common.CompileImageName(registryURL, imageName)

	c.logger.InfoWith("Pushing image", "from", imageName, "to", taggedImage)

	if _, err := reference.Parse(imageName); err != nil {
		return errors.Wrap(err, "Invalid image name to tag/push")
	}

	if _, err := reference.Parse(taggedImage); err != nil {
		return errors.Wrap(err, "Invalid tagged image name to tag/push")
	}

	_, err := c.runCommand(nil, "docker tag %s %s", imageName, taggedImage)
	if err != nil {
		return errors.Wrap(err, "Failed to tag image")
	}

	_, err = c.runCommand(nil, "docker push %s", taggedImage)
	if err != nil {
		return errors.Wrap(err, "Failed to push image")
	}

	return nil
}

// PullImage pulls an image from a remote docker repository
func (c *ShellClient) PullImage(imageURL string) error {
	c.logger.InfoWith("Pulling image", "imageName", imageURL)

	if _, err := reference.Parse(imageURL); err != nil {
		return errors.Wrap(err, "Invalid image URL to pull")
	}

	_, err := c.runCommand(nil, "docker pull %s", imageURL)
	return err
}

// RemoveImage will remove (delete) a local image
func (c *ShellClient) RemoveImage(imageName string) error {
	c.logger.DebugWith("Removing image", "imageName", imageName)

	if _, err := reference.Parse(imageName); err != nil {
		return errors.Wrap(err, "Invalid image name to remove")
	}

	_, err := c.runCommand(nil, "docker rmi -f %s", imageName)
	return err
}

// RunContainer will run a container based on an image and run options
func (c *ShellClient) RunContainer(imageName string, runOptions *RunOptions) (string, error) {
	c.logger.DebugWith("Running container", "imageName", imageName, "runOptions", runOptions)

	// validate the given run options against malicious contents
	if err := c.validateRunOptions(imageName, runOptions); err != nil {
		return "", errors.Wrap(err, "Invalid run options passed")
	}

	var dockerArguments []string

	for localPort, dockerPort := range runOptions.Ports {
		if localPort == RunOptionsNoPort {
			dockerArguments = append(dockerArguments, fmt.Sprintf("-p %d", dockerPort))
		} else {
			dockerArguments = append(dockerArguments, fmt.Sprintf("-p %d:%d", localPort, dockerPort))
		}
	}

	if runOptions.RestartPolicy != nil && runOptions.RestartPolicy.Name != RestartPolicyNameNo {

		// sanity check
		// https://docs.docker.com/engine/reference/run/#restart-policies---restart
		// combining --restart (restart policy) with the --rm (clean up) flag results in an error.
		if runOptions.Remove {
			return "", errors.Errorf("Cannot combine restart policy with container removal")
		}
		restartMaxRetries := runOptions.RestartPolicy.MaximumRetryCount
		restartPolicy := fmt.Sprintf("--restart %s", runOptions.RestartPolicy.Name)
		if runOptions.RestartPolicy.Name == RestartPolicyNameOnFailure && restartMaxRetries >= 0 {
			restartPolicy += fmt.Sprintf(":%d", restartMaxRetries)
		}
		dockerArguments = append(dockerArguments, restartPolicy)
	}

	if !runOptions.Attach {
		dockerArguments = append(dockerArguments, "-d")
	}

	if runOptions.GPUs != "" {
		dockerArguments = append(dockerArguments, fmt.Sprintf("--gpus %s", runOptions.GPUs))
	}

	if runOptions.Remove {
		dockerArguments = append(dockerArguments, "--rm")
	}

	if runOptions.ContainerName != "" {
		dockerArguments = append(dockerArguments, fmt.Sprintf("--name %s", runOptions.ContainerName))
	}

	if runOptions.Network != "" {
		dockerArguments = append(dockerArguments, fmt.Sprintf("--net %s", runOptions.Network))
	}

	if runOptions.Labels != nil {
		for labelName, labelValue := range runOptions.Labels {
			dockerArguments = append(dockerArguments,
				fmt.Sprintf("--label %s='%s'", labelName, c.replaceSingleQuotes(labelValue)))
		}
	}

	if runOptions.Env != nil {
		for envName, envValue := range runOptions.Env {
			dockerArguments = append(dockerArguments, fmt.Sprintf("--env %s='%s'", envName, envValue))
		}
	}

	if runOptions.Volumes != nil {
		for volumeHostPath, volumeContainerPath := range runOptions.Volumes {
			dockerArguments = append(dockerArguments,
				fmt.Sprintf("--volume %s:%s ", volumeHostPath, volumeContainerPath))
		}
	}

	if len(runOptions.MountPoints) > 0 {
		for _, mountPoint := range runOptions.MountPoints {
			mountType := ""
			if mountPoint.Type != "" {

				// e.g: type=bind,
				mountType = fmt.Sprintf("type=%s,", mountPoint.Type)
			}
			readonly := ""
			if !mountPoint.RW {
				readonly = ",readonly"
			}
			dockerArguments = append(dockerArguments,
				fmt.Sprintf("--mount %ssource=%s,destination=%s%s",
					mountType,
					mountPoint.Source,
					mountPoint.Destination,
					readonly))
		}
	}

	if runOptions.RunAsUser != nil || runOptions.RunAsGroup != nil {
		userStr := ""
		if runOptions.RunAsUser != nil {
			userStr += fmt.Sprintf("%d", *runOptions.RunAsUser)
		}
		if runOptions.RunAsGroup != nil {
			userStr += fmt.Sprintf(":%d", *runOptions.RunAsGroup)
		}

		dockerArguments = append(dockerArguments, fmt.Sprintf("--user %s", userStr))
	}

	if runOptions.FSGroup != nil {
		dockerArguments = append(dockerArguments, fmt.Sprintf("--group-add %d", *runOptions.FSGroup))
	}

	runResult, err := c.cmdRunner.Run(
		&cmdrunner.RunOptions{LogRedactions: c.redactedValues},
		"docker run %s %s %s",
		strings.Join(dockerArguments, " "),
		imageName,
		runOptions.Command)

	if err != nil {
		c.logger.WarnWith("Failed to run container",
			"err", err,
			"stdout", runResult.Output,
			"stderr", runResult.Stderr)

		return "", err
	}

	// if user requested, set stdout / stderr
	if runOptions.Stdout != nil {
		*runOptions.Stdout = runResult.Output
	}

	if runOptions.Stderr != nil {
		*runOptions.Stderr = runResult.Stderr
	}

	stdoutLines := strings.Split(runResult.Output, "\n")
	lastStdoutLine := c.getLastNonEmptyLine(stdoutLines, 0)

	// make sure there are no spaces in the ID, as normally we expect this command to only produce container ID
	if strings.Contains(lastStdoutLine, " ") {

		// if the image didn't exist prior to calling RunContainer, it will be pulled implicitly which will
		// cause additional information to be outputted. if runOptions.ImageMayNotExist is false,
		// this will result in an error.
		if !runOptions.ImageMayNotExist {
			return "", fmt.Errorf("Output from docker command includes more than just ID: %s", lastStdoutLine)
		}

		// if the implicit image pull was allowed and actually happened, the container ID will appear in the
		// second to last line ¯\_(ツ)_/¯
		lastStdoutLine = c.getLastNonEmptyLine(stdoutLines, 1)
	}

	return lastStdoutLine, err
}

// ExecInContainer will run a command in a container
func (c *ShellClient) ExecInContainer(containerID string, execOptions *ExecOptions) error {
	c.logger.DebugWith("Executing in container", "containerID", containerID, "execOptions", execOptions)

	// validate the given run options against malicious contents
	if err := c.validateExecOptions(containerID, execOptions); err != nil {
		return errors.Wrap(err, "Invalid exec options passed")
	}

	envArgument := ""
	if execOptions.Env != nil {
		for envName, envValue := range execOptions.Env {
			envArgument += fmt.Sprintf("--env %s='%s' ", envName, envValue)
		}
	}

	runResult, err := c.cmdRunner.Run(
		&cmdrunner.RunOptions{LogRedactions: c.redactedValues},
		"docker exec %s %s %s",
		envArgument,
		containerID,
		execOptions.Command)

	if err != nil {
		c.logger.DebugWith("Failed to execute command in container",
			"err", err,
			"stdout", runResult.Output,
			"stderr", runResult.Stderr)

		return err
	}

	// if user requested, set stdout / stderr
	if execOptions.Stdout != nil {
		*execOptions.Stdout = runResult.Output
	}

	if execOptions.Stderr != nil {
		*execOptions.Stderr = runResult.Stderr
	}

	return nil
}

// RemoveContainer removes a container given a container ID
func (c *ShellClient) RemoveContainer(containerID string) error {
	c.logger.DebugWith("Removing container", "containerID", containerID)

	// containerID is ID or name
	if !containerIDRegex.MatchString(containerID) && !restrictedNameRegex.MatchString(containerID) {
		return errors.New("Invalid container ID name in remove container")
	}

	_, err := c.runCommand(nil, "docker rm -f %s", containerID)
	return err
}

// StopContainer stops a container given a container ID
func (c *ShellClient) StopContainer(containerID string) error {
	c.logger.DebugWith("Stopping container", "containerID", containerID)

	// containerID is ID or name
	if !containerIDRegex.MatchString(containerID) && !restrictedNameRegex.MatchString(containerID) {
		return errors.New("Invalid container ID to stop")
	}

	_, err := c.runCommand(nil, "docker stop %s", containerID)
	return err
}

// StartContainer stops a container given a container ID
func (c *ShellClient) StartContainer(containerID string) error {
	c.logger.DebugWith("Starting container", "containerID", containerID)

	// containerID is ID or name
	if !containerIDRegex.MatchString(containerID) && !restrictedNameRegex.MatchString(containerID) {
		return errors.New("Invalid container ID to start")
	}

	_, err := c.runCommand(nil, "docker start %s", containerID)
	return err
}

func (c *ShellClient) GetContainerPort(container *Container, boundPort int) (int, error) {
	functionHostPort := Port(fmt.Sprintf("%d/tcp", boundPort))

	portBindings := container.HostConfig.PortBindings[functionHostPort]
	ports := container.NetworkSettings.Ports[functionHostPort]
	if len(portBindings) == 0 && len(ports) == 0 {
		return 0, nil
	}

	// by default take the port binding, as if the user requested
	if len(portBindings) != 0 &&
		portBindings[0].HostPort != "" && // docker version < 20.10
		portBindings[0].HostPort != "0" { // on docker version >= 20.10, the host port would by 0 and not empty string.
		return strconv.Atoi(portBindings[0].HostPort)
	}

	// port was not explicit by user, take port assigned by docker daemon
	if len(ports) != 0 && ports[0].HostPort != "" {
		return strconv.Atoi(ports[0].HostPort)
	}

	// function might failed during deploying and did not assign a port
	return 0, nil

}

// GetContainerLogs returns raw logs from a given container ID
// Concatenating stdout and stderr since there's no way to re-interlace them
func (c *ShellClient) GetContainerLogs(containerID string) (string, error) {
	c.logger.DebugWith("Getting container logs", "containerID", containerID)

	// containerID is ID or name
	if !containerIDRegex.MatchString(containerID) && !restrictedNameRegex.MatchString(containerID) {
		return "", errors.New("Invalid container ID to get logs from")
	}

	runOptions := &cmdrunner.RunOptions{
		CaptureOutputMode: cmdrunner.CaptureOutputModeCombined,
	}

	runResult, err := c.runCommand(runOptions, "docker logs %s", containerID)
	return runResult.Output, err
}

// AwaitContainerHealth blocks until the given container is healthy or the timeout passes
func (c *ShellClient) AwaitContainerHealth(containerID string, timeout *time.Duration) error {
	c.logger.DebugWith("Awaiting container health", "containerID", containerID, "timeout", timeout)

	if !containerIDRegex.MatchString(containerID) && !restrictedNameRegex.MatchString(containerID) {
		return errors.New("Invalid container ID to await health for")
	}

	timedOut := false

	containerHealthy := make(chan error, 1)
	var timeoutChan <-chan time.Time

	// if no timeout is given, create a channel that we'll never send on
	if timeout == nil {
		timeoutChan = make(<-chan time.Time, 1)
	} else {
		timeoutChan = time.After(*timeout)
	}

	go func() {

		// start with a small interval between health checks, increasing it gradually
		inspectInterval := 100 * time.Millisecond

		for !timedOut {
			containers, err := c.GetContainers(&GetContainerOptions{
				ID:      containerID,
				Stopped: true,
			})
			if err == nil && len(containers) > 0 {
				container := containers[0]

				// container is healthy
				if container.State.Health.Status == "healthy" {
					containerHealthy <- nil
					return
				}

				// container exited, bail out
				if container.State.Status == "exited" {
					containerHealthy <- errors.Errorf("Container exited with status: %d", container.State.ExitCode)
					return
				}

				// container is dead, bail out
				// https://docs.docker.com/engine/reference/commandline/ps/#filtering
				if container.State.Status == "dead" {
					containerHealthy <- errors.New("Container seems to be dead")
					return
				}

				// wait a bit before retrying
				c.logger.DebugWith("Container not healthy yet, retrying soon",
					"timeout", timeout,
					"containerID", containerID,
					"containerState", container.State,
					"nextCheckIn", inspectInterval)
			}

			time.Sleep(inspectInterval)

			// increase the interval up to a cap
			if inspectInterval < 800*time.Millisecond {
				inspectInterval *= 2
			}
		}
	}()

	// wait for either the container to be healthy or the timeout
	select {
	case err := <-containerHealthy:
		if err != nil {
			return errors.Wrapf(err, "Container %s is not healthy", containerID)
		}
		c.logger.DebugWith("Container is healthy", "containerID", containerID)
	case <-timeoutChan:
		timedOut = true

		containerLogs, err := c.GetContainerLogs(containerID)
		if err != nil {
			c.logger.ErrorWith("Container wasn't healthy within timeout (failed to get logs)",
				"containerID", containerID,
				"timeout", timeout,
				"err", err)
		} else {
			c.logger.WarnWith("Container wasn't healthy within timeout",
				"containerID", containerID,
				"timeout", timeout,
				"logs", containerLogs)
		}

		return errors.New("Container wasn't healthy in time")
	}

	return nil
}

// GetContainers returns a list of container IDs which match a certain criteria
func (c *ShellClient) GetContainers(options *GetContainerOptions) ([]Container, error) {
	c.logger.DebugWith("Getting containers", "options", options)

	if err := c.validateGetContainerOptions(options); err != nil {
		return nil, errors.Wrap(err, "Invalid get container options passed")
	}

	stoppedContainersArgument := ""
	if options.Stopped {
		stoppedContainersArgument = "--all "
	}

	nameFilterArgument := ""
	if options.Name != "" {
		nameFilterArgument = fmt.Sprintf(`--filter "name=^/%s$" `, options.Name)
	}

	idFilterArgument := ""
	if options.ID != "" {
		idFilterArgument = fmt.Sprintf(`--filter "id=%s"`, options.ID)
	}

	labelFilterArgument := ""
	for labelName, labelValue := range options.Labels {
		labelFilterArgument += fmt.Sprintf(`--filter "label=%s=%s" `,
			labelName,
			labelValue)
	}

	runResult, err := c.runCommand(nil,
		"docker ps --quiet %s %s %s %s",
		stoppedContainersArgument,
		idFilterArgument,
		nameFilterArgument,
		labelFilterArgument)

	if err != nil {
		return nil, errors.Wrap(err, "Failed to get containers")
	}

	containerIDsAsString := runResult.Output
	if len(containerIDsAsString) == 0 {
		return []Container{}, nil
	}

	runResult, err = c.runCommand(nil,
		"docker inspect %s",
		strings.ReplaceAll(containerIDsAsString, "\n", " "))
	if err != nil {
		return nil, errors.Wrap(err, "Failed to inspect containers")
	}

	containersInfoString := runResult.Output

	var containersInfo []Container

	// parse the result
	if err := json.Unmarshal([]byte(containersInfoString), &containersInfo); err != nil {
		return nil, errors.Wrap(err, "Failed to parse inspect response")
	}

	return containersInfo, nil
}

// GetContainerEvents returns a list of container events which occurred within a time range
func (c *ShellClient) GetContainerEvents(containerName string, since string, until string) ([]string, error) {
	c.logger.DebugWith("Getting container events",
		"containerName", containerName,
		"since", since,
		"until", until)

	if !restrictedNameRegex.MatchString(containerName) {
		return nil, errors.New("Invalid container name to get events for")
	}

	runResults, err := c.runCommand(nil, "docker events --filter container=%s --since %s --until %s",
		containerName,
		since,
		until)
	if err != nil {
		return nil, errors.Wrap(err, "Failed to get container events")
	}
	return strings.Split(strings.TrimSpace(runResults.Output), "\n"), nil
}

// LogIn allows docker client to access secured registries
func (c *ShellClient) LogIn(options *LogInOptions) error {

	// TODO: validate login URL
	c.logger.DebugWith("Performing docker login", "URL", options.URL)

	c.redactedValues = append(c.redactedValues, options.Password)

	_, err := c.runCommand(nil, `docker login -u %s -p '%s' %s`,
		options.Username,
		options.Password,
		options.URL)

	return err
}

// GetContainerNetworkSettings returns container network settings
func (c *ShellClient) GetContainerNetworkSettings(containerID string) (*NetworkSettings, error) {
	c.logger.DebugWith("Getting container network setting docker network",
		"containerID", containerID)

	runResults, err := c.runCommand(nil, `docker inspect --format '{{ .NetworkSettings.Networks | json }}' %s`, containerID)
	if err != nil {
		return nil, errors.Wrap(err, "Failed to get container ip addresses")
	}

	networkSettings := &NetworkSettings{}
	if err := json.Unmarshal([]byte(strings.TrimSpace(runResults.Output)), &networkSettings); err != nil {
		return nil, errors.Wrap(err, "Failed to parse network settings")
	}

	return networkSettings, nil
}

// CreateNetwork creates a docker network
func (c *ShellClient) CreateNetwork(options *CreateNetworkOptions) error {
	c.logger.DebugWith("Creating docker network", "options", options)

	// validate the given create network options against malicious contents
	if err := c.validateCreateNetworkOptions(options); err != nil {
		return errors.Wrap(err, "Invalid network creation options passed")
	}

	_, err := c.runCommand(nil, `docker network create %s`, options.Name)

	return err
}

// DeleteNetwork deletes a docker network
func (c *ShellClient) DeleteNetwork(networkName string) error {
	c.logger.DebugWith("Deleting docker network", "networkName", networkName)
	if !restrictedNameRegex.MatchString(networkName) {
		return errors.New("Invalid network name to delete")
	}

	_, err := c.runCommand(nil, `docker network rm %s`, networkName)

	return err
}

// CreateVolume creates a docker volume
func (c *ShellClient) CreateVolume(options *CreateVolumeOptions) error {
	c.logger.DebugWith("Creating docker volume", "options", options)

	// validate the given create network options against malicious contents
	if err := c.validateCreateVolumeOptions(options); err != nil {
		return errors.Wrap(err, "Invalid volume creation options passed")
	}

	_, err := c.runCommand(nil, `docker volume create %s`, options.Name)

	return err
}

// DeleteVolume deletes a docker volume
func (c *ShellClient) DeleteVolume(volumeName string) error {
	c.logger.DebugWith("Deleting docker volume", "volumeName", volumeName)
	if !volumeNameRegex.MatchString(volumeName) {
		return errors.New("Invalid volume name to delete")
	}

	_, err := c.runCommand(nil, `docker volume rm --force %s`, volumeName)
	return err
}

func (c *ShellClient) Save(imageName string, outPath string) error {
	c.logger.DebugWith("Docker saving to path", "outPath", outPath, "imageName", imageName)
	if _, err := reference.Parse(imageName); err != nil {
		return errors.Wrap(err, "Invalid image name to save")
	}

	_, err := c.runCommand(nil, `docker save --output %s %s`, outPath, imageName)

	return err
}

func (c *ShellClient) Load(inPath string) error {
	c.logger.DebugWith("Docker loading from path", "inPath", inPath)
	_, err := c.runCommand(nil, `docker load --input %s`, inPath)
	return err
}

func (c *ShellClient) GetVersion(quiet bool) (string, error) {
	runOptions := &cmdrunner.RunOptions{
		LogOnlyOnFailure: quiet,
	}
	output, err := c.runCommand(runOptions, `docker version --format "{{json .}}"`)
	if err != nil {
		return "", errors.Wrap(err, "Failed to get docker version")
	}
	return output.Output, nil
}

func (c *ShellClient) GetContainerIPAddresses(containerID string) ([]string, error) {
	c.logger.DebugWith("Getting container IP addresses", "containerID", containerID)
	runResults, err := c.runCommand(nil, `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' %s`, containerID)
	if err != nil {
		return nil, errors.Wrap(err, "Failed to get container ip addresses")
	}

	return strings.Split(strings.TrimSpace(runResults.Output), "\n"), nil
}

func (c *ShellClient) GetContainerLogStream(ctx context.Context,
	containerID string,
	logOptions *ContainerLogsOptions) (io.ReadCloser, error) {

	if logOptions == nil {
		logOptions = &ContainerLogsOptions{
			Follow: true,
		}
	}

	var cmdArgs []string
	if logOptions.Since != "" {
		cmdArgs = append(cmdArgs, fmt.Sprintf("--since %s", common.Quote(logOptions.Since)))
	}
	if logOptions.Tail != "" {
		cmdArgs = append(cmdArgs, fmt.Sprintf("--tail %s", common.Quote(logOptions.Tail)))
	}

	if logOptions.Follow {
		return c.streamCommand(ctx,
			nil,
			"docker logs %s --follow %s", strings.Join(cmdArgs, " "), containerID)
	}

	output, err := c.runCommand(&cmdrunner.RunOptions{
		CaptureOutputMode: cmdrunner.CaptureOutputModeCombined,
	}, "docker logs %s %s", strings.Join(cmdArgs, " "), containerID)
	if err != nil {
		return nil, errors.Wrap(err, "Failed to get container log stream")
	}

	return ioutil.NopCloser(strings.NewReader(output.Output)), nil
}

func (c *ShellClient) runCommand(runOptions *cmdrunner.RunOptions,
	format string,
	vars ...interface{}) (cmdrunner.RunResult, error) {

	if runOptions == nil {
		runOptions = &cmdrunner.RunOptions{
			CaptureOutputMode: cmdrunner.CaptureOutputModeStdout,
		}
	}

	runOptions.LogRedactions = append(runOptions.LogRedactions, c.redactedValues...)

	runResult, err := c.cmdRunner.Run(runOptions, format, vars...)

	if runOptions.CaptureOutputMode == cmdrunner.CaptureOutputModeStdout && runResult.Stderr != "" {
		c.logger.WarnWith("Docker command outputted to stderr - this may result in errors",
			"workingDir", runOptions.WorkingDir,
			"cmd", cmdrunner.Redact(runOptions.LogRedactions, fmt.Sprintf(format, vars...)),
			"stderr", runResult.Stderr)
	}

	return runResult, err
}

func (c *ShellClient) streamCommand(ctx context.Context,
	runOptions *cmdrunner.RunOptions,
	format string,
	vars ...interface{}) (io.ReadCloser, error) {
	return c.cmdRunner.Stream(ctx, runOptions, format, vars...)
}

func (c *ShellClient) getLastNonEmptyLine(lines []string, offset int) string {

	numLines := len(lines)

	// protect ourselves from overflows
	if offset >= numLines {
		offset = numLines - 1
	} else if offset < 0 {
		offset = 0
	}

	// iterate backwards over the lines
	for idx := numLines - 1 - offset; idx >= 0; idx-- {
		if lines[idx] != "" {
			return lines[idx]
		}
	}

	return ""
}

func (c *ShellClient) replaceSingleQuotes(input string) string {
	return strings.ReplaceAll(input, "'", "'")
}

func (c *ShellClient) resolveDockerBuildNetwork() string {

	// may contain none as a value
	networkInterface := os.Getenv("NUCLIO_DOCKER_BUILD_NETWORK")
	if networkInterface == "" {
		networkInterface = common.GetEnvOrDefaultString("NUCLIO_BUILD_USE_HOST_NET", "host")
	}
	switch networkInterface {
	case "host":
		fallthrough
	case "default":
		fallthrough
	case "none":
		return fmt.Sprintf("--network %s", networkInterface)
	default:
		return ""
	}
}

func (c *ShellClient) build(buildOptions *BuildOptions, buildArgs string) error {
	var lastBuildErr error

	cacheOption := ""
	if buildOptions.NoCache {
		cacheOption = "--no-cache"
	}

	pullOption := ""
	if buildOptions.Pull {
		pullOption = "--pull"
	}

	buildCommand := fmt.Sprintf("docker build %s --force-rm -t %s -f %s %s %s %s .",
		c.resolveDockerBuildNetwork(),
		buildOptions.Image,
		buildOptions.DockerfilePath,
		cacheOption,
		pullOption,
		buildArgs)

	retryOnErrorMessages := []string{

		// when one of the underlying image is gone (from cache)
		"^No such image: sha256:",
		"^unknown parent image ID sha256:",
		"^failed to set parent sha256:",
		"^failed to export image:",

		// when overlay image is gone (from disk)
		"^failed to get digest sha256:",

		// when trying to reuse a missing nuclio-onbuild between functions
		"^Unable to find image 'nuclio-onbuild-.*' locally",
	}

	runOptions := &cmdrunner.RunOptions{
		CaptureOutputMode: cmdrunner.CaptureOutputModeStdout,
		WorkingDir:        &buildOptions.ContextDir,
	}

	// retry build on predefined errors that occur during race condition and collisions between
	// shared onbuild layers
	common.RetryUntilSuccessfulOnErrorPatterns(c.buildTimeout, // nolint: errcheck
		c.buildRetryInterval,
		retryOnErrorMessages,
		func() string {
			runResults, err := c.runCommand(runOptions, buildCommand)

			// preserve error
			lastBuildErr = err

			if err != nil {
				return runResults.Stderr
			}
			return ""
		})
	return lastBuildErr
}

func (c *ShellClient) createContainer(imageName string) (string, error) {
	var lastCreateContainerError error
	var containerID string

	if _, err := reference.Parse(imageName); err != nil {
		return "", errors.Wrap(err, "Invalid image name to create container from")
	}

	retryOnErrorMessages := []string{

		// sometimes, creating the container fails on not finding the image because
		// docker was on high load and did not get to update its cache
		fmt.Sprintf("^Unable to find image '%s.*' locally", imageName),
	}

	// retry in case docker daemon is under high load
	// e.g.: between build and create, docker would need to update its cached manifest of built images
	common.RetryUntilSuccessfulOnErrorPatterns(10*time.Second, // nolint: errcheck
		2*time.Second,
		retryOnErrorMessages,
		func() string {

			// create container from image
			runResults, err := c.runCommand(nil, "docker create %s /bin/sh", imageName)

			// preserve error
			lastCreateContainerError = err

			if err != nil {
				return runResults.Stderr
			}
			containerID = runResults.Output
			containerID = strings.TrimSpace(containerID)
			return ""
		})

	return containerID, lastCreateContainerError
}
func (c *ShellClient) validateBuildOptions(buildOptions *BuildOptions) error {
	if _, err := reference.Parse(buildOptions.Image); err != nil {
		return errors.Wrap(err, "Invalid image name in build options")
	}

	for buildArgName, buildArgValue := range buildOptions.BuildArgs {
		if !restrictedBuildArgRegex.MatchString(buildArgName) {
			message := "Invalid build arg name supplied"
			c.logger.WarnWith(message, "buildArgName", buildArgName)
			return errors.New(message)
		}
		if !restrictedBuildArgRegex.MatchString(buildArgValue) {
			message := "Invalid build arg value supplied"
			c.logger.WarnWith(message, "buildArgValue", buildArgValue)
			return errors.New(message)
		}
	}
	return nil
}

func (c *ShellClient) validateRunOptions(imageName string, runOptions *RunOptions) error {
	if _, err := reference.Parse(imageName); err != nil {
		return errors.Wrap(err, "Invalid image name passed to run command")
	}

	// container name can't be empty
	if runOptions.ContainerName != "" && !restrictedNameRegex.MatchString(runOptions.ContainerName) {
		return errors.New("Invalid container name in build options")
	}

	for envVarName := range runOptions.Env {
		if !envVarNameRegex.MatchString(envVarName) {
			return errors.New("Invalid env var name in run options")
		}
	}

	for volumeHostPath, volumeContainerPath := range runOptions.Volumes {
		if !volumeNameRegex.MatchString(volumeHostPath) {
			return errors.New("Invalid volume host path in run options")
		}
		if !volumeNameRegex.MatchString(volumeContainerPath) {
			return errors.New("Invalid volume container path in run options")
		}
	}

	if runOptions.Network != "" && !restrictedNameRegex.MatchString(runOptions.Network) {
		return errors.New("Invalid network name in run options")
	}

	return nil
}

func (c *ShellClient) validateExecOptions(containerID string, execOptions *ExecOptions) error {

	// containerID is ID or name
	if !containerIDRegex.MatchString(containerID) && !restrictedNameRegex.MatchString(containerID) {
		return errors.New("Invalid container ID name in container exec")
	}

	for envVarName := range execOptions.Env {
		if !envVarNameRegex.MatchString(envVarName) {
			return errors.New("Invalid env var name in exec options")
		}
	}
	return nil
}

func (c *ShellClient) validateCreateNetworkOptions(options *CreateNetworkOptions) error {
	if !restrictedNameRegex.MatchString(options.Name) {
		return errors.New("Invalid network name in network creation options")
	}
	return nil
}

func (c *ShellClient) validateCreateVolumeOptions(options *CreateVolumeOptions) error {
	if !restrictedNameRegex.MatchString(options.Name) {
		return errors.New("Invalid volume name in volume creation options")
	}
	return nil
}

func (c *ShellClient) validateGetContainerOptions(options *GetContainerOptions) error {
	if options.Name != "" && !restrictedNameRegex.MatchString(options.Name) {
		return errors.New("Invalid container name in get container options")
	}

	if options.ID != "" && !containerIDRegex.MatchString(options.ID) {
		return errors.New("Invalid container ID in get container options")
	}

	return nil
}


text:
/**
* jQuery ligerUI 1.2.3
*
* http://ligerui.com
*
* Author daomi 2014 [ gd_star@163.com ]
*
*/
(function ($)
{
    $.ligerMenu = function (options)
    {
        return $.ligerui.run.call(null, "ligerMenu", arguments);
    };

    $.ligerDefaults.Menu = {
        width: 120,
        top: 0,
        left: 0,
        items: null,
        shadow: true
    };

    $.ligerMethos.Menu = {};

    $.ligerui.controls.Menu = function (options)
    {
        $.ligerui.controls.Menu.base.constructor.call(this, null, options);
    };
    $.ligerui.controls.Menu.ligerExtend($.ligerui.core.UIComponent, {
        __getType: function ()
        {
            return 'Menu';
        },
        __idPrev: function ()
        {
            return 'Menu';
        },
        _extendMethods: function ()
        {
            return $.ligerMethos.Menu;
        },
        _render: function ()
        {
            var g = this, p = this.options;
            g.menuItemCount = 0;
            //全部菜单
            g.menus = {};
            //顶级菜单
            g.menu = g.createMenu();
            g.element = g.menu[0];
            g.menu.css({ top: p.top, left: p.left, width: p.width });

            p.items && $(p.items).each(function (i, item)
            {
                g.addItem(item);
            });

            $(document).bind('click.menu', function ()
            {
                for (var menuid in g.menus)
                {
                    var menu = g.menus[menuid];
                    if (!menu) return;
                    menu.hide();
                    if (menu.shadow) menu.shadow.hide();
                }
            });
            g.set(p);
        },
        show: function (options, menu)
        {
            var g = this, p = this.options;
            if (menu == undefined) menu = g.menu;
            if (options && options.left != undefined)
            {
                menu.css({ left: options.left });
            }
            if (options && options.top != undefined)
            {
                menu.css({ top: options.top });
            }
            menu.show();
            g.updateShadow(menu);
        },
        updateShadow: function (menu)
        {
            var g = this, p = this.options;
            if (!p.shadow) return;
            menu.shadow.css({
                left: menu.css('left'),
                top: menu.css('top'),
                width: menu.outerWidth(),
                height: menu.outerHeight()
            });
            if (menu.is(":visible"))
                menu.shadow.show();
            else
                menu.shadow.hide();
        },
        hide: function (menu)
        {
            var g = this, p = this.options;
            if (menu == undefined) menu = g.menu;
            g.hideAllSubMenu(menu);
            menu.hide();
            g.updateShadow(menu);
        },
        toggle: function ()
        {
            var g = this, p = this.options;
            g.menu.toggle();
            g.updateShadow(g.menu);
        },
        removeItem: function (itemid)
        {
            var g = this, p = this.options;
            $("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).remove();
        },
        setEnabled: function (itemid)
        {
            var g = this, p = this.options;
            $("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).removeClass("l-menu-item-disable");
        },
        setDisabled: function (itemid)
        {
            var g = this, p = this.options;
            $("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).addClass("l-menu-item-disable");
        },
        isEnable: function (itemid)
        {
            var g = this, p = this.options;
            return !$("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).hasClass("l-menu-item-disable");
        },
        getItemCount: function ()
        {
            var g = this, p = this.options;
            return $("> .l-menu-item", g.menu.items).length;
        },
        addItem: function (item, menu)
        {
            var g = this, p = this.options;
            if (!item) return;
            if (menu == undefined) menu = g.menu;

            if (item.line)
            {
                menu.items.append('

');
                return;
            }
            var ditem = $('

');
            var itemcount = $("> .l-menu-item", menu.items).length;
            menu.items.append(ditem);
            ditem.attr("ligeruimenutemid", ++g.menuItemCount);
            item.id && ditem.attr("menuitemid", item.id);
            item.text && $(">.l-menu-item-text:first", ditem).html(item.text);
            item.icon && ditem.prepend('

');
            item.img && ditem.prepend('

');
            if (item.disable || item.disabled)
                ditem.addClass("l-menu-item-disable");
            if (item.children)
            {
                ditem.append('

');
                var newmenu = g.createMenu(ditem.attr("ligeruimenutemid"));
                g.menus[ditem.attr("ligeruimenutemid")] = newmenu;
                newmenu.width(p.width);
                newmenu.hover(null, function ()
                {
                    if (!newmenu.showedSubMenu)
                        g.hide(newmenu);
                });
                $(item.children).each(function ()
                {
                    g.addItem(this, newmenu);
                });
            }
            item.click && ditem.click(function ()
            {
                if ($(this).hasClass("l-menu-item-disable")) return;
                item.click(item, itemcount);
            });
            item.dblclick && ditem.dblclick(function ()
            {
                if ($(this).hasClass("l-menu-item-disable")) return;
                item.dblclick(item, itemcount);
            });

            var menuover = $("> .l-menu-over:first", menu);
            ditem.hover(function ()
            {
                if ($(this).hasClass("l-menu-item-disable")) return;
                var itemtop = $(this).offset().top;
                var top = itemtop - menu.offset().top;
                menuover.css({ top: top });
                g.hideAllSubMenu(menu);
                if (item.children)
                {
                    var ligeruimenutemid = $(this).attr("ligeruimenutemid");
                    if (!ligeruimenutemid) return;
                    if (g.menus[ligeruimenutemid])
                    {
                        g.show({ top: itemtop, left: $(this).offset().left + $(this).width() - 5 }, g.menus[ligeruimenutemid]);
                        menu.showedSubMenu = true;
                    }
                }
            }, function ()
            {
                if ($(this).hasClass("l-menu-item-disable")) return;
                var ligeruimenutemid = $(this).attr("ligeruimenutemid");
                if (item.children)
                {
                    var ligeruimenutemid = $(this).attr("ligeruimenutemid");
                    if (!ligeruimenutemid) return;
                };
            });
        },
        hideAllSubMenu: function (menu)
        {
            var g = this, p = this.options;
            if (menu == undefined) menu = g.menu;
            $("> .l-menu-item", menu.items).each(function ()
            {
                if ($("> .l-menu-item-arrow", this).length > 0)
                {
                    var ligeruimenutemid = $(this).attr("ligeruimenutemid");
                    if (!ligeruimenutemid) return;
                    g.menus[ligeruimenutemid] && g.hide(g.menus[ligeruimenutemid]);
                }
            });
            menu.showedSubMenu = false;
        },
        createMenu: function (parentMenuItemID)
        {
            var g = this, p = this.options;
            var menu = $('

');
            parentMenuItemID && menu.attr("ligeruiparentmenuitemid", parentMenuItemID);
            menu.items = $("> .l-menu-inner:first", menu);
            menu.appendTo('body');
            if (p.shadow)
            {
                menu.shadow = $('

').insertAfter(menu);
                g.updateShadow(menu);
            }
            menu.hover(null, function ()
            {
                if (!menu.showedSubMenu)
                    $("> .l-menu-over:first", menu).css({ top: -24 });
            });
            if (parentMenuItemID)
                g.menus[parentMenuItemID] = menu;
            else
                g.menus[0] = menu;
            return menu;
        }
    });
    //旧写法保留
    $.ligerui.controls.Menu.prototype.setEnable = $.ligerui.controls.Menu.prototype.setEnabled;
    $.ligerui.controls.Menu.prototype.setDisable = $.ligerui.controls.Menu.prototype.setDisabled;

})(jQuery);