summaryrefslogtreecommitdiff
path: root/windows
diff options
context:
space:
mode:
Diffstat (limited to 'windows')
-rw-r--r--windows/win_robocopy.ps1147
-rw-r--r--windows/win_robocopy.py143
2 files changed, 290 insertions, 0 deletions
diff --git a/windows/win_robocopy.ps1 b/windows/win_robocopy.ps1
new file mode 100644
index 00000000..69cf9ee3
--- /dev/null
+++ b/windows/win_robocopy.ps1
@@ -0,0 +1,147 @@
+#!powershell
+# This file is part of Ansible
+#
+# Copyright 2015, Corwin Brown <corwin.brown@maxpoint.com>
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+# WANT_JSON
+# POWERSHELL_COMMON
+
+$params = Parse-Args $args;
+
+$result = New-Object psobject @{
+ win_robocopy = New-Object psobject @{
+ recurse = $false
+ purge = $false
+ }
+ changed = $false
+}
+
+$src = Get-AnsibleParam -obj $params -name "src" -failifempty $true
+$dest = Get-AnsibleParam -obj $params -name "dest" -failifempty $true
+$purge = ConvertTo-Bool (Get-AnsibleParam -obj $params -name "purge" -default $false)
+$recurse = ConvertTo-Bool (Get-AnsibleParam -obj $params -name "recurse" -default $false)
+$flags = Get-AnsibleParam -obj $params -name "flags" -default $null
+$_ansible_check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $false
+
+# Search for an Error Message
+# Robocopy seems to display an error after 3 '-----' separator lines
+Function SearchForError($cmd_output, $default_msg) {
+ $separator_count = 0
+ $error_msg = $default_msg
+ ForEach ($line in $cmd_output) {
+ if (-Not $line) {
+ continue
+ }
+
+ if ($separator_count -ne 3) {
+ if (Select-String -InputObject $line -pattern "^(\s+)?(\-+)(\s+)?$") {
+ $separator_count += 1
+ }
+ }
+ Else {
+ If (Select-String -InputObject $line -pattern "error") {
+ $error_msg = $line
+ break
+ }
+ }
+ }
+
+ return $error_msg
+}
+
+# Build Arguments
+$robocopy_opts = @()
+
+if (-Not (Test-Path $src)) {
+ Fail-Json $result "$src does not exist!"
+}
+
+$robocopy_opts += $src
+Set-Attr $result.win_robocopy "src" $src
+
+$robocopy_opts += $dest
+Set-Attr $result.win_robocopy "dest" $dest
+
+if ($flags -eq $null) {
+ if ($purge) {
+ $robocopy_opts += "/purge"
+ }
+
+ if ($recurse) {
+ $robocopy_opts += "/e"
+ }
+}
+Else {
+ $robocopy_opts += $flags
+}
+
+Set-Attr $result.win_robocopy "purge" $purge
+Set-Attr $result.win_robocopy "recurse" $recurse
+Set-Attr $result.win_robocopy "flags" $flags
+
+$robocopy_output = ""
+$rc = 0
+If ($_ansible_check_mode -eq $true) {
+ $robocopy_output = "Would have copied the contents of $src to $dest"
+ $rc = 0
+}
+Else {
+ Try {
+ &robocopy $robocopy_opts | Tee-Object -Variable robocopy_output | Out-Null
+ $rc = $LASTEXITCODE
+ }
+ Catch {
+ $ErrorMessage = $_.Exception.Message
+ Fail-Json $result "Error synchronizing $src to $dest! Msg: $ErrorMessage"
+ }
+}
+
+Set-Attr $result.win_robocopy "return_code" $rc
+Set-Attr $result.win_robocopy "output" $robocopy_output
+
+$cmd_msg = "Success"
+If ($rc -eq 0) {
+ $cmd_msg = "No files copied."
+}
+ElseIf ($rc -eq 1) {
+ $cmd_msg = "Files copied successfully!"
+ $changed = $true
+}
+ElseIf ($rc -eq 2) {
+ $cmd_msg = "Extra files or directories were detected!"
+ $changed = $true
+}
+ElseIf ($rc -eq 4) {
+ $cmd_msg = "Some mismatched files or directories were detected!"
+ $changed = $true
+}
+ElseIf ($rc -eq 8) {
+ $error_msg = SearchForError $robocopy_output "Some files or directories could not be copied!"
+ Fail-Json $result $error_msg
+}
+ElseIf ($rc -eq 10) {
+ $error_msg = SearchForError $robocopy_output "Serious Error! No files were copied! Do you have permissions to access $src and $dest?"
+ Fail-Json $result $error_msg
+}
+ElseIf ($rc -eq 16) {
+ $error_msg = SearchForError $robocopy_output "Fatal Error!"
+ Fail-Json $result $error_msg
+}
+
+Set-Attr $result.win_robocopy "msg" $cmd_msg
+Set-Attr $result.win_robocopy "changed" $changed
+
+Exit-Json $result
diff --git a/windows/win_robocopy.py b/windows/win_robocopy.py
new file mode 100644
index 00000000..d627918e
--- /dev/null
+++ b/windows/win_robocopy.py
@@ -0,0 +1,143 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2015, Corwin Brown <blakfeld@gmail.com>
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+# this is a windows documentation stub. actual code lives in the .ps1
+# file of the same name
+
+DOCUMENTATION = """
+---
+module: win_robocopy
+version_added: "2.2"
+short_description: Synchronizes the contents of two directories using Robocopy.
+description:
+ - Synchronizes the contents of two directories on the remote machine. Under the hood this just calls out to RoboCopy, since that should be available on most modern Windows Systems.
+options:
+ src:
+ description:
+ - Source file/directory to sync.
+ required: true
+ dest:
+ description:
+ - Destination file/directory to sync (Will receive contents of src).
+ required: true
+ recurse:
+ description:
+ - Includes all subdirectories (Toggles the `/e` flag to RoboCopy). If "flags" is set, this will be ignored.
+ choices:
+ - true
+ - false
+ defaults: false
+ required: false
+ purge:
+ description:
+ - Deletes any files/directories found in the destination that do not exist in the source (Toggles the `/purge` flag to RoboCopy). If "flags" is set, this will be ignored.
+ choices:
+ - true
+ - false
+ defaults: false
+ required: false
+ flags:
+ description:
+ - Directly supply Robocopy flags. If set, purge and recurse will be ignored.
+ default: None
+ required: false
+author: Corwin Brown (@blakfeld)
+notes:
+ - This is not a complete port of the "synchronize" module. Unlike the "synchronize" module this only performs the sync/copy on the remote machine, not from the master to the remote machine.
+ - This module does not currently support all Robocopy flags.
+ - Works on Windows 7, Windows 8, Windows Server 2k8, and Windows Server 2k12
+"""
+
+EXAMPLES = """
+# Syncs the contents of one diretory to another.
+$ ansible -i hosts all -m win_robocopy -a "src=C:\\DirectoryOne dest=C:\\DirectoryTwo"
+
+# Sync the contents of one directory to another, including subdirectories.
+$ ansible -i hosts all -m win_robocopy -a "src=C:\\DirectoryOne dest=C:\\DirectoryTwo recurse=true"
+
+# Sync the contents of one directory to another, and remove any files/directories found in destination that do not exist in the source.
+$ ansible -i hosts all -m win_robocopy -a "src=C:\\DirectoryOne dest=C:\\DirectoryTwo purge=true"
+
+# Sample sync
+---
+- name: Sync Two Directories
+ win_robocopy:
+ src: "C:\\DirectoryOne
+ dest: "C:\\DirectoryTwo"
+ recurse: true
+ purge: true
+
+---
+- name: Sync Two Directories
+ win_robocopy:
+ src: "C:\\DirectoryOne
+ dest: "C:\\DirectoryTwo"
+ recurse: true
+ purge: true
+ flags: '/XD SOME_DIR /XF SOME_FILE /MT:32'
+"""
+
+RETURN = '''
+src:
+ description: The Source file/directory of the sync.
+ returned: always
+ type: string
+ sample: "c:/Some/Path"
+dest:
+ description: The Destination file/directory of the sync.
+ returned: always
+ type: string
+ sample: "c:/Some/Path"
+recurse:
+ description: Whether or not the recurse flag was toggled.
+ returned: always
+ type: bool
+ sample: False
+purge:
+ description: Whether or not the purge flag was toggled.
+ returned: always
+ type: bool
+ sample: False
+flags:
+ description: Any flags passed in by the user.
+ returned: always
+ type: string
+ sample: "/e /purge"
+return_code:
+ description: The return code retuned by robocopy.
+ returned: success
+ type: int
+ sample: 1
+output:
+ description: The output of running the robocopy command.
+ returned: success
+ type: string
+ sample: "-------------------------------------------------------------------------------\n ROBOCOPY :: Robust File Copy for Windows \n-------------------------------------------------------------------------------\n"
+msg:
+ description: Output intrepreted into a concise message.
+ returned: always
+ type: string
+ sample: No files copied!
+changed:
+ description: Whether or not any changes were made.
+ returned: always
+ type: bool
+ sample: False
+'''