{"action":"created","comment":{"url":"https://api.github.com/repos/mendersoftware/mender/pulls/comments/55495334","id":55495334,"diff_hunk":"@@ -0,0 +1,195 @@\n+// Copyright 2016 Mender Software AS\n+//\n+//    Licensed under the Apache License, Version 2.0 (the \"License\");\n+//    you may not use this file except in compliance with the License.\n+//    You may obtain a copy of the License at\n+//\n+//        http://www.apache.org/licenses/LICENSE-2.0\n+//\n+//    Unless required by applicable law or agreed to in writing, software\n+//    distributed under the License is distributed on an \"AS IS\" BASIS,\n+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+//    See the License for the specific language governing permissions and\n+//    limitations under the License.\n+package main\n+\n+import (\n+\t\"encoding/json\"\n+\t\"errors\"\n+\t\"io/ioutil\"\n+\t\"net/http\"\n+\t\"time\"\n+)\n+import \"github.com/mendersoftware/log\"\n+\n+// create a channel so that we will be able to stop daemon\n+var daemonQuit = make(chan bool)\n+\n+//TODO: daemon configuration will be hardcoded now\n+const (\n+\t// pull data from server every 3 minutes by default\n+\tdefaultServerPullInterval = time.Duration(3) * time.Minute\n+\tdefaultServerAddress      = \"127.0.0.1\"\n+\tdefaultDeviceID           = \"1234:5678:90ab:cdef\"\n+)\n+\n+// possible API responses received for update request\n+const (\n+\tupdateRespponseHaveUpdate = 200\n+\tupdateResponseNoUpdates   = 204\n+\tupdateResponseError       = 404\n+)\n+\n+// daemon configuration\n+type daemonConfigType struct {\n+\tserverPullInterval time.Duration\n+\tserver             string\n+\tdeviceID           string\n+}\n+\n+func getServerAddress() string {\n+\t// TODO: this should be taken from configuration or should be set at bootstrap\n+\tserver, err := ioutil.ReadFile(\"/data/serveraddress\")\n+\n+\tif err != nil {\n+\t\treturn \"\"\n+\t}\n+\treturn string(server)\n+}\n+\n+type responseParserFunc func(response http.Response, respBody []byte) (dataActuator, error)\n+type updateRequester struct {\n+\treqType              string\n+\trequest              string\n+\tmenderClient         client\n+\tupdateResponseParser responseParserFunc\n+}\n+\n+// implementation of clientWorker interface\n+func (ur updateRequester) getClient() client {\n+\treturn ur.menderClient\n+}\n+\n+func (ur updateRequester) formatRequest() clientRequestType {\n+\treturn clientRequestType{ur.reqType, ur.request}\n+}\n+\n+func (ur updateRequester) actOnResponse(response http.Response, respBody []byte) error {\n+\tdata, err := ur.updateResponseParser(response, respBody)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\treturn data.actOnData()\n+}\n+\n+// Current API is supporting different responses from the server for update request.\n+// Each of the data structures received after sending update request needs to\n+// implement dataActuator interface\n+type dataActuator interface {\n+\tactOnData() error\n+}\n+\n+// have update for the client\n+type updateHaveUpdateResponseType struct {\n+\tImage struct {\n+\t\tURI      string\n+\t\tChecksum string\n+\t\tID       string\n+\t}\n+\tID string\n+}\n+\n+func (resp updateHaveUpdateResponseType) actOnData() error {\n+\t// perform update of the device\n+\treturn doRootfs(resp.Image.URI)\n+}\n+\n+// there is no update for the device\n+type updateNoUpdateResponseType struct {\n+\t// empty for now\n+}\n+\n+func (resp updateNoUpdateResponseType) actOnData() error {\n+\treturn nil\n+}\n+\n+// there was an error geting update information\n+type updateErrorResponseType struct {\n+\t//empty for now\n+}\n+\n+func (resp updateErrorResponseType) actOnData() error {\n+\treturn nil\n+}\n+\n+func parseUpdateResponse(response http.Response, respBody []byte) (dataActuator, error) {\n+\n+\tlog.Debug(\"Received response:\", response.Status)\n+\n+\tswitch response.StatusCode {\n+\tcase updateRespponseHaveUpdate:\n+\t\tlog.Debug(\"Have update available\")\n+\n+\t\tvar data updateHaveUpdateResponseType\n+\t\tif err := json.Unmarshal(respBody, &data); err != nil {\n+\t\t\tswitch err.(type) {\n+\t\t\tcase *json.SyntaxError:\n+\t\t\t\treturn updateHaveUpdateResponseType{}, errors.New(\"Error parsing data syntax\")\n+\t\t\t}\n+\t\t\treturn updateHaveUpdateResponseType{}, errors.New(\"Error parsing data: \" + err.Error())\n+\t\t}\n+\n+\t\t// check if we have JSON data correctky decoded\n+\t\tif data.ID != \"\" && data.Image.Checksum != \"\" && data.Image.ID != \"\" && data.Image.URI != \"\" {\n+\t\t\tlog.Info(\"Received correct request for getting image from: \" + data.Image.URI)\n+\t\t\treturn data, nil\n+\t\t}\n+\n+\t\treturn updateHaveUpdateResponseType{}, errors.New(\"Mallformed update response\")\n+\n+\tcase updateResponseNoUpdates:\n+\t\tlog.Debug(\"No update available\")\n+\n+\t\t//TODO: check body to see if message is mallformed\n+\t\treturn updateNoUpdateResponseType{}, nil\n+\n+\tcase updateResponseError:\n+\t\t//TODO: check body to see if message is mallformed\n+\t\treturn updateErrorResponseType{}, nil\n+\n+\tdefault:","path":"daemon.go","position":162,"original_position":160,"commit_id":"bd3bdd4eb86d1a320411333672454d081503e2bd","original_commit_id":"01f90de7172e6857c2128b8ee394088703defcc3","user":{"login":"maciejmrowiec","id":1391631,"avatar_url":"https://avatars.githubusercontent.com/u/1391631?v=3","gravatar_id":"","url":"https://api.github.com/users/maciejmrowiec","html_url":"https://github.com/maciejmrowiec","followers_url":"https://api.github.com/users/maciejmrowiec/followers","following_url":"https://api.github.com/users/maciejmrowiec/following{/other_user}","gists_url":"https://api.github.com/users/maciejmrowiec/gists{/gist_id}","starred_url":"https://api.github.com/users/maciejmrowiec/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maciejmrowiec/subscriptions","organizations_url":"https://api.github.com/users/maciejmrowiec/orgs","repos_url":"https://api.github.com/users/maciejmrowiec/repos","events_url":"https://api.github.com/users/maciejmrowiec/events{/privacy}","received_events_url":"https://api.github.com/users/maciejmrowiec/received_events","type":"User","site_admin":false},"body":"sure, you can handle this as range 400-499 client errors 500-599 server errors","created_at":"2016-03-09T10:00:11Z","updated_at":"2016-03-09T10:00:11Z","html_url":"https://github.com/mendersoftware/mender/pull/34#discussion_r55495334","pull_request_url":"https://api.github.com/repos/mendersoftware/mender/pulls/34","_links":{"self":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/comments/55495334"},"html":{"href":"https://github.com/mendersoftware/mender/pull/34#discussion_r55495334"},"pull_request":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/34"}}},"pull_request":{"url":"https://api.github.com/repos/mendersoftware/mender/pulls/34","id":61728716,"html_url":"https://github.com/mendersoftware/mender/pull/34","diff_url":"https://github.com/mendersoftware/mender/pull/34.diff","patch_url":"https://github.com/mendersoftware/mender/pull/34.patch","issue_url":"https://api.github.com/repos/mendersoftware/mender/issues/34","number":34,"state":"open","locked":false,"title":"Add daemonization handling and bootstrapping.","user":{"login":"pasinskim","id":6329055,"avatar_url":"https://avatars.githubusercontent.com/u/6329055?v=3","gravatar_id":"","url":"https://api.github.com/users/pasinskim","html_url":"https://github.com/pasinskim","followers_url":"https://api.github.com/users/pasinskim/followers","following_url":"https://api.github.com/users/pasinskim/following{/other_user}","gists_url":"https://api.github.com/users/pasinskim/gists{/gist_id}","starred_url":"https://api.github.com/users/pasinskim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pasinskim/subscriptions","organizations_url":"https://api.github.com/users/pasinskim/orgs","repos_url":"https://api.github.com/users/pasinskim/repos","events_url":"https://api.github.com/users/pasinskim/events{/privacy}","received_events_url":"https://api.github.com/users/pasinskim/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-03-04T15:42:14Z","updated_at":"2016-03-09T10:00:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e2b424c0b4e24d54da2bf2012551ae989e2a59aa","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mendersoftware/mender/pulls/34/commits","review_comments_url":"https://api.github.com/repos/mendersoftware/mender/pulls/34/comments","review_comment_url":"https://api.github.com/repos/mendersoftware/mender/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mendersoftware/mender/issues/34/comments","statuses_url":"https://api.github.com/repos/mendersoftware/mender/statuses/bd3bdd4eb86d1a320411333672454d081503e2bd","head":{"label":"pasinskim:master","ref":"master","sha":"bd3bdd4eb86d1a320411333672454d081503e2bd","user":{"login":"pasinskim","id":6329055,"avatar_url":"https://avatars.githubusercontent.com/u/6329055?v=3","gravatar_id":"","url":"https://api.github.com/users/pasinskim","html_url":"https://github.com/pasinskim","followers_url":"https://api.github.com/users/pasinskim/followers","following_url":"https://api.github.com/users/pasinskim/following{/other_user}","gists_url":"https://api.github.com/users/pasinskim/gists{/gist_id}","starred_url":"https://api.github.com/users/pasinskim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pasinskim/subscriptions","organizations_url":"https://api.github.com/users/pasinskim/orgs","repos_url":"https://api.github.com/users/pasinskim/repos","events_url":"https://api.github.com/users/pasinskim/events{/privacy}","received_events_url":"https://api.github.com/users/pasinskim/received_events","type":"User","site_admin":false},"repo":{"id":50120838,"name":"mender","full_name":"pasinskim/mender","owner":{"login":"pasinskim","id":6329055,"avatar_url":"https://avatars.githubusercontent.com/u/6329055?v=3","gravatar_id":"","url":"https://api.github.com/users/pasinskim","html_url":"https://github.com/pasinskim","followers_url":"https://api.github.com/users/pasinskim/followers","following_url":"https://api.github.com/users/pasinskim/following{/other_user}","gists_url":"https://api.github.com/users/pasinskim/gists{/gist_id}","starred_url":"https://api.github.com/users/pasinskim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pasinskim/subscriptions","organizations_url":"https://api.github.com/users/pasinskim/orgs","repos_url":"https://api.github.com/users/pasinskim/repos","events_url":"https://api.github.com/users/pasinskim/events{/privacy}","received_events_url":"https://api.github.com/users/pasinskim/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pasinskim/mender","description":"Mender over-the-air software updates.","fork":true,"url":"https://api.github.com/repos/pasinskim/mender","forks_url":"https://api.github.com/repos/pasinskim/mender/forks","keys_url":"https://api.github.com/repos/pasinskim/mender/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pasinskim/mender/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pasinskim/mender/teams","hooks_url":"https://api.github.com/repos/pasinskim/mender/hooks","issue_events_url":"https://api.github.com/repos/pasinskim/mender/issues/events{/number}","events_url":"https://api.github.com/repos/pasinskim/mender/events","assignees_url":"https://api.github.com/repos/pasinskim/mender/assignees{/user}","branches_url":"https://api.github.com/repos/pasinskim/mender/branches{/branch}","tags_url":"https://api.github.com/repos/pasinskim/mender/tags","blobs_url":"https://api.github.com/repos/pasinskim/mender/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pasinskim/mender/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pasinskim/mender/git/refs{/sha}","trees_url":"https://api.github.com/repos/pasinskim/mender/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pasinskim/mender/statuses/{sha}","languages_url":"https://api.github.com/repos/pasinskim/mender/languages","stargazers_url":"https://api.github.com/repos/pasinskim/mender/stargazers","contributors_url":"https://api.github.com/repos/pasinskim/mender/contributors","subscribers_url":"https://api.github.com/repos/pasinskim/mender/subscribers","subscription_url":"https://api.github.com/repos/pasinskim/mender/subscription","commits_url":"https://api.github.com/repos/pasinskim/mender/commits{/sha}","git_commits_url":"https://api.github.com/repos/pasinskim/mender/git/commits{/sha}","comments_url":"https://api.github.com/repos/pasinskim/mender/comments{/number}","issue_comment_url":"https://api.github.com/repos/pasinskim/mender/issues/comments{/number}","contents_url":"https://api.github.com/repos/pasinskim/mender/contents/{+path}","compare_url":"https://api.github.com/repos/pasinskim/mender/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pasinskim/mender/merges","archive_url":"https://api.github.com/repos/pasinskim/mender/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pasinskim/mender/downloads","issues_url":"https://api.github.com/repos/pasinskim/mender/issues{/number}","pulls_url":"https://api.github.com/repos/pasinskim/mender/pulls{/number}","milestones_url":"https://api.github.com/repos/pasinskim/mender/milestones{/number}","notifications_url":"https://api.github.com/repos/pasinskim/mender/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pasinskim/mender/labels{/name}","releases_url":"https://api.github.com/repos/pasinskim/mender/releases{/id}","deployments_url":"https://api.github.com/repos/pasinskim/mender/deployments","created_at":"2016-01-21T16:34:16Z","updated_at":"2016-01-21T16:35:29Z","pushed_at":"2016-03-08T16:04:59Z","git_url":"git://github.com/pasinskim/mender.git","ssh_url":"git@github.com:pasinskim/mender.git","clone_url":"https://github.com/pasinskim/mender.git","svn_url":"https://github.com/pasinskim/mender","homepage":"https://mender.io","size":174,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mendersoftware:master","ref":"master","sha":"c007ebaa6758afbc83262b6b3358ea143952fea2","user":{"login":"mendersoftware","id":15040539,"avatar_url":"https://avatars.githubusercontent.com/u/15040539?v=3","gravatar_id":"","url":"https://api.github.com/users/mendersoftware","html_url":"https://github.com/mendersoftware","followers_url":"https://api.github.com/users/mendersoftware/followers","following_url":"https://api.github.com/users/mendersoftware/following{/other_user}","gists_url":"https://api.github.com/users/mendersoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/mendersoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mendersoftware/subscriptions","organizations_url":"https://api.github.com/users/mendersoftware/orgs","repos_url":"https://api.github.com/users/mendersoftware/repos","events_url":"https://api.github.com/users/mendersoftware/events{/privacy}","received_events_url":"https://api.github.com/users/mendersoftware/received_events","type":"Organization","site_admin":false},"repo":{"id":47542798,"name":"mender","full_name":"mendersoftware/mender","owner":{"login":"mendersoftware","id":15040539,"avatar_url":"https://avatars.githubusercontent.com/u/15040539?v=3","gravatar_id":"","url":"https://api.github.com/users/mendersoftware","html_url":"https://github.com/mendersoftware","followers_url":"https://api.github.com/users/mendersoftware/followers","following_url":"https://api.github.com/users/mendersoftware/following{/other_user}","gists_url":"https://api.github.com/users/mendersoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/mendersoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mendersoftware/subscriptions","organizations_url":"https://api.github.com/users/mendersoftware/orgs","repos_url":"https://api.github.com/users/mendersoftware/repos","events_url":"https://api.github.com/users/mendersoftware/events{/privacy}","received_events_url":"https://api.github.com/users/mendersoftware/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mendersoftware/mender","description":"Mender over-the-air software updates.","fork":false,"url":"https://api.github.com/repos/mendersoftware/mender","forks_url":"https://api.github.com/repos/mendersoftware/mender/forks","keys_url":"https://api.github.com/repos/mendersoftware/mender/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mendersoftware/mender/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mendersoftware/mender/teams","hooks_url":"https://api.github.com/repos/mendersoftware/mender/hooks","issue_events_url":"https://api.github.com/repos/mendersoftware/mender/issues/events{/number}","events_url":"https://api.github.com/repos/mendersoftware/mender/events","assignees_url":"https://api.github.com/repos/mendersoftware/mender/assignees{/user}","branches_url":"https://api.github.com/repos/mendersoftware/mender/branches{/branch}","tags_url":"https://api.github.com/repos/mendersoftware/mender/tags","blobs_url":"https://api.github.com/repos/mendersoftware/mender/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mendersoftware/mender/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mendersoftware/mender/git/refs{/sha}","trees_url":"https://api.github.com/repos/mendersoftware/mender/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mendersoftware/mender/statuses/{sha}","languages_url":"https://api.github.com/repos/mendersoftware/mender/languages","stargazers_url":"https://api.github.com/repos/mendersoftware/mender/stargazers","contributors_url":"https://api.github.com/repos/mendersoftware/mender/contributors","subscribers_url":"https://api.github.com/repos/mendersoftware/mender/subscribers","subscription_url":"https://api.github.com/repos/mendersoftware/mender/subscription","commits_url":"https://api.github.com/repos/mendersoftware/mender/commits{/sha}","git_commits_url":"https://api.github.com/repos/mendersoftware/mender/git/commits{/sha}","comments_url":"https://api.github.com/repos/mendersoftware/mender/comments{/number}","issue_comment_url":"https://api.github.com/repos/mendersoftware/mender/issues/comments{/number}","contents_url":"https://api.github.com/repos/mendersoftware/mender/contents/{+path}","compare_url":"https://api.github.com/repos/mendersoftware/mender/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mendersoftware/mender/merges","archive_url":"https://api.github.com/repos/mendersoftware/mender/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mendersoftware/mender/downloads","issues_url":"https://api.github.com/repos/mendersoftware/mender/issues{/number}","pulls_url":"https://api.github.com/repos/mendersoftware/mender/pulls{/number}","milestones_url":"https://api.github.com/repos/mendersoftware/mender/milestones{/number}","notifications_url":"https://api.github.com/repos/mendersoftware/mender/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mendersoftware/mender/labels{/name}","releases_url":"https://api.github.com/repos/mendersoftware/mender/releases{/id}","deployments_url":"https://api.github.com/repos/mendersoftware/mender/deployments","created_at":"2015-12-07T09:36:43Z","updated_at":"2016-02-27T20:59:23Z","pushed_at":"2016-03-08T16:05:00Z","git_url":"git://github.com/mendersoftware/mender.git","ssh_url":"git@github.com:mendersoftware/mender.git","clone_url":"https://github.com/mendersoftware/mender.git","svn_url":"https://github.com/mendersoftware/mender","homepage":"https://mender.io","size":146,"stargazers_count":4,"watchers_count":4,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":6,"mirror_url":null,"open_issues_count":2,"forks":6,"open_issues":2,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/34"},"html":{"href":"https://github.com/mendersoftware/mender/pull/34"},"issue":{"href":"https://api.github.com/repos/mendersoftware/mender/issues/34"},"comments":{"href":"https://api.github.com/repos/mendersoftware/mender/issues/34/comments"},"review_comments":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/34/comments"},"review_comment":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/34/commits"},"statuses":{"href":"https://api.github.com/repos/mendersoftware/mender/statuses/bd3bdd4eb86d1a320411333672454d081503e2bd"}}}}