module VagrantPlugins module DockerProvider module Action # Include the built-in modules so we can use them as top-level things. include Vagrant::Action::Builtin # This action starts another container just like the real one running # but only for the purpose of running a single command rather than # to exist long-running. def self.action_run_command Vagrant::Action::Builder.new.tap do |b| # We just call the "up" action. We create a separate action # to hold this though in case we modify it in the future, and # so that we can switch on the "machine_action" env var. b.use action_up end end # This action brings the "machine" up from nothing, including creating the # container, configuring metadata, and booting. def self.action_up Vagrant::Action::Builder.new.tap do |b| b.use Call, IsState, :not_created do |env, b2| if env[:result] b2.use HandleBox end end b.use ConfigValidate b.use HostMachine # Yeah, this is supposed to be here twice (once more above). This # catches the case when the container was supposed to be created, # but the host state was unknown, and now we know its not actually # created. b.use Call, IsState, :not_created do |env, b2| if env[:result] b2.use HandleBox b2.use DestroyBuildImage end end b.use action_start end end def self.action_package lambda do |env| raise Errors::PackageNotSupported end end # This action just runs the provisioners on the machine. def self.action_provision Vagrant::Action::Builder.new.tap do |b| b.use ConfigValidate b.use Call, IsState, :not_created do |env, b2| if env[:result] b2.use Message, I18n.t("docker_provider.messages.not_created") next end b2.use Call, IsState, :running do |env2, b3| if !env2[:result] b3.use Message, I18n.t("docker_provider.messages.not_running") next end b3.use Call, HasProvisioner do |env3, b4| b4.use Provision end end end end end # This is the action that is primarily responsible for halting # the virtual machine, gracefully or by force. def self.action_halt Vagrant::Action::Builder.new.tap do |b| b.use Call, IsState, :host_state_unknown do |env, b2| if env[:result] b2.use HostMachine end end b.use Call, IsState, :not_created do |env, b2| if env[:result] b2.use Message, I18n.t("docker_provider.messages.not_created") next end b2.use Stop end end end # This action is responsible for reloading the machine, which # brings it down, sucks in new configuration, and brings the # machine back up with the new configuration. def self.action_reload Vagrant::Action::Builder.new.tap do |b| b.use ConfigValidate b.use Call, IsState, :not_created do |env, b2| if env[:result] b2.use Message, I18n.t("docker_provider.messages.not_created") next end b2.use action_halt b2.use Call, IsBuild do |env2, b3| if env2[:result] b3.use EnvSet, force_halt: true b3.use action_halt b3.use HostMachineSyncFoldersDisable b3.use Destroy b3.use ProvisionerCleanup end end b2.use action_start end end end # This is the action that is primarily responsible for completely # freeing the resources of the underlying virtual machine. def self.action_destroy Vagrant::Action::Builder.new.tap do |b| b.use Call, IsHostMachineCreated do |env, b2| if !env[:result] b2.use Message, I18n.t("docker_provider.messages.not_created") next end b2.use Call, IsState, :host_state_unknown do |env2, b3| if env2[:result] b3.use HostMachine end end b2.use Call, IsState, :not_created do |env2, b3| if env2[:result] b3.use Message, I18n.t("docker_provider.messages.not_created") next end b3.use Call, DestroyConfirm do |env3, b4| if env3[:result] b4.use ConfigValidate b4.use ProvisionerCleanup, :before b4.use EnvSet, force_halt: true b4.use action_halt b4.use HostMachineSyncFoldersDisable b4.use Destroy b4.use DestroyNetwork b4.use DestroyBuildImage else b4.use Message, I18n.t("docker_provider.messages.will_not_destroy") end end end end end end # This is the action that will exec into an SSH shell. def self.action_ssh Vagrant::Action::Builder.new.tap do |b| b.use Call, IsState, :not_created do |env, b2| if env[:result] raise Errors::ContainerNotCreatedError end b2.use Call, IsState, :running do |env2, b3| if !env2[:result] raise Errors::ContainerNotRunningError end b3.use PrepareSSH b3.use SSHExec end end end end # This is the action that will run a single SSH command. def self.action_ssh_run Vagrant::Action::Builder.new.tap do |b| b.use Call, IsState, :not_created do |env, b2| if env[:result] raise Errors::ContainerNotCreatedError end b2.use Call, IsState, :running do |env2, b3| if !env2[:result] raise Errors::ContainerNotRunningError end b3.use SSHRun end end end end def self.action_start Vagrant::Action::Builder.new.tap do |b| b.use Call, IsState, :running do |env, b2| if env[:machine_action] != :run_command b2.use Call, HasProvisioner do |env2, b3| b3.use Provision end end # If the container is running and we're doing a run, we're done next if env[:result] && env[:machine_action] != :run_command b2.use Call, IsState, :not_created do |env2, b3| if env2[:result] # First time making this thing, set to the "preparing" state b3.use InitState else b3.use EnvSet, host_machine_sync_folders: false end end b2.use HostMachineBuildDir b2.use HostMachineSyncFolders b2.use PrepareNFSValidIds b2.use SyncedFolderCleanup b2.use PrepareNFSSettings b2.use PrepareNetworks b2.use Login b2.use Build if env[:machine_action] != :run_command # If the container is NOT created yet, then do some setup steps # necessary for creating it. b2.use Call, IsState, :preparing do |env2, b3| if env2[:result] b3.use EnvSet, port_collision_repair: true b3.use HostMachinePortWarning b3.use HostMachinePortChecker b3.use ForwardedPorts # This action converts the `ports` param into proper network configs b3.use PrepareForwardedPortCollisionParams b3.use HandleForwardedPortCollisions b3.use SyncedFolders b3.use Pull b3.use Create b3.use WaitForRunning else b3.use CompareSyncedFolders end end b2.use ConnectNetworks b2.use Start b2.use WaitForRunning b2.use Call, HasSSH do |env2, b3| if env2[:result] b3.use WaitForCommunicator end end else # We're in a run command, so we do things a bit differently. b2.use SyncedFolders b2.use Create end end end end def self.action_suspend lambda do |env| raise Errors::SuspendNotSupported end end # The autoload farm action_root = Pathname.new(File.expand_path("../action", __FILE__)) autoload :Build, action_root.join("build") autoload :CompareSyncedFolders, action_root.join("compare_synced_folders") autoload :ConnectNetworks, action_root.join("connect_networks") autoload :Create, action_root.join("create") autoload :Destroy, action_root.join("destroy") autoload :DestroyBuildImage, action_root.join("destroy_build_image") autoload :DestroyNetwork, action_root.join("destroy_network") autoload :ForwardedPorts, action_root.join("forwarded_ports") autoload :HasSSH, action_root.join("has_ssh") autoload :HostMachine, action_root.join("host_machine") autoload :HostMachineBuildDir, action_root.join("host_machine_build_dir") autoload :HostMachinePortChecker, action_root.join("host_machine_port_checker") autoload :HostMachinePortWarning, action_root.join("host_machine_port_warning") autoload :HostMachineRequired, action_root.join("host_machine_required") autoload :HostMachineSyncFolders, action_root.join("host_machine_sync_folders") autoload :HostMachineSyncFoldersDisable, action_root.join("host_machine_sync_folders_disable") autoload :InitState, action_root.join("init_state") autoload :IsBuild, action_root.join("is_build") autoload :IsHostMachineCreated, action_root.join("is_host_machine_created") autoload :Login, action_root.join("login") autoload :PrepareForwardedPortCollisionParams, action_root.join("prepare_forwarded_port_collision_params") autoload :PrepareNetworks, action_root.join("prepare_networks") autoload :PrepareNFSValidIds, action_root.join("prepare_nfs_valid_ids") autoload :PrepareNFSSettings, action_root.join("prepare_nfs_settings") autoload :PrepareSSH, action_root.join("prepare_ssh") autoload :Pull, action_root.join("pull") autoload :Start, action_root.join("start") autoload :Stop, action_root.join("stop") autoload :WaitForRunning, action_root.join("wait_for_running") end end end