History log of /openbmc/bmcweb/features/redfish/lib/update_service.hpp (Results 51 – 75 of 172)
Revision Date Author Comments
# f86bcc87 25-Aug-2023 Ed Tanous <edtanous@google.com>

Clean up tftp update to use URL

Similar to transforms we've done elsewhere, we shouldn't be parsing
urls using std::string::find, regex, or anything else, as they don't
handle URL % encoding properl

Clean up tftp update to use URL

Similar to transforms we've done elsewhere, we shouldn't be parsing
urls using std::string::find, regex, or anything else, as they don't
handle URL % encoding properly.

Change-Id: I48bb30c0c737c4df2ae73f40fc49c63bac5b658f
Signed-off-by: Ed Tanous <edtanous@google.com>

show more ...


# 8ece0e45 02-Jan-2024 Ed Tanous <ed@tanous.net>

Fix spelling mistakes

These were found with:
codespell -w $(git ls-files | grep "\.[hc]\(pp\)\?$")

At some point in the future, we might want to get this enabled in CI.

Change-Id: Iccb57b2adfd06a2

Fix spelling mistakes

These were found with:
codespell -w $(git ls-files | grep "\.[hc]\(pp\)\?$")

At some point in the future, we might want to get this enabled in CI.

Change-Id: Iccb57b2adfd06a2e177e99db2923fe4e8e329118
Signed-off-by: Ed Tanous <ed@tanous.net>

show more ...


# 5a39f77a 20-Oct-2023 Patrick Williams <patrick@stwcx.xyz>

clang-format: copy latest and re-format

clang-format-17 has some backwards incompatible changes that require
additional settings for best compatibility and re-running the formatter.
Copy the latest

clang-format: copy latest and re-format

clang-format-17 has some backwards incompatible changes that require
additional settings for best compatibility and re-running the formatter.
Copy the latest .clang-format from the docs repository and reformat the
repository.

Change-Id: I2f9540cf0d545a2da4d6289fc87b754f684bc9a7
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>

show more ...


# 4034a652 17-Aug-2023 Myung Bae <myungbae@us.ibm.com>

Ignore Non-software-related events during Update

During code update, if another application (e.g. pldm[1]) logs an error
unrelated to code update, this triggers an error event notification
and cause

Ignore Non-software-related events during Update

During code update, if another application (e.g. pldm[1]) logs an error
unrelated to code update, this triggers an error event notification
and causes the code update failure.

```
$ uri=$(curl -k https://${bmc}/redfish/v1/UpdateService | jq -r ' .HttpPushUri'); echo $uri
$ curl -k -H "Content-Type: application/octet-stream" -X POST -T ${image} https://${bmc}${uri}
{
"error": {
...
"code": "Base.1.13.0.InternalError",
"message": "The request failed due to an internal service error. The service is still operational."
}
}
```

This commit is to filter out those non-update-related error events
from concluding the code update as failure.

The valid update-related errors are defined in
- https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Software/Version.errors.yaml
- https://github.com/openbmc/phosphor-bmc-code-mgmt/blob/master/xyz/openbmc_project/Software/Image.errors.yaml

Tested:

1) Redfish validator passed

2) Error injection during Update.

- Start the code update and wait for completion of update (e.g. using journalctl -f)

```
$ uri=$(curl -k https://${bmc}/redfish/v1/UpdateService | jq -r ' .HttpPushUri'); echo $uri
$ curl -k -H "Content-Type: application/octet-stream" -X POST -T ${image} https://${bmc}${uri}
```
- As soon as the image is untarring, and issue busctl cmd to inject a non-update error

```
busctl call xyz.openbmc_project.Logging /xyz/openbmc_project/logging \
xyz.openbmc_project.Logging.Create Create ssa{ss} \
xyz.openbmc_project.Host.Error.Event \
xyz.openbmc_project.Logging.Entry.Level.Error 1 RAWPEL \
/tmp/FILE_NBMC_UNRECOVERABLE
```

[1] https://github.com/openbmc/pldm/blob/master/oem/ibm/libpldmresponder/file_io_type_pel.cpp#L268

Change-Id: Ice54c403efacffa6a388e182bd04d97c3e2b97fc
Signed-off-by: Myung Bae <myungbae@us.ibm.com>

show more ...


# 80f79a40 24-Aug-2023 Michael Shen <gpgpgp@google.com>

Fix typo `DBusInteracesMap` -> `DBusInterfacesMap`

Change-Id: I9a851076eccee9d79ad7bb036e58b717e06ad5d1
Signed-off-by: Michael Shen <gpgpgp@google.com>


# 8549b951 16-Aug-2023 Myung Bae <myungbae@us.ibm.com>

Refactor Update monitorForSoftwareAvailable function

The scope of this code refactor is to limit the function of
monitorForSoftwareAvailable() for the coming future code modifications
in the area.

Refactor Update monitorForSoftwareAvailable function

The scope of this code refactor is to limit the function of
monitorForSoftwareAvailable() for the coming future code modifications
in the area.

Tested:
- Compiles successfully.
- Code update works as before (for success and failure cases)

Change-Id: I90fd41caa6b88c97c2a0c47fcf4553d48905b886
Signed-off-by: Myung Bae <myungbae@us.ibm.com>

show more ...


# bf2ddede 09-Aug-2023 Carson Labrado <clabrado@google.com>

Reduce some Error log severities

There are instances of ERROR logs that would work better as WARNING or
DEBUG since they do not actually result in bailing early and returning
an error response.

Sig

Reduce some Error log severities

There are instances of ERROR logs that would work better as WARNING or
DEBUG since they do not actually result in bailing early and returning
an error response.

Signed-off-by: Carson Labrado <clabrado@google.com>
Change-Id: I1e7bca0bb38487b26a4642ab72ce475170bb53c6

show more ...


# 1ccf70f1 02-Aug-2023 Myung Bae <myungbae@us.ibm.com>

Show Update error type on logs if unknown

Update is failing due to unknown update dbus error type
but the cause can not be determined as its value is not showing.

This change is to add the error ca

Show Update error type on logs if unknown

Update is failing due to unknown update dbus error type
but the cause can not be determined as its value is not showing.

This change is to add the error cause to journal in addition to
CRITICAL internalError.

```
Aug 02 09:00:16 bmcweb[2476]: (2023-08-02 09:00:14) [ERROR
"update_service.hpp":396] Unknown Software Image Error type = <XXX>
Aug 02 09:00:16 bmcweb[2476]: (2023-08-02 09:00:14) [CRITICAL
"error_messages.cpp":284] Internal Error ....`
```

Not tested but successfully compiled.

Change-Id: I20833d24042bf8d2f7e2d8a8e4359e3d80af702a
Signed-off-by: Myung Bae <myungbae@us.ibm.com>

show more ...


# 62598e31 17-Jul-2023 Ed Tanous <ed@tanous.net>

Replace logging with std::format

std::format is a much more modern logging solution, and gives us a lot
more flexibility, and better compile times when doing logging.

Unfortunately, given its level

Replace logging with std::format

std::format is a much more modern logging solution, and gives us a lot
more flexibility, and better compile times when doing logging.

Unfortunately, given its level of compile time checks, it needs to be a
method, instead of the stream style logging we had before. This
requires a pretty substantial change. Fortunately, this change can be
largely automated, via the script included in this commit under
scripts/replace_logs.py. This is to aid people in moving their
patchsets over to the new form in the short period where old patches
will be based on the old logging. The intention is that this script
eventually goes away.

The old style logging (stream based) looked like.

BMCWEB_LOG_DEBUG << "Foo " << foo;

The new equivalent of the above would be:
BMCWEB_LOG_DEBUG("Foo {}", foo);

In the course of doing this, this also cleans up several ignored linter
errors, including macro usage, and array to pointer deconstruction.

Note, This patchset does remove the timestamp from the log message. In
practice, this was duplicated between journald and bmcweb, and there's
no need for both to exist.

One design decision of note is the addition of logPtr. Because the
compiler can't disambiguate between const char* and const MyThing*, it's
necessary to add an explicit cast to void*. This is identical to how
fmt handled it.

Tested: compiled with logging meson_option enabled, and launched bmcweb

Saw the usual logging, similar to what was present before:
```
[Error include/webassets.hpp:60] Unable to find or open /usr/share/www/ static file hosting disabled
[Debug include/persistent_data.hpp:133] Restored Session Timeout: 1800
[Debug redfish-core/include/event_service_manager.hpp:671] Old eventService config not exist
[Info src/webserver_main.cpp:59] Starting webserver on port 18080
[Error redfish-core/include/event_service_manager.hpp:1301] inotify_add_watch failed for redfish log file.
[Info src/webserver_main.cpp:137] Start Hostname Monitor Service...
```
Signed-off-by: Ed Tanous <ed@tanous.net>

Change-Id: I86a46aa2454be7fe80df608cb7e5573ca4029ec8

show more ...


# 2c6ffdb0 28-Jun-2023 Ed Tanous <edtanous@google.com>

Use openssl random number generator

We already have a generator class. We should use it. Wrap this into a
function that can be unit tested, and add unit tests.

Note, some files also needed to cha

Use openssl random number generator

We already have a generator class. We should use it. Wrap this into a
function that can be unit tested, and add unit tests.

Note, some files also needed to change name, because random.hpp
conflicts with the built in random, and causes circular build problems.
This commit changes it to ossl_random.

Tested: Unit tests pass. Now has coverage.

Redfish service validator passes.

Change-Id: I5f8eee1af5f4843a352c6fd0e26d67fd3320ef53
Signed-off-by: Ed Tanous <edtanous@google.com>

show more ...


# 8b24275d 27-Jun-2023 Ed Tanous <edtanous@google.com>

Rename all error_code instances to ec

We're not consistent here, which leads to people copying and pasting
code all over, which has lead to a bunch of different names for error
codes.

This commit c

Rename all error_code instances to ec

We're not consistent here, which leads to people copying and pasting
code all over, which has lead to a bunch of different names for error
codes.

This commit changes to coerce them all to "ec", because that's what
boost uses for a naming convention.

Tested: Rename only, code compiles.

Change-Id: I7053cc738faa9f7a82f55fc46fc78618bdf702a5
Signed-off-by: Ed Tanous <edtanous@google.com>

show more ...


# 9ae226fa 21-Jun-2023 George Liu <liuxiwei@inspur.com>

Refactor setProperty method

SetProperty is a method we should use more, and use consistently in the
codebase, this commit makes it consistently used from the utility
namespace.

Tested: Refactor. C

Refactor setProperty method

SetProperty is a method we should use more, and use consistently in the
codebase, this commit makes it consistently used from the utility
namespace.

Tested: Refactor. Code compiles.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I5939317d23483e16bd98a8298f53e75604ef374d

show more ...


# b33a4327 09-Jun-2023 Ninad Palsule <ninad@linux.ibm.com>

Add content type check in the update service

The content type check is required in the update service. This may be a
security issue.

The correct content types to update service are multipart/form-d

Add content type check in the update service

The content type check is required in the update service. This may be a
security issue.

The correct content types to update service are multipart/form-data and
application/octet-stream. The multipart content type was missing from
the contentTypes array which is added in this drop.

Added couple of test cases.

Tested:

1) Make sure that update service content type
application/octet-stream are working correctly.
$ curl -k -H 'X-Auth-Token: THIbp1G0DiNVj3JrCZMf' -H 'Content-Type: \
application/octet-stream' -X POST \
-T ./obmc-phosphor-image-everest.ext4.mmc.tar \
https://${bmc}/redfish/v1/UpdateService/update
{
"@odata.id": "/redfish/v1/TaskService/Tasks/0",
"@odata.type": "#Task.v1_4_3.Task",
"Id": "0",
"TaskState": "Running",
"TaskStatus": "OK"

2) Make sure that update service content type
multipart/form-data are working correctly.
$ curl -k -H 'X-Auth-Token: Vc7KBgM6z3uMs1G7uVqu' \
-H Content-Type:multipart/form-data \
-F 'UpdateParameters={"Targets":["/redfish/v1/Managers/bmc"], \
"@Redfish.OperationApplyTime":"Immediate"};type=application/json'\
-F 'UpdateFile=@obmc-phosphor-image-p10bmc.ext4.mmc.tar; \
type=application/octet-stream' \
https://${bmc}/redfish/v1/UpdateService/update
{
"@Message.ExtendedInfo": [
{
"@odata.type": "#Message.v1_1_1.Message",
"Message": "The request completed successfully.",
"MessageArgs": [],
"MessageId": "Base.1.16.0.Success",
"MessageSeverity": "OK",
"Resolution": "None"
}
],
"@odata.id": "/redfish/v1/TaskService/Tasks/0",
"@odata.type": "#Task.v1_4_3.Task",
"Id": "0",
"TaskState": "Running",
"TaskStatus": "OK"

3) Make sure that command fails when content type is missing.
$ curl -k -H 'X-Auth-Token: vH3B88sh323sfy0YG8eN' -H Content-Type: \
-X POST -T ./obmc-phosphor-image-everest.ext4.mmc.tar \
https://${bmc}/redfish/v1/UpdateService/update
Bad Request

[INFO "http_connection.hpp":201] Request: 0x177f920 HTTP/1.1 POST \
/redfish/v1/UpdateService/update ::ffff:x.x.xx.xxx
|
[DEBUG "update_service.hpp":687] doPost: contentType=
[DEBUG "update_service.hpp":692] Bad content type specified:

4) Make sure that command fails when wrong cotent type specified.
$ curl -k -H 'X-Auth-Token: OQzODMaR0G29AjpD2YmT' -H 'Content-Type: \
application/octet-json' -X POST \
-T ./obmc-phosphor-image-everest.ext4.mmc.tar \
https://${bmc}/redfish/v1/UpdateService/update
Bad Request

[INFO "http_connection.hpp":201] Request: 0x17a69d0 HTTP/1.1 POST \
/redfish/v1/UpdateService/update ::ffff:x.x.xx.xxx
|
[DEBUG "update_service.hpp":687] doPost:
contentType=application/octet-json
[DEBUG "update_service.hpp":720] Bad content type specified:
application/octet-json

5) Make sure that command fails when header is not specified.
$ curl -k -H 'X-Auth-Token: Z1AEXg075qGKi0xISu6o' -X POST \
-T ./obmc-phosphor-image-everest.ext4.mmc.tar \
https://${bmc}/redfish/v1/UpdateService/update
Bad Request

[INFO "http_connection.hpp":201] Request: 0x17a69d0 HTTP/1.1 \
POST /redfish/v1/UpdateService/update ::ffff:x.x.xx.xxx
|
[DEBUG "update_service.hpp":687] doPost: contentType=
[DEBUG "update_service.hpp":692] Bad content type specified:

Change-Id: I48b709b6219debfed9ff60dd46ab87652e5a1fe5
Signed-off-by: Ninad Palsule <ninad@linux.ibm.com>

show more ...


# b90d14f2 31-May-2023 Myung Bae <myungbae@us.ibm.com>

Fix Error log entries to Warning

Some logging entries are categorized as ERROR, but they would better be
as WARNING.

1)
```
$ curl -k -X GET https://${bmc}:18080/redfish/v1/Managers/bmc/LogServices

Fix Error log entries to Warning

Some logging entries are categorized as ERROR, but they would better be
as WARNING.

1)
```
$ curl -k -X GET https://${bmc}:18080/redfish/v1/Managers/bmc/LogServices/Dump/Entries/INVALID
{
....
"code": "Base.1.13.0.InternalError",
"message": "The request failed due to an internal service error. The service is still operational."
}
}%

(2023-06-01 23:29:40) [ERROR "log_services.hpp":665] Can't find Dump Entry
(2023-06-01 23:29:40) [CRITICAL "error_messages.cpp":282] Internal Error \
../../../../../../../../../bmcweb/redfish-core/lib/log_services.hpp(666:36) \
`redfish::getDumpEntryById(const std::shared_ptr<bmcweb::AsyncResp>&, const std::string&, \
const std::string&)::<lambda(const boost::system::error_code&, const dbus::utility::ManagedObjectType&)>`:
```

2)
```
$ curl -k -X GET https://${bmc}:18080/redfish/v1/UpdateService/FirmwareInventory/INVALID

(2023-05-31 15:03:38) [ERROR "update_service.hpp":1010] Input swID X1cd6ce5fZ not found!
```

Tested:
- Set bmcweb-logging=error to obtain Error or higher logs
- Run the above commands and watch out logs
- Redfish validator passed and see whether there are unexpected error or higher level logs

Change-Id: I5f14eedd68fd3454cdf2a5b2f34442a7718e718a
Signed-off-by: Myung Bae <myungbae@us.ibm.com>

show more ...


# ac106bf6 07-Jun-2023 Ed Tanous <edtanous@google.com>

Consistently name AsyncResp variables

In about half of our code, AsyncResp objects take the name asyncResp,
and in the other half they take the name aResp. While the difference
between them is negl

Consistently name AsyncResp variables

In about half of our code, AsyncResp objects take the name asyncResp,
and in the other half they take the name aResp. While the difference
between them is negligeble and arbitrary, having two naming conventions
makes it more difficult to do automated changes over time via grep.

This commit was generated automtatically with the command:
git grep -l 'aResp' | xargs sed -i 's|aResp|asyncResp|g'

Tested: Code compiles.

Change-Id: Id363437b6a78f51e91cbf60aa0a0c2286f36a037
Signed-off-by: Ed Tanous <edtanous@google.com>

show more ...


# 08d81ada 17-May-2022 John Edward Broadbent <jebr@google.com>

update service: use getCollectionMembers

There are some cases that getCollectionMembers can be leveraged

Tested:

GET https://127.0.0.1:443/redfish/v1/UpdateService/FirmwareInventory/
Returns the s

update service: use getCollectionMembers

There are some cases that getCollectionMembers can be leveraged

Tested:

GET https://127.0.0.1:443/redfish/v1/UpdateService/FirmwareInventory/
Returns the same result.

Redfish service validator passes.

Signed-off-by: John Edward Broadbent <jebr@google.com>
Change-Id: I417bc08cffd24c6c95abaf86013002ce705d20a4

show more ...


# 81c4e330 18-May-2023 Ed Tanous <edtanous@google.com>

Capture all boost::system::error_codes by ref

Capturing these possibly overloaded values by reference can avoid a copy
in some cases, and it's good to be consistent.

This change was made automatica

Capture all boost::system::error_codes by ref

Capturing these possibly overloaded values by reference can avoid a copy
in some cases, and it's good to be consistent.

This change was made automatically by grep/sed.

Tested: Code compiles.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Iafeaca2a5dc52f39753b5a3880419d6bc943f81b

show more ...


# 4a40441f 15-May-2023 Ed Tanous <edtanous@google.com>

Remove redfish-post-to-old-updateservice

It is now Q2 2023, and this option has been deprecated. Maintainers
have not had any reports of this behavior breaking people.

Tested: Code delete only. C

Remove redfish-post-to-old-updateservice

It is now Q2 2023, and this option has been deprecated. Maintainers
have not had any reports of this behavior breaking people.

Tested: Code delete only. Code compiles.

Change-Id: I9c1fe26e497806c6bc602fb019bafe0fc80d7619
Signed-off-by: Ed Tanous <edtanous@google.com>

show more ...


# ef4c65b7 24-Apr-2023 Ed Tanous <edtanous@google.com>

Boost::urls::format

Boost 1.82 dropped a lovely new toy, boost::urls::format, which is a lot
like our urlFromPieces method, but better in that it makes the resulting
uris more readable, and allows d

Boost::urls::format

Boost 1.82 dropped a lovely new toy, boost::urls::format, which is a lot
like our urlFromPieces method, but better in that it makes the resulting
uris more readable, and allows doing things like fragments in a single
line instead of multiple. We should prefer it in some cases.

Tested:
Redfish service validator passes.
Spot checks of URLs work as expected.
Unit tests pass.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ia7b38f0a95771c862507e7d5b4aa68aa1c98403c

show more ...


# b2ba3072 12-May-2023 Patrick Williams <patrick@stwcx.xyz>

fix more push vs emplace calls

It seems like clang-tidy doesn't catch every place that an emplace could
be used instead of a push. Use a few grep/sed pairs to find and fix up
some common patterns.

fix more push vs emplace calls

It seems like clang-tidy doesn't catch every place that an emplace could
be used instead of a push. Use a few grep/sed pairs to find and fix up
some common patterns.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I93eaec26b8e3be240599e92b66cf54947073dc4c

show more ...


# 89492a15 10-May-2023 Patrick Williams <patrick@stwcx.xyz>

clang-format: copy latest and re-format

clang-format-16 has some backwards incompatible changes that require
additional settings for best compatibility and re-running the formatter.
Copy the latest

clang-format: copy latest and re-format

clang-format-16 has some backwards incompatible changes that require
additional settings for best compatibility and re-running the formatter.
Copy the latest .clang-format from the docs repository and reformat the
repository.

Change-Id: I75f89d2959b0f1338c20d72ad669fbdc1d720835
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>

show more ...


# 0ed80c8c 12-May-2020 George Liu <liuxiwei@inspur.com>

UpdateService: Support for MultipartHttpPushUri

Since a service support the MultipartHttpPushUri property within the
UpdateService resource, so add a new MultipartHttpPushUri property,
This property

UpdateService: Support for MultipartHttpPushUri

Since a service support the MultipartHttpPushUri property within the
UpdateService resource, so add a new MultipartHttpPushUri property,
This property shall contain a URI used to perform a Redfish
Specification-defined Multipart HTTP or HTTPS POST of a software image
for the purpose of installing software contained within the image, and
use the requirements of a multipart/form-data to request body for HTTP
push software update.

Tested:
curl -k -H "X-Auth-Token: $token" -H "Content-Type:
multipart/form-data"
-F
'UpdateParameters={"Targets":["/redfish/v1/Managers/bmc"],
"@Redfish.OperationApplyTime":"Immediate"};type=application/json'
-F
'UpdateFile=@obmc-phosphor-image.static.mtd.tar;type=application/
octet-stream'
https://${bmc}/redfish/v1/UpdateService/update
{
"@odata.id": "/redfish/v1/TaskService/Tasks/0",
"@odata.type": "#Task.v1_4_3.Task",
"Id": "0",
"TaskState": "Running",
"TaskStatus": "OK"
}

Passed the validator:

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: Ie1ea0594337efdb073270aba6918389c4381a2b3

show more ...


# 33c6b580 14-Feb-2023 Ed Tanous <edtanous@google.com>

Remove body member from Request

Per cpp core guidelines, these should be methods.

Tested: on last patchset of the series.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ib16479db9d2b68d

Remove body member from Request

Per cpp core guidelines, these should be methods.

Tested: on last patchset of the series.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ib16479db9d2b68da68e7ad6e825c7e205c64f1de

show more ...


# 5e7e2dc5 16-Feb-2023 Ed Tanous <edtanous@google.com>

Take boost error_code by reference

By convention, we should be following boost here, and passing error_code
by reference, not by value. This makes our code consistent, and removes
the need for a co

Take boost error_code by reference

By convention, we should be following boost here, and passing error_code
by reference, not by value. This makes our code consistent, and removes
the need for a copy in some cases.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Id42ea4a90b6685a84818b87d1506c11256b3b9ae

show more ...


# eddfc437 26-Sep-2022 Willy Tu <wltu@google.com>

Update most resources to use urlFromPieces

Only id in event_service and account_service have not been updated due
to the risk of it breaking the username/id. It will require further
testing to verif

Update most resources to use urlFromPieces

Only id in event_service and account_service have not been updated due
to the risk of it breaking the username/id. It will require further
testing to verify.

Use urlFromPieces wherever that is needed to insert a variable in the
URI. Don't use urlFromPieces when it is hardcoded values. This allow us
to control all resource URIs that is dynamically added and to sync with
the current recommanded method for `@odata.id`. The goal is to have a
common place to manage the url created from dbus-paths in order to
manage/update it easily when needed.

Tested:
RedfishValidtor Passed for all resource including the sensors with the
fragments.

Change-Id: I95cdfaaee58fc7f21c95f5944e1e5c813b3215f2
Signed-off-by: Willy Tu <wltu@google.com>
Signed-off-by: Ed Tanous <edtanous@google.com>

show more ...


1234567