From 02da0726e496bd2dd97105a5cef67e4624b3a47d Mon Sep 17 00:00:00 2001 From: UENISHI Kota Date: Wed, 5 Nov 2014 18:29:57 +0900 Subject: [PATCH] First packaged basho_bench Through the effort to make smaller package, several changes to the code and dependent modules were done: - dependent modules updated; lager, mochiweb and getopt - some dependent modules removed; erlcql, velvet, casbench - deprecate R15 Andalso, there are some kludge to enable package install with node_package; - not using escriptize but just a proxy script installed - unnecessary directories like log, data created - unnecessary user and group named basho-bench created for this - not pinning dependent module versions yet --- .gitignore | 5 +- Makefile | 12 +- pkg.vars.config | 16 +-- rebar.config | 22 ++-- rel/files/basho_bench | 9 ++ rel/files/install_upgrade.escript | 44 +++++++ rel/files/vm.args | 19 +++ rel/reltool.config | 63 ++++++++++ rel/vars.config | 20 ++++ src/basho_bench.app.src | 2 +- src/basho_bench.erl | 2 +- src/basho_bench_driver_cassandra.erl | 125 -------------------- src/basho_bench_driver_cassandra_cql.erl | 142 ----------------------- src/basho_bench_driver_cs.erl | 6 +- 14 files changed, 187 insertions(+), 300 deletions(-) create mode 100755 rel/files/basho_bench create mode 100644 rel/files/install_upgrade.escript create mode 100644 rel/files/vm.args create mode 100644 rel/reltool.config create mode 100644 rel/vars.config delete mode 100644 src/basho_bench_driver_cassandra.erl delete mode 100644 src/basho_bench_driver_cassandra_cql.erl diff --git a/.gitignore b/.gitignore index 5d78da55e..44e26ca49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ ebin/ deps/ tests/ -basho_bench +/basho_bench +/rel/basho_bench +package +.rebar *~ #*# diff --git a/Makefile b/Makefile index dac17e54c..dd54188f5 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ REPO ?= basho_bench PKG_REVISION ?= $(shell git describe --tags) PKG_VERSION ?= $(shell git describe --tags | tr - .) -PKG_ID = bashobench-$(PKG_VERSION) +PKG_ID = basho-bench-$(PKG_VERSION) PKG_BUILD = 1 BASE_DIR = $(shell pwd) ERLANG_BIN = $(shell dirname $(shell which erl)) @@ -10,14 +10,14 @@ REBAR ?= $(BASE_DIR)/rebar OVERLAY_VARS ?= -.PHONY: deps - -rel: deps compile - ./rebar skip_deps=true escriptize - all: deps compile ./rebar skip_deps=true escriptize +.PHONY: deps compile rel + +rel: deps compile + cd rel && ../rebar generate skip_deps=true $(OVERLAY_VARS) + deps: ./rebar get-deps diff --git a/pkg.vars.config b/pkg.vars.config index 005e34f31..0377c816e 100644 --- a/pkg.vars.config +++ b/pkg.vars.config @@ -4,21 +4,21 @@ %% %% Packaging %% -{package_name, "bashobench"}. -{package_install_name, "bashobench"}. -{package_install_user, "bashobench"}. -{package_install_group, "bashobench"}. +{package_name, "basho-bench"}. +{package_install_name, "basho_bench"}. +{package_install_user, "basho-bench"}. +{package_install_group, "basho-bench"}. {package_install_user_desc, "Basho-bench user"}. -{package_shortdesc, "Bashobench benchmarking tool"}. +{package_shortdesc, "Basho benchmarking tool"}. {package_desc, "Benchmarking tool"}. -{package_commands, {list, [[{name, "bashobench"}]]}}. +{package_commands, {list, [[{name, "basho_bench"}]]}}. {package_patch_dir, "basho-patches"}. {bin_or_sbin, "bin"}. {license_type, "OSS"}. -{copyright, "2013 Basho Technologies, Inc"}. +{copyright, "2014 Basho Technologies, Inc"}. {vendor_name, "Basho Technologies, Inc"}. {vendor_url, "http://basho.com"}. {vendor_contact_name, "Basho Package Maintainer"}. {vendor_contact_email, "packaging@basho.com"}. {license_full_text, "This software is provided under license from Basho Technologies."}. -{solaris_pkgname, "BASHObashobench"}. +{solaris_pkgname, "BASHObasho-bench"}. diff --git a/rebar.config b/rebar.config index f6633dc80..82a48d5cf 100644 --- a/rebar.config +++ b/rebar.config @@ -1,3 +1,4 @@ +{require_otp_vsn, "R16|17"}. {deps, [ @@ -8,32 +9,23 @@ %% increments. If someone wants to take advantage of a %% new folsom feature, that desire + float incr must be %% weighed. - {node_package, "1.2.2", {git, "git://github.com/basho/node_package", {tag, "1.2.2"}}}, + {node_package, "2.0.*", {git, "git://github.com/basho/node_package", {tag, "2.0.0"}}}, {folsom, ".*", {git, "git://github.com/basho/folsom.git", {branch, "boundary-0.7.1+basho-bench-float"}}}, - {lager, "2.*", {git, "git://github.com/basho/lager", {tag, "2.0.3"}}}, + {lager, "2.*", {git, "git://github.com/basho/lager", {tag, "2.1.0"}}}, {ibrowse, ".*", {git, "git://github.com/cmullaparthi/ibrowse.git", {tag, "v3.0.4"}}}, - {casbench, "0.1", - {git, "git://github.com/basho/casbench", - "95ed55b494551577870984aeb1e0f683631a326f"}}, - {erlcql, ".*", - {git, "git://github.com/rpt/erlcql.git", - {branch, "master"}}}, {riakc, ".*", {git, "git://github.com/basho/riak-erlang-client", {branch, "develop"}}}, - {mochiweb, "1.5.1*", - {git, "git://github.com/basho/mochiweb", {tag, "1.5.1p6"}}}, - {velvet, "1.*", - {git, "git://github.com/basho/velvet", - "4bb0fd664ff065c4082ca8dd2e0683e920537d15"}}, + {mochiweb, "2.9.*", + {git, "git://github.com/basho/mochiweb", {tag, "v2.9.0"}}}, {getopt, ".*", - {git, "git://github.com/jcomellas/getopt", {tag, "v0.4"}}} + {git, "git://github.com/jcomellas/getopt", {tag, "v0.8.2"}}} ]}. {erl_opts, [{src_dirs, [src]}, {parse_transform, lager_transform}]}. -{escript_incl_apps, [node_package, lager, getopt, bear, folsom, ibrowse, riakc, mochiweb, protobuffs, velvet, goldrush]}. +{escript_incl_apps, [node_package, lager, getopt, bear, folsom, ibrowse, riakc, mochiweb, protobuffs, goldrush]}. {escript_emu_args, "%%! +K true -rsh ssh\n"}. %% Use this for the Java client bench driver diff --git a/rel/files/basho_bench b/rel/files/basho_bench new file mode 100755 index 000000000..c67d139b7 --- /dev/null +++ b/rel/files/basho_bench @@ -0,0 +1,9 @@ +#!/bin/sh + +# Pull environment for this install +. "{{runner_base_dir}}/lib/env.sh" + +# Make sure CWD is set to runner run dir +cd $RUNNER_BASE_DIR/lib/basho_bench*/ebin + +ERL_LIBS=$RUNNER_BASE_DIR $ERTS_PATH/escript basho_bench.beam "$@" diff --git a/rel/files/install_upgrade.escript b/rel/files/install_upgrade.escript new file mode 100644 index 000000000..56cea1963 --- /dev/null +++ b/rel/files/install_upgrade.escript @@ -0,0 +1,44 @@ +#!/usr/bin/env escript +%%! -noshell -noinput +%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% ex: ft=erlang ts=4 sw=4 et + +-define(TIMEOUT, 60000). +-define(INFO(Fmt,Args), io:format(Fmt,Args)). + +main([NodeName, Cookie, ReleasePackage]) -> + TargetNode = start_distribution(NodeName, Cookie), + {ok, Vsn} = rpc:call(TargetNode, release_handler, unpack_release, + [ReleasePackage], ?TIMEOUT), + ?INFO("Unpacked Release ~p~n", [Vsn]), + {ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler, + check_install_release, [Vsn], ?TIMEOUT), + {ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler, + install_release, [Vsn], ?TIMEOUT), + ?INFO("Installed Release ~p~n", [Vsn]), + ok = rpc:call(TargetNode, release_handler, make_permanent, [Vsn], ?TIMEOUT), + ?INFO("Made Release ~p Permanent~n", [Vsn]); +main(_) -> + init:stop(1). + +start_distribution(NodeName, Cookie) -> + MyNode = make_script_node(NodeName), + {ok, _Pid} = net_kernel:start([MyNode, shortnames]), + erlang:set_cookie(node(), list_to_atom(Cookie)), + TargetNode = make_target_node(NodeName), + case {net_kernel:hidden_connect_node(TargetNode), + net_adm:ping(TargetNode)} of + {true, pong} -> + ok; + {_, pang} -> + io:format("Node ~p not responding to pings.\n", [TargetNode]), + init:stop(1) + end, + TargetNode. + +make_target_node(Node) -> + [_, Host] = string:tokens(atom_to_list(node()), "@"), + list_to_atom(lists:concat([Node, "@", Host])). + +make_script_node(Node) -> + list_to_atom(lists:concat([Node, "_upgrader_", os:getpid()])). diff --git a/rel/files/vm.args b/rel/files/vm.args new file mode 100644 index 000000000..cce3b816f --- /dev/null +++ b/rel/files/vm.args @@ -0,0 +1,19 @@ +## Name of the node +-name healthb@127.0.0.1 + +## Cookie for distributed erlang +-setcookie healthb + +## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive +## (Disabled by default..use with caution!) +##-heart + +## Enable kernel poll and a few async threads +##+K true +##+A 5 + +## Increase number of concurrent ports/sockets +##-env ERL_MAX_PORTS 4096 + +## Tweak GC to run more often +##-env ERL_FULLSWEEP_AFTER 10 diff --git a/rel/reltool.config b/rel/reltool.config new file mode 100644 index 000000000..e60cfc75f --- /dev/null +++ b/rel/reltool.config @@ -0,0 +1,63 @@ +%% -*- mode: erlang -*- +%% ex: ft=erlang +{sys, [ + {lib_dirs, ["../deps"]}, + {erts, [{mod_cond, derived}, {app_file, strip}]}, + {app_file, strip}, + {rel, "basho_bench", "0.10.0", + [ + kernel, + stdlib, + bear, + lager, + folsom, + goldrush, + riakc, + ibrowse, + mochiweb + ]}, + {rel, "start_clean", "", + [ + kernel, + stdlib + ]}, + {boot_rel, "basho_bench"}, + {profile, embedded}, + {incl_cond, derived}, + {excl_archive_filters, [".*"]}, %% Do not archive built libs + {excl_sys_filters, ["^bin/(?!start_clean.boot)", + "^erts.*/bin/(dialyzer|typer)", + "^erts.*/(doc|info|include|lib|man|src)"]}, + {excl_app_filters, ["\.gitignore"]}, + {app, basho_bench, [{mod_cond, app}, {incl_cond, include}, {lib_dir, ".."}]}, + {app, hipe, [{incl_cond, exclude}]} + ]}. + +{target_dir, "basho_bench"}. +{overlay_vars, "vars.config"}. + +{overlay, [ + {template, "../deps/node_package/priv/base/env.sh", + "lib/env.sh"}, + {mkdir, "data/b_b"}, + + %% Copy base files for starting and interacting w/ node + {copy, "../deps/node_package/priv/base/erl", + "{{erts_vsn}}/bin/erl"}, + {copy, "../deps/node_package/priv/base/nodetool", + "{{erts_vsn}}/bin/nodetool"}, + {template, "../deps/node_package/priv/base/env.sh", + "lib/env.sh"}, + {copy, "files/vm.args", "etc/vm.args"}, + + {template, "files/basho_bench", "bin/basho_bench"}, + + {copy, "../examples/cs.config.sample", "etc/cs.config"}, + {copy, "../examples/riakc_pb.config", "etc/riakc_pb.config"}, + {copy, "../examples/httpraw.config", "etc/httpraw.config"}, + {copy, "../examples/http.config", "etc/http.config"}, + {copy, "../examples/null_test.config", "etc/null_test.config"} + + %%{copy, "files/install_upgrade.escript", "bin/install_upgrade.escript"}, + + ]}. diff --git a/rel/vars.config b/rel/vars.config new file mode 100644 index 000000000..00ff42b68 --- /dev/null +++ b/rel/vars.config @@ -0,0 +1,20 @@ +%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% ex: ts=4 sw=4 et + +%% Platform-specific installation paths +{platform_bin_dir, "./bin"}. +{platform_data_dir, "./data"}. +{platform_etc_dir, "./etc"}. +{platform_lib_dir, "./lib"}. +{platform_log_dir, "./log"}. + +%% +{data_dir, "{{target_dir}}/data"}. +{runner_script_dir, "\`cd \\`dirname $0\\` && /bin/pwd\`"}. +{runner_base_dir, "{{runner_script_dir}}/.."}. +{runner_etc_dir, "$RUNNER_BASE_DIR/etc"}. +{runner_log_dir, "$RUNNER_BASE_DIR/log"}. +{runner_lib_dir, "$RUNNER_BASE_DIR/lib"}. +{runner_patch_dir, "$RUNNER_BASE_DIR/lib/basho-patches"}. +{pipe_dir, "/tmp/$RUNNER_BASE_DIR/"}. +{runner_user, ""}. diff --git a/src/basho_bench.app.src b/src/basho_bench.app.src index ee35ab0d5..1c3c74974 100644 --- a/src/basho_bench.app.src +++ b/src/basho_bench.app.src @@ -1,6 +1,6 @@ {application, basho_bench, [{description, "Riak Benchmarking Suite"}, - {vsn, "0.9"}, + {vsn, git}, {modules, []}, {registered, [ basho_bench_sup ]}, {applications, [kernel, diff --git a/src/basho_bench.erl b/src/basho_bench.erl index 38391bab9..0609418fc 100644 --- a/src/basho_bench.erl +++ b/src/basho_bench.erl @@ -307,7 +307,7 @@ setup_distributed_work() -> [pool:attach(SlaveName) || SlaveName <- SlaveNames], CodePaths = code:get_path(), rpc:multicall(SlaveNames, code, set_path, [CodePaths]), - Apps = [lager, basho_bench, getopt, bear, folsom, ibrowse, riakc, riak_pb, mochiweb, protobuffs, velvet, goldrush], + Apps = [lager, basho_bench, getopt, bear, folsom, ibrowse, riakc, riak_pb, mochiweb, protobuffs, goldrush], [distribute_app(App) || App <- Apps]. diff --git a/src/basho_bench_driver_cassandra.erl b/src/basho_bench_driver_cassandra.erl deleted file mode 100644 index c9946cb6b..000000000 --- a/src/basho_bench_driver_cassandra.erl +++ /dev/null @@ -1,125 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% basho_bench: Benchmarking Suite -%% -%% Copyright (c) 2009-2010 Basho Techonologies -%% -%% This file is provided to you 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. -%% -%% ------------------------------------------------------------------- --module(basho_bench_driver_cassandra). - --export([new/1, - run/4]). - --include("basho_bench.hrl"). --include_lib("casbench/include/cassandra_thrift.hrl"). - --record(state, { client, - keyspace, - colpath, - conlevel - }). - - -%% ==================================================================== -%% API -%% ==================================================================== - -new(Id) -> - %% Make sure the path is setup such that we can get at riak_client - case code:which(cassandra_thrift) of - non_existing -> - ?FAIL_MSG("~s requires cassandra_thrift module to be available on code path.\n", - [?MODULE]); - _ -> - ok - end, - - Hosts = basho_bench_config:get(cassandra_hosts, ["localhost"]), - Port = basho_bench_config:get(cassandra_port, 9160), - Keyspace = basho_bench_config:get(cassandra_keyspace, "Keyspace1"), - ColPath = #columnPath { column_family = "Standard1", column = "col1" }, - ConLevel = basho_bench_config:get(cassandra_consistencylevel, 1), - - %% Choose the node using our ID as a modulus - TargetHost = lists:nth((Id rem length(Hosts)+1), Hosts), - ?INFO("Using target ~s:~p for worker ~p\n", [TargetHost, Port, Id]), - - case thrift_client:start_link(TargetHost, Port, cassandra_thrift) of - {ok, Client} -> - {ok, #state { client = Client, - keyspace = Keyspace, - colpath = ColPath, - conlevel = ConLevel }}; - {error, Reason} -> - ?FAIL_MSG("Failed to get a thrift_client for ~p: ~p\n", [TargetHost, Reason]) - end. - -call(State, Op, Args) -> - (catch thrift_client:call(State#state.client, Op, Args)). - -tstamp() -> - {Mega, Sec, _Micro} = now(), - (Mega * 1000000) + Sec. - - -run(get, KeyGen, _ValueGen, - #state{keyspace=KeySpace, colpath=ColPath, conlevel=ConLevel}=State) -> - Key = KeyGen(), - Args = [KeySpace, Key, ColPath, ConLevel], - case call(State, get, Args) of - {ok, _} -> - {ok, State}; - {notFoundException} -> - %% DEBUG io:format("g(~p)",[Key]), - io:format("g"), - {ok, State}; - {'EXIT', {timeout, _}} -> - {error, timeout, State}; - Error -> - {error, Error, State} - end; -run(put, KeyGen, ValueGen, - #state{keyspace=KeySpace, colpath=ColPath, conlevel=ConLevel}=State) -> - Key = KeyGen(), - Val = ValueGen(), - TS = tstamp(), - Args = [KeySpace, Key, ColPath, Val, TS, ConLevel], - case call(State, insert, Args) of - {ok, ok} -> - {ok, State}; - {'EXIT', {timeout, _}} -> - {error, timeout, State}; - Error -> - {error, Error, State} - end; -run(delete, KeyGen, _ValueGen, - #state{keyspace=KeySpace, colpath=ColPath, conlevel=ConLevel}=State) -> - Key = KeyGen(), - TS = 0, %% TBD: cannot specify a "known" timestamp value? - Args = [KeySpace, Key, ColPath, TS, ConLevel], - case call(State, remove, Args) of - {ok, _} -> - {ok, State}; - {notFoundException} -> - %% DEBUG io:format("d(~p)",[Key]), - io:format("d"), - {ok, State}; - {'EXIT', {timeout, _}} -> - {error, timeout, State}; - Error -> - {error, Error, State} - end. diff --git a/src/basho_bench_driver_cassandra_cql.erl b/src/basho_bench_driver_cassandra_cql.erl deleted file mode 100644 index 63c062077..000000000 --- a/src/basho_bench_driver_cassandra_cql.erl +++ /dev/null @@ -1,142 +0,0 @@ -%% ------------------------------------------------------------------- -%% -%% basho_bench: Benchmarking Suite -%% -%% Copyright (c) 2009-2012 Basho Techonologies -%% -%% This file is provided to you 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. -%% -%% ------------------------------------------------------------------- --module(basho_bench_driver_cassandra_cql). - --export([new/1, - run/4]). - --include("basho_bench.hrl"). - --record(state, { client, - keyspace, - columnfamily, - column - }). - - -%% ==================================================================== -%% API -%% ==================================================================== - -new(Id) -> - Host = basho_bench_config:get(cassandra_host, "localhost"), - Port = basho_bench_config:get(cassandra_port, 9042), - Keyspace = basho_bench_config:get(cassandra_keyspace, "Keyspace1"), - ColumnFamily = basho_bench_config:get(cassandra_columnfamily, "ColumnFamily1"), - Column = basho_bench_config:get(cassandra_column, "Column"), - - % connect to client - {ok, C} = erlcql:start_link(Host, [{port, Port}]), - error_logger:info_msg("Id: ~p, " - "Connected to Cassandra at Host ~p and Port ~p\n", [Id, Host, Port]), - - - case ksbarrier(C, Keyspace) of - ok -> - {ok, #state { client = C, - keyspace = Keyspace, - columnfamily = ColumnFamily, - column = Column}}; - {error, Reason} -> - error_logger:error_msg("Failed to get a erlcql client for ~p: ~p\n", - [Host, Reason]) - end. - - -ksbarrier(C, Keyspace) -> - case erlcql:q(C, lists:concat(["USE ", Keyspace, ";"])) of - {ok, _KSBin} -> ok; - {error, not_ready} -> - %% Not ready yet, try again - timer:sleep(100), - ksbarrier(C, Keyspace); - {error, _} = Error -> - Error - end. - -run(get, KeyGen, _ValueGen, - #state{client=C, columnfamily=ColumnFamily, column=Column}=State) -> - Key = KeyGen(), - Query = ["SELECT ", Column ," FROM ", ColumnFamily ," where KEY = '", Key ,"';"], - case erlcql:q(C, Query, one) of - {ok,void} -> - {ok, State}; - {ok, {_Rows, _Cols}} -> - {ok, State}; - Error -> - {error, Error, State} - end; -run(insert, KeyGen, ValueGen, - #state{client=C, columnfamily=ColumnFamily, column=Column}=State) -> - Key = KeyGen(), - Val = ValueGen(), - Query = ["INSERT INTO ", ColumnFamily , - " (KEY, ", Column, ") VALUES " - "('", Key ,"', ", bin_to_hexstr(Val) ,");"], - - case erlcql:q(C, Query, any) of - {ok,void} -> - {ok, State}; - {ok, {_Rows, _Cols}} -> - {ok, State}; - Error -> - {error, Error, State} - end; -run(put, KeyGen, ValueGen, - #state{client=C, columnfamily=ColumnFamily, column=Column}=State) -> - Key = KeyGen(), - Val = ValueGen(), - Query = ["UPDATE ", ColumnFamily, - " SET ", Column, " = ", bin_to_hexstr(Val), - " WHERE KEY = '", Key, "';"], - - case erlcql:q(C, Query, any) of - {ok,void} -> - {ok, State}; - {ok, {_Rows, _Cols}} -> - {ok, State}; - Error -> - {error, Error, State} - end; -run(delete, KeyGen, _ValueGen, - #state{client=C, columnfamily=ColumnFamily}=State) -> - Key = KeyGen(), - Query = ["DELETE FROM ", ColumnFamily ," WHERE KEY = '", Key ,"';"], - case erlcql:q(C, Query, any) of - {ok,void} -> - {ok, State}; - {ok, {_Rows, _Cols}} -> - {ok, State}; - Error -> - {error, Error, State} - end. - -%% Internal Functions - -hex(N) when N < 10 -> - $0+N; -hex(N) when N >= 10, N < 16 -> - $a+(N-10). - -bin_to_hexstr(Bin) -> - List = binary_to_list(Bin), - ["0x", [ [hex(N div 16), hex(N rem 16)] || N <- List, N < 256 ] ]. diff --git a/src/basho_bench_driver_cs.erl b/src/basho_bench_driver_cs.erl index b4c20f1a9..10a94927b 100644 --- a/src/basho_bench_driver_cs.erl +++ b/src/basho_bench_driver_cs.erl @@ -569,11 +569,15 @@ auth_sig(AccessKey, SecretKey, Method, ContentType, Date, Headers, Resource) -> CanonizedAmzHeaders, Resource ], - Signature = base64:encode(stanchion_utils:sha_mac(SecretKey, StringToSign)), + Signature = base64:encode(sha_mac(SecretKey, StringToSign)), ["AWS ", AccessKey, $:, Signature]. %% CS utilities +%% @doc copied from stanchion_utils +sha_mac(KeyData, STS) -> + crypto:hmac(sha, KeyData, STS). + setup_user_and_bucket(State) -> case basho_bench_config:get(cs_access_key, undefined) of undefined ->