diff mbox

[ovs-dev,V4,1/5] Python tests: Add winutils.py module

Message ID 1483474197-8702-2-git-send-email-abalutoiu@cloudbasesolutions.com
State Accepted
Headers show

Commit Message

Alin Balutoiu Jan. 3, 2017, 8:10 p.m. UTC
From: Alin Balutoiu <abalutoiu@cloudbasesolutions.com>

This patch adds a new python module which contains
helper functions. These will be neccessary for the
Windows implementation.

They cover the following aspects: sockets and namedpipes.

Signed-off-by: Alin-Gheorghe Balutoiu <abalutoiu@cloudbasesolutions.com>
Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions>
---
V2: No changes.
V3: Changed Signed-off-by name and added previous Acked-by's.
V4: Fixed typo and included myself in the AUTHORS file.
---
 AUTHORS.rst            |   1 +
 python/automake.mk     |   3 +-
 python/ovs/winutils.py | 226 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 python/ovs/winutils.py

Comments

Gurucharan Shetty Jan. 3, 2017, 9:07 p.m. UTC | #1
On 3 January 2017 at 12:10, Alin Balutoiu <abalutoiu@cloudbasesolutions.com>
wrote:

> From: Alin Balutoiu <abalutoiu@cloudbasesolutions.com>
>
> This patch adds a new python module which contains
> helper functions. These will be neccessary for the
> Windows implementation.
>
> They cover the following aspects: sockets and namedpipes.
>
> Signed-off-by: Alin-Gheorghe Balutoiu <abalutoiu@cloudbasesolutions.com>
>

I changed your Signed-off-by to the previous version and applied the series.


> Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions>
> ---
> V2: No changes.
> V3: Changed Signed-off-by name and added previous Acked-by's.
> V4: Fixed typo and included myself in the AUTHORS file.
> ---
>  AUTHORS.rst            |   1 +
>  python/automake.mk     |   3 +-
>  python/ovs/winutils.py | 226 ++++++++++++++++++++++++++++++
> +++++++++++++++++++
>  3 files changed, 229 insertions(+), 1 deletion(-)
>  create mode 100644 python/ovs/winutils.py
>
> diff --git a/AUTHORS.rst b/AUTHORS.rst
> index d30511a..1efb332 100644
> --- a/AUTHORS.rst
> +++ b/AUTHORS.rst
> @@ -39,6 +39,7 @@ Alexei Starovoitov              ast@plumgrid.com
>  Alexey I. Froloff               raorn@raorn.name
>  Alex Wang                       ee07b291@gmail.com
>  Alfredo Finelli                 alf@computationes.de
> +Alin Balutoiu                   abalutoiu@cloudbasesolutions.com
>  Alin Serdean                    aserdean@cloudbasesolutions.com
>  Ambika Arora                    ambika.arora@tcs.com
>  Amit Bose                       bose@noironetworks.com
> diff --git a/python/automake.mk b/python/automake.mk
> index 1c8fa38..e417483 100644
> --- a/python/automake.mk
> +++ b/python/automake.mk
> @@ -34,7 +34,8 @@ ovs_pyfiles = \
>         python/ovs/unixctl/server.py \
>         python/ovs/util.py \
>         python/ovs/version.py \
> -       python/ovs/vlog.py
> +       python/ovs/vlog.py \
> +       python/ovs/winutils.py
>
>  # These python files are used at build time but not runtime,
>  # so they are not installed.
> diff --git a/python/ovs/winutils.py b/python/ovs/winutils.py
> new file mode 100644
> index 0000000..3a235f8
> --- /dev/null
> +++ b/python/ovs/winutils.py
> @@ -0,0 +1,226 @@
> +# Copyright (c) 2016 Cloudbase Solutions Srl
> +#
> +# Licensed under the Apache License, Version 2.0 (the "License");
> +# you may not use this file except in compliance with the License.
> +# You may obtain a copy of the License at:
> +#
> +#     http://www.apache.org/licenses/LICENSE-2.0
> +#
> +# Unless required by applicable law or agreed to in writing, software
> +# distributed under the License is distributed on an "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> +# See the License for the specific language governing permissions and
> +# limitations under the License.
> +
> +import six
> +import sys
> +
> +if sys.platform != 'win32':
> +    raise Exception("Intended to use only on Windows")
> +else:
> +    import pywintypes
> +    import winerror
> +    import win32pipe
> +    import win32con
> +    import win32security
> +    import win32file
> +    import win32event
> +
> +
> +def close_handle(handle, logger=None):
> +    try:
> +        win32file.CloseHandle(handle)
> +        return None
> +    except pywintypes.error as e:
> +        if logger is not None:
> +            logger("failed to close handle: %s" % e.strerror)
> +        return e.winerror
> +
> +
> +def windows_create_pipe(sAttrs=-1, nSize=None):
> +    # Default values if parameters are not passed
> +    if sAttrs == -1:
> +        sAttrs = win32security.SECURITY_ATTRIBUTES()
> +        sAttrs.bInheritHandle = 1
> +    if nSize is None:
> +        # If this parameter is zero, the system uses the default buffer
> size.
> +        nSize = 0
> +
> +    try:
> +        (read_pipe, write_pipe) = win32pipe.CreatePipe(sAttrs, nSize)
> +    except pywintypes.error:
> +        raise
> +
> +    return (read_pipe, write_pipe)
> +
> +
> +def windows_read_pipe(fd, length):
> +    try:
> +        (error, data) = win32file.ReadFile(fd, length)
> +        return error, data
> +    except pywintypes.error as e:
> +        return e.winerror, ""
> +
> +
> +def create_file(filename, desiredAccess=None, shareMode=None,
> attributes=-1,
> +                CreationDisposition=None, flagsAndAttributes=None,
> +                hTemplateFile=-1):
> +    # Default values if parameters are not passed
> +    if desiredAccess is None:
> +        desiredAccess = win32file.GENERIC_READ | win32file.GENERIC_WRITE
> +    if shareMode is None:
> +        shareMode = 0
> +    if attributes == -1:
> +        # attributes can be None
> +        attributes = None
> +    if CreationDisposition is None:
> +        CreationDisposition = win32file.OPEN_EXISTING
> +    if flagsAndAttributes is None:
> +        flagsAndAttributes = (win32file.FILE_ATTRIBUTE_NORMAL |
> +                              win32file.FILE_FLAG_OVERLAPPED |
> +                              win32file.FILE_FLAG_NO_BUFFERING)
> +    if hTemplateFile == -1:
> +        hTemplateFile = None
> +
> +    try:
> +        npipe = win32file.CreateFile(filename,
> +                                     desiredAccess,
> +                                     shareMode,
> +                                     attributes,
> +                                     CreationDisposition,
> +                                     flagsAndAttributes,
> +                                     hTemplateFile)
> +    except pywintypes.error:
> +        raise
> +    return npipe
> +
> +
> +def write_file(handle, data, overlapped=None):
> +    try:
> +        (errCode, nBytesWritten) = win32file.WriteFile(handle,
> +                                                       data,
> +                                                       overlapped)
> +        # Note: win32file.WriteFile doesn't throw an exception
> +        # in case it receives ERROR_IO_PENDING.
> +        return (errCode, nBytesWritten)
> +    except pywintypes.error as e:
> +        return (e.winerror, 0)
> +
> +
> +def read_file(handle, bufsize, overlapped=None):
> +    try:
> +        # Note: win32file.ReadFile doesn't throw an exception
> +        # in case it receives ERROR_IO_PENDING.
> +        (errCode, read_buffer) = win32file.ReadFile(
> +            handle, bufsize, overlapped)
> +        return (errCode, read_buffer)
> +    except pywintypes.error as e:
> +        return (e.winerror, "")
> +
> +
> +def create_named_pipe(pipename, openMode=None, pipeMode=None,
> +                      nMaxInstances=None, nOutBufferSize=None,
> +                      nInBufferSize=None, nDefaultTimeOut=None,
> +                      saAttr=-1):
> +    # Default values if parameters are not passed
> +    if openMode is None:
> +        openMode = win32con.PIPE_ACCESS_DUPLEX |
> win32con.FILE_FLAG_OVERLAPPED
> +    if pipeMode is None:
> +        pipeMode = (win32con.PIPE_TYPE_MESSAGE |
> +                    win32con.PIPE_READMODE_BYTE |
> +                    win32con.PIPE_WAIT)
> +    if nMaxInstances is None:
> +        nMaxInstances = 64
> +    if nOutBufferSize is None:
> +        nOutBufferSize = 65000
> +    if nInBufferSize is None:
> +        nInBufferSize = 65000
> +    if nDefaultTimeOut is None:
> +        nDefaultTimeOut = 0
> +    if saAttr == -1:
> +        # saAttr can be None
> +        saAttr = win32security.SECURITY_ATTRIBUTES()
> +        saAttr.bInheritHandle = 1
> +
> +    try:
> +        npipe = win32pipe.CreateNamedPipe(pipename,
> +                                          openMode,
> +                                          pipeMode,
> +                                          nMaxInstances,
> +                                          nOutBufferSize,
> +                                          nInBufferSize,
> +                                          nDefaultTimeOut,
> +                                          saAttr)
> +
> +        if npipe == win32file.INVALID_HANDLE_VALUE:
> +            return None
> +
> +        return npipe
> +    except pywintypes.error:
> +        return None
> +
> +
> +def set_pipe_mode(hPipe, mode=-1, maxCollectionCount=None,
> +                  collectDataTimeout=None):
> +    # Default values if parameters are not passed
> +    if mode == -1:
> +        mode = win32pipe.PIPE_READMODE_BYTE
> +    try:
> +        win32pipe.SetNamedPipeHandleState(
> +            hPipe, mode, maxCollectionCount, collectDataTimeout)
> +    except pywintypes.error:
> +        raise
> +
> +
> +def connect_named_pipe(pipe_handle, overlapped=None):
> +    try:
> +        # If the result of ConnectNamedPipe is ERROR_IO_PENDING or
> +        # ERROR_PIPE_CONNECTED, then this value is returned.
> +        # All other error values raise a win32 exception
> +        error = win32pipe.ConnectNamedPipe(pipe_handle, overlapped)
> +        return error
> +    except pywintypes.error as e:
> +        return e.winerror
> +
> +
> +def get_pipe_name(name):
> +    name = name.replace('/', '')
> +    name = name.replace('\\', '')
> +    name = "\\\\.\\pipe\\" + name
> +    return name
> +
> +
> +def get_overlapped_result(handle, overlapped=None, bWait=False):
> +    try:
> +        return win32file.GetOverlappedResult(handle, overlapped, bWait)
> +    except pywintypes.error:
> +        raise
> +
> +
> +def get_decoded_buffer(recvBuffer):
> +    if six.PY3:
> +        return bytes(recvBuffer).decode("utf-8")
> +    else:
> +        return str(recvBuffer)
> +
> +
> +def get_encoded_buffer(buff):
> +    # Python 3 has separate types for strings and bytes.
> +    # We must have bytes here.
> +    if not isinstance(buff, six.binary_type):
> +        if six.PY3:
> +            buff = six.binary_type(buff, 'utf-8')
> +        else:
> +            buff = six.binary_type(buff)
> +    return buff
> +
> +
> +def get_new_event(sa=None, bManualReset=True, bInitialState=True,
> +                  objectName=None):
> +    return win32event.CreateEvent(sa, bManualReset, bInitialState,
> objectName)
> +
> +
> +pipe_disconnected_errors = [winerror.ERROR_PIPE_NOT_CONNECTED,
> +                            winerror.ERROR_BAD_PIPE,
> +                            winerror.ERROR_NO_DATA,
> +                            winerror.ERROR_BROKEN_PIPE]
> --
> 2.10.0.windows.1
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
Gurucharan Shetty Jan. 3, 2017, 11 p.m. UTC | #2
Would you mind updating Appveyor to include the new libraries? It currently
fails:
https://ci.appveyor.com/project/blp/ovs/build/1.0.2634

On 3 January 2017 at 13:07, Guru Shetty <guru@ovn.org> wrote:

>
>
> On 3 January 2017 at 12:10, Alin Balutoiu <abalutoiu@cloudbasesolutions.
> com> wrote:
>
>> From: Alin Balutoiu <abalutoiu@cloudbasesolutions.com>
>>
>> This patch adds a new python module which contains
>> helper functions. These will be neccessary for the
>> Windows implementation.
>>
>> They cover the following aspects: sockets and namedpipes.
>>
>> Signed-off-by: Alin-Gheorghe Balutoiu <abalutoiu@cloudbasesolutions.com>
>>
>
> I changed your Signed-off-by to the previous version and applied the
> series.
>
>
>> Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions>
>> ---
>> V2: No changes.
>> V3: Changed Signed-off-by name and added previous Acked-by's.
>> V4: Fixed typo and included myself in the AUTHORS file.
>> ---
>>  AUTHORS.rst            |   1 +
>>  python/automake.mk     |   3 +-
>>  python/ovs/winutils.py | 226 ++++++++++++++++++++++++++++++
>> +++++++++++++++++++
>>  3 files changed, 229 insertions(+), 1 deletion(-)
>>  create mode 100644 python/ovs/winutils.py
>>
>> diff --git a/AUTHORS.rst b/AUTHORS.rst
>> index d30511a..1efb332 100644
>> --- a/AUTHORS.rst
>> +++ b/AUTHORS.rst
>> @@ -39,6 +39,7 @@ Alexei Starovoitov              ast@plumgrid.com
>>  Alexey I. Froloff               raorn@raorn.name
>>  Alex Wang                       ee07b291@gmail.com
>>  Alfredo Finelli                 alf@computationes.de
>> +Alin Balutoiu                   abalutoiu@cloudbasesolutions.com
>>  Alin Serdean                    aserdean@cloudbasesolutions.com
>>  Ambika Arora                    ambika.arora@tcs.com
>>  Amit Bose                       bose@noironetworks.com
>> diff --git a/python/automake.mk b/python/automake.mk
>> index 1c8fa38..e417483 100644
>> --- a/python/automake.mk
>> +++ b/python/automake.mk
>> @@ -34,7 +34,8 @@ ovs_pyfiles = \
>>         python/ovs/unixctl/server.py \
>>         python/ovs/util.py \
>>         python/ovs/version.py \
>> -       python/ovs/vlog.py
>> +       python/ovs/vlog.py \
>> +       python/ovs/winutils.py
>>
>>  # These python files are used at build time but not runtime,
>>  # so they are not installed.
>> diff --git a/python/ovs/winutils.py b/python/ovs/winutils.py
>> new file mode 100644
>> index 0000000..3a235f8
>> --- /dev/null
>> +++ b/python/ovs/winutils.py
>> @@ -0,0 +1,226 @@
>> +# Copyright (c) 2016 Cloudbase Solutions Srl
>> +#
>> +# Licensed under the Apache License, Version 2.0 (the "License");
>> +# you may not use this file except in compliance with the License.
>> +# You may obtain a copy of the License at:
>> +#
>> +#     http://www.apache.org/licenses/LICENSE-2.0
>> +#
>> +# Unless required by applicable law or agreed to in writing, software
>> +# distributed under the License is distributed on an "AS IS" BASIS,
>> +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>> implied.
>> +# See the License for the specific language governing permissions and
>> +# limitations under the License.
>> +
>> +import six
>> +import sys
>> +
>> +if sys.platform != 'win32':
>> +    raise Exception("Intended to use only on Windows")
>> +else:
>> +    import pywintypes
>> +    import winerror
>> +    import win32pipe
>> +    import win32con
>> +    import win32security
>> +    import win32file
>> +    import win32event
>> +
>> +
>> +def close_handle(handle, logger=None):
>> +    try:
>> +        win32file.CloseHandle(handle)
>> +        return None
>> +    except pywintypes.error as e:
>> +        if logger is not None:
>> +            logger("failed to close handle: %s" % e.strerror)
>> +        return e.winerror
>> +
>> +
>> +def windows_create_pipe(sAttrs=-1, nSize=None):
>> +    # Default values if parameters are not passed
>> +    if sAttrs == -1:
>> +        sAttrs = win32security.SECURITY_ATTRIBUTES()
>> +        sAttrs.bInheritHandle = 1
>> +    if nSize is None:
>> +        # If this parameter is zero, the system uses the default buffer
>> size.
>> +        nSize = 0
>> +
>> +    try:
>> +        (read_pipe, write_pipe) = win32pipe.CreatePipe(sAttrs, nSize)
>> +    except pywintypes.error:
>> +        raise
>> +
>> +    return (read_pipe, write_pipe)
>> +
>> +
>> +def windows_read_pipe(fd, length):
>> +    try:
>> +        (error, data) = win32file.ReadFile(fd, length)
>> +        return error, data
>> +    except pywintypes.error as e:
>> +        return e.winerror, ""
>> +
>> +
>> +def create_file(filename, desiredAccess=None, shareMode=None,
>> attributes=-1,
>> +                CreationDisposition=None, flagsAndAttributes=None,
>> +                hTemplateFile=-1):
>> +    # Default values if parameters are not passed
>> +    if desiredAccess is None:
>> +        desiredAccess = win32file.GENERIC_READ | win32file.GENERIC_WRITE
>> +    if shareMode is None:
>> +        shareMode = 0
>> +    if attributes == -1:
>> +        # attributes can be None
>> +        attributes = None
>> +    if CreationDisposition is None:
>> +        CreationDisposition = win32file.OPEN_EXISTING
>> +    if flagsAndAttributes is None:
>> +        flagsAndAttributes = (win32file.FILE_ATTRIBUTE_NORMAL |
>> +                              win32file.FILE_FLAG_OVERLAPPED |
>> +                              win32file.FILE_FLAG_NO_BUFFERING)
>> +    if hTemplateFile == -1:
>> +        hTemplateFile = None
>> +
>> +    try:
>> +        npipe = win32file.CreateFile(filename,
>> +                                     desiredAccess,
>> +                                     shareMode,
>> +                                     attributes,
>> +                                     CreationDisposition,
>> +                                     flagsAndAttributes,
>> +                                     hTemplateFile)
>> +    except pywintypes.error:
>> +        raise
>> +    return npipe
>> +
>> +
>> +def write_file(handle, data, overlapped=None):
>> +    try:
>> +        (errCode, nBytesWritten) = win32file.WriteFile(handle,
>> +                                                       data,
>> +                                                       overlapped)
>> +        # Note: win32file.WriteFile doesn't throw an exception
>> +        # in case it receives ERROR_IO_PENDING.
>> +        return (errCode, nBytesWritten)
>> +    except pywintypes.error as e:
>> +        return (e.winerror, 0)
>> +
>> +
>> +def read_file(handle, bufsize, overlapped=None):
>> +    try:
>> +        # Note: win32file.ReadFile doesn't throw an exception
>> +        # in case it receives ERROR_IO_PENDING.
>> +        (errCode, read_buffer) = win32file.ReadFile(
>> +            handle, bufsize, overlapped)
>> +        return (errCode, read_buffer)
>> +    except pywintypes.error as e:
>> +        return (e.winerror, "")
>> +
>> +
>> +def create_named_pipe(pipename, openMode=None, pipeMode=None,
>> +                      nMaxInstances=None, nOutBufferSize=None,
>> +                      nInBufferSize=None, nDefaultTimeOut=None,
>> +                      saAttr=-1):
>> +    # Default values if parameters are not passed
>> +    if openMode is None:
>> +        openMode = win32con.PIPE_ACCESS_DUPLEX |
>> win32con.FILE_FLAG_OVERLAPPED
>> +    if pipeMode is None:
>> +        pipeMode = (win32con.PIPE_TYPE_MESSAGE |
>> +                    win32con.PIPE_READMODE_BYTE |
>> +                    win32con.PIPE_WAIT)
>> +    if nMaxInstances is None:
>> +        nMaxInstances = 64
>> +    if nOutBufferSize is None:
>> +        nOutBufferSize = 65000
>> +    if nInBufferSize is None:
>> +        nInBufferSize = 65000
>> +    if nDefaultTimeOut is None:
>> +        nDefaultTimeOut = 0
>> +    if saAttr == -1:
>> +        # saAttr can be None
>> +        saAttr = win32security.SECURITY_ATTRIBUTES()
>> +        saAttr.bInheritHandle = 1
>> +
>> +    try:
>> +        npipe = win32pipe.CreateNamedPipe(pipename,
>> +                                          openMode,
>> +                                          pipeMode,
>> +                                          nMaxInstances,
>> +                                          nOutBufferSize,
>> +                                          nInBufferSize,
>> +                                          nDefaultTimeOut,
>> +                                          saAttr)
>> +
>> +        if npipe == win32file.INVALID_HANDLE_VALUE:
>> +            return None
>> +
>> +        return npipe
>> +    except pywintypes.error:
>> +        return None
>> +
>> +
>> +def set_pipe_mode(hPipe, mode=-1, maxCollectionCount=None,
>> +                  collectDataTimeout=None):
>> +    # Default values if parameters are not passed
>> +    if mode == -1:
>> +        mode = win32pipe.PIPE_READMODE_BYTE
>> +    try:
>> +        win32pipe.SetNamedPipeHandleState(
>> +            hPipe, mode, maxCollectionCount, collectDataTimeout)
>> +    except pywintypes.error:
>> +        raise
>> +
>> +
>> +def connect_named_pipe(pipe_handle, overlapped=None):
>> +    try:
>> +        # If the result of ConnectNamedPipe is ERROR_IO_PENDING or
>> +        # ERROR_PIPE_CONNECTED, then this value is returned.
>> +        # All other error values raise a win32 exception
>> +        error = win32pipe.ConnectNamedPipe(pipe_handle, overlapped)
>> +        return error
>> +    except pywintypes.error as e:
>> +        return e.winerror
>> +
>> +
>> +def get_pipe_name(name):
>> +    name = name.replace('/', '')
>> +    name = name.replace('\\', '')
>> +    name = "\\\\.\\pipe\\" + name
>> +    return name
>> +
>> +
>> +def get_overlapped_result(handle, overlapped=None, bWait=False):
>> +    try:
>> +        return win32file.GetOverlappedResult(handle, overlapped, bWait)
>> +    except pywintypes.error:
>> +        raise
>> +
>> +
>> +def get_decoded_buffer(recvBuffer):
>> +    if six.PY3:
>> +        return bytes(recvBuffer).decode("utf-8")
>> +    else:
>> +        return str(recvBuffer)
>> +
>> +
>> +def get_encoded_buffer(buff):
>> +    # Python 3 has separate types for strings and bytes.
>> +    # We must have bytes here.
>> +    if not isinstance(buff, six.binary_type):
>> +        if six.PY3:
>> +            buff = six.binary_type(buff, 'utf-8')
>> +        else:
>> +            buff = six.binary_type(buff)
>> +    return buff
>> +
>> +
>> +def get_new_event(sa=None, bManualReset=True, bInitialState=True,
>> +                  objectName=None):
>> +    return win32event.CreateEvent(sa, bManualReset, bInitialState,
>> objectName)
>> +
>> +
>> +pipe_disconnected_errors = [winerror.ERROR_PIPE_NOT_CONNECTED,
>> +                            winerror.ERROR_BAD_PIPE,
>> +                            winerror.ERROR_NO_DATA,
>> +                            winerror.ERROR_BROKEN_PIPE]
>> --
>> 2.10.0.windows.1
>> _______________________________________________
>> dev mailing list
>> dev@openvswitch.org
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>
>
Alin Serdean Jan. 4, 2017, 10:06 a.m. UTC | #3
Oooops, my bad. I totally forgot about it while reviewing.

I sent a patch out: http://patchwork.ozlabs.org/patch/710882/ , and I got a clean build on my account: https://ci.appveyor.com/project/AlinGabrielSerdean/ovs/build/1.0.16

Thanks,
Alin.

> -----Original Message-----
> From: ovs-dev-bounces@openvswitch.org [mailto:ovs-dev-
> bounces@openvswitch.org] On Behalf Of Guru Shetty
> Sent: Wednesday, January 4, 2017 1:01 AM
> To: Alin Balutoiu <abalutoiu@cloudbasesolutions.com>
> Cc: dev@openvswitch.org
> Subject: Re: [ovs-dev] [PATCH V4 1/5] Python tests: Add winutils.py module
> 
> Would you mind updating Appveyor to include the new libraries? It currently
> fails:
> https://ci.appveyor.com/project/blp/ovs/build/1.0.2634
> 
> On 3 January 2017 at 13:07, Guru Shetty <guru@ovn.org> wrote:
> 
> >
> >
> > On 3 January 2017 at 12:10, Alin Balutoiu <abalutoiu@cloudbasesolutions.
> > com> wrote:
> >
> >> From: Alin Balutoiu <abalutoiu@cloudbasesolutions.com>
> >>
> >> This patch adds a new python module which contains helper functions.
> >> These will be neccessary for the Windows implementation.
> >>
> >> They cover the following aspects: sockets and namedpipes.
> >>
> >> Signed-off-by: Alin-Gheorghe Balutoiu
> >> <abalutoiu@cloudbasesolutions.com>
> >>
> >
diff mbox

Patch

diff --git a/AUTHORS.rst b/AUTHORS.rst
index d30511a..1efb332 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -39,6 +39,7 @@  Alexei Starovoitov              ast@plumgrid.com
 Alexey I. Froloff               raorn@raorn.name
 Alex Wang                       ee07b291@gmail.com
 Alfredo Finelli                 alf@computationes.de
+Alin Balutoiu                   abalutoiu@cloudbasesolutions.com
 Alin Serdean                    aserdean@cloudbasesolutions.com
 Ambika Arora                    ambika.arora@tcs.com
 Amit Bose                       bose@noironetworks.com
diff --git a/python/automake.mk b/python/automake.mk
index 1c8fa38..e417483 100644
--- a/python/automake.mk
+++ b/python/automake.mk
@@ -34,7 +34,8 @@  ovs_pyfiles = \
 	python/ovs/unixctl/server.py \
 	python/ovs/util.py \
 	python/ovs/version.py \
-	python/ovs/vlog.py
+	python/ovs/vlog.py \
+	python/ovs/winutils.py
 
 # These python files are used at build time but not runtime,
 # so they are not installed.
diff --git a/python/ovs/winutils.py b/python/ovs/winutils.py
new file mode 100644
index 0000000..3a235f8
--- /dev/null
+++ b/python/ovs/winutils.py
@@ -0,0 +1,226 @@ 
+# Copyright (c) 2016 Cloudbase Solutions Srl
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import six
+import sys
+
+if sys.platform != 'win32':
+    raise Exception("Intended to use only on Windows")
+else:
+    import pywintypes
+    import winerror
+    import win32pipe
+    import win32con
+    import win32security
+    import win32file
+    import win32event
+
+
+def close_handle(handle, logger=None):
+    try:
+        win32file.CloseHandle(handle)
+        return None
+    except pywintypes.error as e:
+        if logger is not None:
+            logger("failed to close handle: %s" % e.strerror)
+        return e.winerror
+
+
+def windows_create_pipe(sAttrs=-1, nSize=None):
+    # Default values if parameters are not passed
+    if sAttrs == -1:
+        sAttrs = win32security.SECURITY_ATTRIBUTES()
+        sAttrs.bInheritHandle = 1
+    if nSize is None:
+        # If this parameter is zero, the system uses the default buffer size.
+        nSize = 0
+
+    try:
+        (read_pipe, write_pipe) = win32pipe.CreatePipe(sAttrs, nSize)
+    except pywintypes.error:
+        raise
+
+    return (read_pipe, write_pipe)
+
+
+def windows_read_pipe(fd, length):
+    try:
+        (error, data) = win32file.ReadFile(fd, length)
+        return error, data
+    except pywintypes.error as e:
+        return e.winerror, ""
+
+
+def create_file(filename, desiredAccess=None, shareMode=None, attributes=-1,
+                CreationDisposition=None, flagsAndAttributes=None,
+                hTemplateFile=-1):
+    # Default values if parameters are not passed
+    if desiredAccess is None:
+        desiredAccess = win32file.GENERIC_READ | win32file.GENERIC_WRITE
+    if shareMode is None:
+        shareMode = 0
+    if attributes == -1:
+        # attributes can be None
+        attributes = None
+    if CreationDisposition is None:
+        CreationDisposition = win32file.OPEN_EXISTING
+    if flagsAndAttributes is None:
+        flagsAndAttributes = (win32file.FILE_ATTRIBUTE_NORMAL |
+                              win32file.FILE_FLAG_OVERLAPPED |
+                              win32file.FILE_FLAG_NO_BUFFERING)
+    if hTemplateFile == -1:
+        hTemplateFile = None
+
+    try:
+        npipe = win32file.CreateFile(filename,
+                                     desiredAccess,
+                                     shareMode,
+                                     attributes,
+                                     CreationDisposition,
+                                     flagsAndAttributes,
+                                     hTemplateFile)
+    except pywintypes.error:
+        raise
+    return npipe
+
+
+def write_file(handle, data, overlapped=None):
+    try:
+        (errCode, nBytesWritten) = win32file.WriteFile(handle,
+                                                       data,
+                                                       overlapped)
+        # Note: win32file.WriteFile doesn't throw an exception
+        # in case it receives ERROR_IO_PENDING.
+        return (errCode, nBytesWritten)
+    except pywintypes.error as e:
+        return (e.winerror, 0)
+
+
+def read_file(handle, bufsize, overlapped=None):
+    try:
+        # Note: win32file.ReadFile doesn't throw an exception
+        # in case it receives ERROR_IO_PENDING.
+        (errCode, read_buffer) = win32file.ReadFile(
+            handle, bufsize, overlapped)
+        return (errCode, read_buffer)
+    except pywintypes.error as e:
+        return (e.winerror, "")
+
+
+def create_named_pipe(pipename, openMode=None, pipeMode=None,
+                      nMaxInstances=None, nOutBufferSize=None,
+                      nInBufferSize=None, nDefaultTimeOut=None,
+                      saAttr=-1):
+    # Default values if parameters are not passed
+    if openMode is None:
+        openMode = win32con.PIPE_ACCESS_DUPLEX | win32con.FILE_FLAG_OVERLAPPED
+    if pipeMode is None:
+        pipeMode = (win32con.PIPE_TYPE_MESSAGE |
+                    win32con.PIPE_READMODE_BYTE |
+                    win32con.PIPE_WAIT)
+    if nMaxInstances is None:
+        nMaxInstances = 64
+    if nOutBufferSize is None:
+        nOutBufferSize = 65000
+    if nInBufferSize is None:
+        nInBufferSize = 65000
+    if nDefaultTimeOut is None:
+        nDefaultTimeOut = 0
+    if saAttr == -1:
+        # saAttr can be None
+        saAttr = win32security.SECURITY_ATTRIBUTES()
+        saAttr.bInheritHandle = 1
+
+    try:
+        npipe = win32pipe.CreateNamedPipe(pipename,
+                                          openMode,
+                                          pipeMode,
+                                          nMaxInstances,
+                                          nOutBufferSize,
+                                          nInBufferSize,
+                                          nDefaultTimeOut,
+                                          saAttr)
+
+        if npipe == win32file.INVALID_HANDLE_VALUE:
+            return None
+
+        return npipe
+    except pywintypes.error:
+        return None
+
+
+def set_pipe_mode(hPipe, mode=-1, maxCollectionCount=None,
+                  collectDataTimeout=None):
+    # Default values if parameters are not passed
+    if mode == -1:
+        mode = win32pipe.PIPE_READMODE_BYTE
+    try:
+        win32pipe.SetNamedPipeHandleState(
+            hPipe, mode, maxCollectionCount, collectDataTimeout)
+    except pywintypes.error:
+        raise
+
+
+def connect_named_pipe(pipe_handle, overlapped=None):
+    try:
+        # If the result of ConnectNamedPipe is ERROR_IO_PENDING or
+        # ERROR_PIPE_CONNECTED, then this value is returned.
+        # All other error values raise a win32 exception
+        error = win32pipe.ConnectNamedPipe(pipe_handle, overlapped)
+        return error
+    except pywintypes.error as e:
+        return e.winerror
+
+
+def get_pipe_name(name):
+    name = name.replace('/', '')
+    name = name.replace('\\', '')
+    name = "\\\\.\\pipe\\" + name
+    return name
+
+
+def get_overlapped_result(handle, overlapped=None, bWait=False):
+    try:
+        return win32file.GetOverlappedResult(handle, overlapped, bWait)
+    except pywintypes.error:
+        raise
+
+
+def get_decoded_buffer(recvBuffer):
+    if six.PY3:
+        return bytes(recvBuffer).decode("utf-8")
+    else:
+        return str(recvBuffer)
+
+
+def get_encoded_buffer(buff):
+    # Python 3 has separate types for strings and bytes.
+    # We must have bytes here.
+    if not isinstance(buff, six.binary_type):
+        if six.PY3:
+            buff = six.binary_type(buff, 'utf-8')
+        else:
+            buff = six.binary_type(buff)
+    return buff
+
+
+def get_new_event(sa=None, bManualReset=True, bInitialState=True,
+                  objectName=None):
+    return win32event.CreateEvent(sa, bManualReset, bInitialState, objectName)
+
+
+pipe_disconnected_errors = [winerror.ERROR_PIPE_NOT_CONNECTED,
+                            winerror.ERROR_BAD_PIPE,
+                            winerror.ERROR_NO_DATA,
+                            winerror.ERROR_BROKEN_PIPE]