Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support gRPC 1.46.3 (also fix builds on Darwin) #138

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ examples/echo/echo-cpp/echo-server
benchmarks.html
result
*~
cabal.project.local
cabal.project.local*
dist-newstyle/
tests/py-tmp
tests/tmp
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ have extended and released under the same [`LICENSE`](./LICENSE)
Installation
------------

**The current version of this library requires gRPC version 1.34.1. Newer versions may work but have not been tested.**
**The current version of this library requires gRPC version 1.46.3. Newer versions may work but have not been tested.**

Usage
-----
Expand All @@ -22,7 +22,7 @@ put the completed package into the nix store. `nix-shell` can be used to give
you a development environment where you can use `cabal` for development and
testing:

```bash
``` console
$ nix-shell
[nix-shell]$ cabal configure --enable-tests && cabal build && cabal test
```
Expand Down
4 changes: 2 additions & 2 deletions core/grpc-haskell-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Flag Debug
library
build-depends:
base >=4.8 && <5.0
, clock >=0.6.0 && <0.8.0
, clock >=0.6.0 && <0.9
, bytestring ==0.10.*
, stm >=2.4 && <2.6
, containers >=0.5 && <0.7
Expand Down Expand Up @@ -94,7 +94,7 @@ test-suite tests
, proto3-suite
, transformers
, safe
, clock >=0.6.0 && <0.8.0
, clock >=0.6.0 && <0.9
, turtle >= 1.2.0
, text
, QuickCheck >=2.8 && <3.0
Expand Down
8 changes: 5 additions & 3 deletions core/src/Network/GRPC/LowLevel/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,21 @@ addMetadataCreds c (Just create) = do
createChannel :: ClientConfig -> C.GrpcChannelArgs -> IO C.Channel
createChannel conf@ClientConfig{..} chanargs =
case clientSSLConfig of
Nothing -> C.grpcInsecureChannelCreate e chanargs C.reserved
Nothing ->
C.withInsecureChannelCredentials $ \creds ->
C.grpcChannelCreate e creds chanargs
Just (ClientSSLConfig rootCertPath Nothing plugin) ->
do rootCert <- mapM B.readFile rootCertPath
C.withChannelCredentials rootCert Nothing Nothing $ \creds -> do
creds' <- addMetadataCreds creds plugin
C.secureChannelCreate creds' e chanargs C.reserved
C.grpcChannelCreate e creds' chanargs
Just (ClientSSLConfig x (Just (ClientSSLKeyCertPair y z)) plugin) ->
do rootCert <- mapM B.readFile x
privKey <- Just <$> B.readFile y
clientCert <- Just <$> B.readFile z
C.withChannelCredentials rootCert privKey clientCert $ \creds -> do
creds' <- addMetadataCreds creds plugin
C.secureChannelCreate creds' e chanargs C.reserved
C.grpcChannelCreate e creds' chanargs
where (Endpoint e) = clientEndpoint conf

createClient :: GRPC -> ClientConfig -> IO Client
Expand Down
5 changes: 3 additions & 2 deletions core/src/Network/GRPC/LowLevel/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ serverEndpoint ServerConfig{..} = endpoint host port
addPort :: C.Server -> ServerConfig -> IO Int
addPort server conf@ServerConfig{..} =
case sslConfig of
Nothing -> C.grpcServerAddInsecureHttp2Port server e
Nothing ->
C.withInsecureServerCredentials $ C.grpcServerAddHttp2Port server e
Just ServerSSLConfig{..} ->
do crc <- mapM B.readFile clientRootCert
spk <- B.readFile serverPrivateKey
Expand All @@ -152,7 +153,7 @@ addPort server conf@ServerConfig{..} =
case customMetadataProcessor of
Just p -> C.setMetadataProcessor creds p
Nothing -> return ()
C.serverAddSecureHttp2Port server e creds
C.grpcServerAddHttp2Port server e creds
where e = unEndpoint $ serverEndpoint conf

startServer :: GRPC -> ServerConfig -> IO Server
Expand Down
21 changes: 17 additions & 4 deletions core/src/Network/GRPC/Unsafe.chs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ deriving instance Show Channel
-- | Represents a server. Created on the server side.
{#pointer *grpc_server as Server newtype #}

deriving instance Show Server

-- | A server credentials object that represents a way to authenticate a server.
{#pointer *grpc_server_credentials as ServerCredentials newtype #}

deriving instance Show ServerCredentials

-- | A channel credentials object represents a way to authenticate a client on a
-- channel.
{#pointer *grpc_channel_credentials as ChannelCredentials newtype #}

deriving instance Show ChannelCredentials

-- | Represents a pointer to a call. To users of the gRPC core library, this
-- type is abstract; we have no access to its fields.
{#pointer *grpc_call as Call newtype #}
Expand Down Expand Up @@ -194,8 +207,8 @@ castPeek p = do
-- are expected to pass a 'nullPtr' for the 'ChannelArgsPtr'. We currently don't
-- expose any functions for creating channel args, since they are entirely
-- undocumented.
{#fun grpc_insecure_channel_create as ^
{useAsCString* `ByteString', `GrpcChannelArgs', unReserved `Reserved'} -> `Channel'#}
{#fun grpc_channel_create as ^
{useAsCString* `ByteString', `ChannelCredentials', `GrpcChannelArgs'} -> `Channel'#}

{#fun grpc_channel_register_call as ^
{`Channel', useAsCString* `ByteString',useAsCString* `ByteString',unReserved `Reserved'}
Expand Down Expand Up @@ -258,8 +271,8 @@ getPeerPeek cstr = do
{#fun grpc_server_register_completion_queue as ^
{`Server', `CompletionQueue', unReserved `Reserved'} -> `()'#}

{#fun grpc_server_add_insecure_http2_port as ^
{`Server', useAsCString* `ByteString'} -> `Int'#}
{#fun grpc_server_add_http2_port as ^
{`Server', useAsCString* `ByteString', `ServerCredentials'} -> `Int'#}

-- | Starts a server. To shut down the server, call these in order:
-- 'grpcServerShutdownAndNotify', 'grpcServerCancelAllCalls',
Expand Down
24 changes: 11 additions & 13 deletions core/src/Network/GRPC/Unsafe/Security.chs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import Network.GRPC.LowLevel.GRPC.MetadataMap (MetadataMap)
#include <grpc_haskell.h>

{#import Network.GRPC.Unsafe#}
{#import Network.GRPC.Unsafe.ChannelArgs#}
{#import Network.GRPC.Unsafe.Metadata#}
{#import Network.GRPC.Unsafe.Op#}

Expand Down Expand Up @@ -49,10 +48,6 @@ instance Storable AuthContext where

{#pointer *call_credentials as ^ newtype#}

{#pointer *channel_credentials as ^ newtype#}

{#pointer *server_credentials as ^ newtype#}

withAuthPropertyIterator :: AuthContext
-> (AuthPropertyIterator -> IO a)
-> IO a
Expand Down Expand Up @@ -169,6 +164,8 @@ getAuthProperties ctx = withAuthPropertyIterator ctx $ \i -> do
{#fun unsafe ssl_credentials_create_internal as ^
{`CString', `CString', `CString'} -> `ChannelCredentials'#}

{#fun insecure_credentials_create as ^ {} -> `ChannelCredentials'#}

sslChannelCredentialsCreate :: Maybe ByteString
-> Maybe ByteString
-> Maybe ByteString
Expand All @@ -195,6 +192,10 @@ withChannelCredentials :: Maybe ByteString
withChannelCredentials x y z = bracket (sslChannelCredentialsCreate x y z)
channelCredentialsRelease

withInsecureChannelCredentials :: (ChannelCredentials -> IO a) -> IO a
withInsecureChannelCredentials =
bracket (insecureCredentialsCreate) channelCredentialsRelease

-- * Call Credentials

{#fun call_set_credentials as ^
Expand All @@ -219,6 +220,8 @@ withChannelCredentials x y z = bracket (sslChannelCredentialsCreate x y z)
`SslClientCertificateRequestType'}
-> `ServerCredentials'#}

{#fun insecure_server_credentials_create as ^ {} -> `ServerCredentials'#}

sslServerCredentialsCreate :: Maybe ByteString
-- ^ PEM encoding of the client root certificates.
-- Can be 'Nothing' if SSL authentication of
Expand Down Expand Up @@ -250,14 +253,9 @@ withServerCredentials :: Maybe ByteString
withServerCredentials a b c d = bracket (sslServerCredentialsCreate a b c d)
serverCredentialsRelease

-- * Creating Secure Clients/Servers

{#fun server_add_secure_http2_port as ^
{`Server',useAsCString* `ByteString', `ServerCredentials'} -> `Int'#}

{#fun secure_channel_create as ^
{`ChannelCredentials',useAsCString* `ByteString', `GrpcChannelArgs', unReserved `Reserved'}
-> `Channel'#}
withInsecureServerCredentials :: (ServerCredentials -> IO a) -> IO a
withInsecureServerCredentials =
bracket (insecureServerCredentialsCreate) serverCredentialsRelease

-- * Custom metadata processing -- server side

Expand Down
2 changes: 1 addition & 1 deletion grpc-haskell.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ test-suite tests
, proto3-suite
, transformers
, safe
, clock >=0.6.0 && <0.8.0
, clock >=0.6.0 && <0.9
, turtle >= 1.2.0
, text
, QuickCheck >=2.10 && <3.0
Expand Down
16 changes: 16 additions & 0 deletions nix/data-diverse.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{ mkDerivation, base, containers, criterion, deepseq, ghc-prim
, hspec, lib, tagged
}:
mkDerivation {
pname = "data-diverse";
version = "4.7.0.0";
sha256 = "sha256-w82WWNWbShoYYtDFvJHgQUb1vxEehGmgUOpq4SZaizE=";
libraryHaskellDepends = [
base containers deepseq ghc-prim tagged
];
testHaskellDepends = [ base hspec tagged ];
benchmarkHaskellDepends = [ base criterion ];
homepage = "https://github.com/louispan/data-diverse#readme";
description = "Extensible records and polymorphic variants";
license = lib.licenses.bsd3;
}
108 changes: 108 additions & 0 deletions nix/grpc-pin/grpc.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copy-paste from nixpkgs “release-22.05” branch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need to pin grpc.nix if nixpkgs.nix now uses release-22.05?

Same question for the other grpc-related pins

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Gabriella439 technically no but the library is often used with different nixpkgs pins, not one provided by gRPC-haskell. So gRPC version can be different, thus there can be breaking changes. This feels more reliable to provide fixed pin of gRPC version this library specifically is built for.


{ lib
, stdenv
, fetchFromGitHub
, fetchpatch
, buildPackages
, cmake
, zlib
, c-ares
, pkg-config
, re2
, openssl
, protobuf
, grpc
, abseil-cpp
, libnsl

# tests
, python3
}:

stdenv.mkDerivation rec {
pname = "grpc";
version = "1.46.3"; # N.B: if you change this, please update:
# pythonPackages.grpcio-tools
# pythonPackages.grpcio-status

src = fetchFromGitHub {
owner = "grpc";
repo = "grpc";
rev = "v${version}";
sha256 = "sha256-RiXtKlRtlbqwrSxI904dgSu3da0A6Fwk+/hWHIG7A5E=";
fetchSubmodules = true;
};

patches = [
# Fix build on armv6l (https://github.com/grpc/grpc/pull/21341)
(fetchpatch {
url = "https://github.com/grpc/grpc/commit/2f4cf1d9265c8e10fb834f0794d0e4f3ec5ae10e.patch";
sha256 = "0ams3jmgh9yzwmxcg4ifb34znamr7pb4qm0609kvil9xqvkqz963";
})

# Revert gRPC C++ Mutex to be an alias of Abseil, because it breaks dependent packages
(fetchpatch {
url = "https://github.com/grpc/grpc/commit/931f91b745cd5b2864a0d1787815871d0bd844ae.patch";
sha256 = "0vc93g2i4982ys4gzyaxdv9ni25yk10sxq3n7fkz8dypy8sylck7";
revert = true;
})
];

nativeBuildInputs = [ cmake pkg-config ]
++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) grpc;
propagatedBuildInputs = [ c-ares re2 zlib abseil-cpp ];
buildInputs = [ c-ares.cmake-config openssl protobuf ]
++ lib.optionals stdenv.isLinux [ libnsl ];

cmakeFlags = [
"-DgRPC_ZLIB_PROVIDER=package"
"-DgRPC_CARES_PROVIDER=package"
"-DgRPC_RE2_PROVIDER=package"
"-DgRPC_SSL_PROVIDER=package"
"-DgRPC_PROTOBUF_PROVIDER=package"
"-DgRPC_ABSL_PROVIDER=package"
"-DBUILD_SHARED_LIBS=ON"
"-DCMAKE_SKIP_BUILD_RPATH=OFF"
] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
"-D_gRPC_PROTOBUF_PROTOC_EXECUTABLE=${buildPackages.protobuf}/bin/protoc"
] ++ lib.optionals ((stdenv.hostPlatform.useLLVM or false) && lib.versionOlder stdenv.cc.cc.version "11.0") [
# Needs to be compiled with -std=c++11 for clang < 11. Interestingly this is
# only an issue with the useLLVM stdenv, not the darwin stdenv…
# https://github.com/grpc/grpc/issues/26473#issuecomment-860885484
"-DCMAKE_CXX_STANDARD=11"
];

# CMake creates a build directory by default, this conflicts with the
# basel BUILD file on case-insensitive filesystems.
preConfigure = ''
rm -vf BUILD
'';

# When natively compiling, grpc_cpp_plugin is executed from the build directory,
# needing to load dynamic libraries from the build directory, so we set
# LD_LIBRARY_PATH to enable this. When cross compiling we need to avoid this,
# since it can cause the grpc_cpp_plugin executable from buildPackages to
# crash if build and host architecture are compatible (e. g. pkgsLLVM).
preBuild = lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform) ''
export LD_LIBRARY_PATH=$(pwd)''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
'';

NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isClang "-Wno-error=unknown-warning-option"
+ lib.optionalString stdenv.isAarch64 "-Wno-error=format-security";

enableParallelBuilds = true;

passthru.tests = {
inherit (python3.pkgs) grpcio-status grpcio-tools;
};

meta = with lib; {
description = "The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)";
license = licenses.asl20;
maintainers = with maintainers; [ lnl7 marsam ];
homepage = "https://grpc.io/";
platforms = platforms.all;
changelog = "https://github.com/grpc/grpc/releases/tag/v${version}";
};
}
43 changes: 43 additions & 0 deletions nix/grpc-pin/grpcio-status.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copy-paste from nixpkgs “release-22.05” branch

{ lib
, buildPythonPackage
, fetchPypi
, googleapis-common-protos
, grpcio
, protobuf
, pythonOlder
}:

buildPythonPackage rec {
pname = "grpcio-status";
version = "1.46.3";
format = "setuptools";

disabled = pythonOlder "3.6";

src = fetchPypi {
inherit pname version;
sha256 = "78442ac7d2813c56f9cc04f713efd7088596b10f88a4ddd09279211cc48402d5";
};

propagatedBuildInputs = [
googleapis-common-protos
grpcio
protobuf
];

# Projec thas no tests
doCheck = false;

pythonImportsCheck = [
"grpc_status"
];

meta = with lib; {
description = "GRPC Python status proto mapping";
homepage = "https://github.com/grpc/grpc/tree/master/src/python/grpcio_status";
license = licenses.asl20;
maintainers = with maintainers; [ fab ];
};
}
Loading