diff --git a/CHANGELOG-1.3.md b/CHANGELOG-1.3.md new file mode 100644 index 0000000..3b65538 --- /dev/null +++ b/CHANGELOG-1.3.md @@ -0,0 +1,5 @@ +## v1.3.0 +* Use iofogctl and yaml file for deploying ioFog resources +* Remove Dockerfiles and docker-compose files +* Update test script to set up agent ssh access +* Improve logging \ No newline at end of file diff --git a/README.md b/README.md index 732fc83..e85b37f 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,11 @@ Supported operating systems: * Linux (kernel v3.10+) * macOS 10.12+ -* Windows 7+ Requires tools: * Docker 1.10+ ([installation instructions](https://docs.docker.com/install/)) -* Docker-compose 1.22+ ([installation instructions](https://docs.docker.com/compose/install/)) +* iofogctl 1.3.0+ ([installation instructions](https://github.com/eclipse-iofog/iofogctl/tree/v1.3.0#install)) # Try ioFog - Simple Edge Compute Network @@ -52,38 +51,17 @@ When you are finished, tear down the ioFog stack and all services deployed on it ./stop.sh ``` -## Build from local packages +## Build from local images -If you have a local version of the Agent, Controller and Connector, you can chose to build the containers using those local packages. -To do so, you will need a debian package (`.deb`) for the Agent and the Connector and a tarball (`.tgz`) for the Controller. +If you have a local image version of the Agent, Controller and Connector, you can chose to build the containers using those local images. +To do so, you will need a docker image for the Agent, the Connector and the Controller. You can provide `start.sh` with an option for each local package you want to use. ### Example -Folder structure: -```text -* services -* init -* test -* local-packages # Example folder where you would store your local packages - - iofog-agent_2.0.deb - - iofog-connector_2.0.deb - - iofog-controller_2.0.tgz -* start.sh -* stop.sh -* ... -``` Command: ```sh -./start.sh -a ./local-packages/iofog-agent_2.0.deb -cn ./local-packages/iofog-connector_2.0.deb -ct ./local-packages/iofog-controller_2.0.tgz -``` - -## Force rebuild -If you have previously built the containers using local packages, or remote packages and you want to ensure that running `start.sh` will rebuild the images, you can also provide the `--no-cache` option - - -```sh -./start.sh --no-cache +./start.sh -a gcr.io/focal-freedom-236620/agent:latest -cn gcr.io/focal-freedom-236620/connector:latest -ct gcr.io/focal-freedom-236620/controller:latest ``` ## ECN Status @@ -94,22 +72,21 @@ If you have previously built the containers using local packages, or remote pack ## Interacting With The ioFog Stack - CLI -The simplest way to interact with Agent, Controller, and Connector deployed on a machine you have access to is to use the command line interface. The main interaction point for users is the Controller. +The simplest way to interact with Agent, Controller, and Connector deployed on a machine you have access to is to use the command line interface `iofogctl`. ```sh -docker exec -it iofog-controller iofog-controller help +iofogctl help ``` -For the purpose of this demo, all ioFog components are spun up in separate Docker containers. The Controller's container is called `iofog-controller` (the first occurrence in the above command) and the executable inside the container is also called `iofog-controller` (the second occurrence).)_ + +For the purpose of this demo, all ioFog components are spun up in separate Docker containers. The Controller's container is called `iofog-controller`. Names for all the containers created in the demo are `iofog-agent`, `iofog-controller` and `iofog-connector`. The initialization scripts used to setup the ioFog stack / ECN are using the CLI interface. Feel free to refer to these for more inspiration. -Full reference of the CLI for all ioFog stack components is available at the ioFog website: +Full reference of the CLI is available at the iofogctl github repository: -* https://iofog.org/docs/1.0.0/controllers/cli-usage.html -* https://iofog.org/docs/1.0.0/agents/cli-usage.html -* https://iofog.org/docs/1.0.0/connectors/cli-usage.html +* https://github.com/eclipse-iofog/iofogctl/tree/v1.3.0#usage ## Interacting With The ioFog Stack - REST API @@ -136,11 +113,18 @@ First, create all services for a tutorial ioFog application. You don't have to s ./start.sh tutorial ``` -When you are done with the tutorial, you can tear down the sample application together with the ioFog stack. Note there is currently no wya in the demo to tear down just the tutorial application. +When you are done with the tutorial, you can tear down the sample application together with the ioFog stack. + ```sh ./stop.sh ``` +if you only wish to delete the tutorial application: + +```sh +iofogctl delete application tutorial +``` + # Structure Of This Repository ```text * services # Service Dockerfiles and customization files @@ -149,8 +133,8 @@ When you are done with the tutorial, you can tear down the sample application to + iofog-connector # Connector service files - part of the iofog stack + iofog-controller # Controller service files - part of the iofog stack * init - - iofog # plain ioFog stack initialization service - - tutorial # tutorial initialization service + - iofog # plain ioFog stack initialization yaml file + - tutorial # tutorial initialization yaml file * test + conf # generated test configuration files * azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 23bf058..4f67ff1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,9 +1,17 @@ trigger: - master - develop + - release/* pr: - master - develop +schedules: +- cron: "0 0 * * *" + displayName: Daily build (UTC) + branches: + include: + - master + - develop pool: vmImage: 'ubuntu-16.04' @@ -13,16 +21,25 @@ steps: - task: DockerInstaller@0 displayName: Docker Installer inputs: - dockerVersion: 18.09.2 + dockerVersion: 19.03.2 releaseType: stable +- script: | + # curl -s https://packagecloud.io/install/repositories/iofog/iofogctl/script.deb.sh | sudo bash + # Using dev version of iofogctl until 1.3.0 release + curl -s https://8c90601638aff0b3fb520971175089bbaba2cf7f29be9528:@packagecloud.io/install/repositories/iofog/iofogctl-snapshots/script.deb.sh | sudo bash + sudo apt install iofogctl=1.3.0-dev + displayName: 'Install iofogctl' + - script: | echo $(gcp.svcacc) | docker login -u _json_key --password-stdin https://gcr.io displayName: 'Docker connect to Registry' - script: | - ./start.sh - displayName: 'Start Connector, Controller, and Agent' + ./start.sh tutorial + # Use dev version of agent and controller until 1.3.0 release + # ./start.sh -ct gcr.io/focal-freedom-236620/controller:develop -a gcr.io/focal-freedom-236620/agent:develop -cn gcr.io/focal-freedom-236620/connector:develop + displayName: 'Start Connector, Controller, Agent, and tutorial microservices' - script: | ./test.sh diff --git a/docker-compose-iofog.yml b/docker-compose-iofog.yml deleted file mode 100644 index 5d58dd2..0000000 --- a/docker-compose-iofog.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: "3" -services: - iofog-connector: - image: iofog-connector:local - build: - context: ./services/iofog/iofog-connector - args: - - LOCAL_CONNECTOR_PACKAGE - container_name: iofog-connector - ports: - - "53321:8080" - network_mode: bridge - - iofog-controller: - image: iofog-controller:local - build: - context: ./services/iofog/iofog-controller - args: - - LOCAL_CONTROLLER_PACKAGE - container_name: iofog-controller - depends_on: - - iofog-connector - ports: - - "51121:51121" - environment: - - NODE_ENV=development - links: - - iofog-connector:iofog-connector - network_mode: bridge - - iofog-agent: - image: iofog-agent:local - build: - context: ./services/iofog/iofog-agent - args: - - LOCAL_AGENT_PACKAGE - depends_on: - - iofog-controller - privileged: true - volumes: - - /var/run/docker.sock:/var/run/docker.sock - container_name: iofog-agent - ports: - - "8081:22" - - "54321:54321" - links: - - iofog-controller:iofog-controller - network_mode: bridge - - iofog-init: - build: ./init/iofog - container_name: iofog-init - depends_on: - - iofog-controller - volumes: - - /var/run/docker.sock:/var/run/docker.sock - links: - - iofog-controller:iofog-controller - - iofog-connector:iofog-connector - network_mode: bridge diff --git a/docker-compose-tutorial.yml b/docker-compose-tutorial.yml deleted file mode 100644 index 36755dd..0000000 --- a/docker-compose-tutorial.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: "3" -services: - tutorial-init: - build: ./init/tutorial - container_name: tutorial-init - depends_on: - - iofog-controller - volumes: - - /var/run/docker.sock:/var/run/docker.sock - links: - - iofog-controller:iofog-controller - network_mode: bridge diff --git a/init/iofog/.gitignore b/init/iofog/.gitignore new file mode 100644 index 0000000..9fa6d25 --- /dev/null +++ b/init/iofog/.gitignore @@ -0,0 +1 @@ +local-stack.yaml diff --git a/init/iofog/Dockerfile b/init/iofog/Dockerfile deleted file mode 100644 index 9449a73..0000000 --- a/init/iofog/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM docker:dind - -RUN apk add --no-cache curl jq - -ADD ./provision.sh / - -CMD ["sh", "-c", "/provision.sh"] diff --git a/init/iofog/provision.sh b/init/iofog/provision.sh deleted file mode 100755 index d431a66..0000000 --- a/init/iofog/provision.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env sh - -set -o errexit -o noclobber -o nounset -cd "$(dirname "$0")" - -function waitForController() { - while true; do - STATUS=$(curl --request GET --url "${CONTROLLER_HOST}/status" 2>/dev/null | jq -r ".status") - [[ "${STATUS}" == "online" ]] && break || echo "Waiting for Controller..." - sleep 2 - done -} - -function waitForAgent() { - while true; do - STATUS=$(docker exec iofog-agent iofog-agent status | awk -F': ' '/ioFog daemon/{print $2}') - [[ "${STATUS}" == "RUNNING" ]] && break || echo "Waiting for Agent..." - sleep 2 - done -} - -function waitForConnector() { - while true; do - STATUS=$(curl --request POST --url "${CONNECTOR_HOST}/status" \ - --header 'Content-Type: application/x-www-form-urlencoded' --data mappingid=all 2>/dev/null \ - | jq -r '.status') - [[ "${STATUS}" == "running" ]] && break || echo "Waiting for Connector..." - sleep 2 - done -} - -function createUser() { - echo -n "Creating user John Doe... " - local RET=$(curl --request POST --url "${CONTROLLER_HOST}/user/signup" \ - --header 'Content-Type: application/json' \ - --data '{"email":"user@domain.com","firstName":"John","lastName":"Doe","password":"#Bugs4Fun"}' \ - 2>/dev/null) - local RET_MSG=$(echo $RET | jq -r '.message') - local RET_UID=$(echo $RET | jq -r '.userId') - [[ "${RET_MSG}" == "null" ]] && echo "${RET_UID}" || echo "${RET_MSG}" -} - -function login() { - echo -n "Logging in as user user@domain.com... " - TOKEN=$(curl --request POST --url "${CONTROLLER_HOST}/user/login" \ - --header 'Content-Type: application/json' \ - --data '{"email":"user@domain.com","password":"#Bugs4Fun"}' 2>/dev/null \ - | jq -r '.accessToken') - echo "${TOKEN}" -} - -function createDefaultFog() { - # Delete all fogs with the same default fog name. This is in case the script is run repeatedly. - local DEFAULT_FOGS=$(curl --request GET --url "${CONTROLLER_HOST}/iofog-list" \ - --header "Authorization: ${TOKEN}" \ - --header 'Content-Type: application/json' 2>/dev/null \ - | jq -r ".fogs[] | select(.name == \"${DEFAULT_FOG}\") | .uuid") - for FOG_UUID in ${DEFAULT_FOGS}; do - echo "Deleting pre-existing default fog: ${FOG_UUID}..." - curl --request DELETE --url "${CONTROLLER_HOST}/iofog/${FOG_UUID}" \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' 2>/dev/null - done - - # Wait for all the deleted fogs to be actually delete. - while true; do - DEFAULT_FOGS=$(curl --request GET --url "${CONTROLLER_HOST}/iofog-list" \ - --header "Authorization: ${TOKEN}" \ - --header 'Content-Type: application/json' 2>/dev/null \ - | jq -r ".fogs[] | select(.name == \"${DEFAULT_FOG}\") | .uuid") - [[ -z "${DEFAULT_FOGS}" ]] && break || echo "Waiting for pre-existing default fogs to be deleted..." - sleep 2 - done - - echo -n "Creating default fog... " - curl --request POST --url "${CONTROLLER_HOST}/iofog" \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data "{\"name\": \"${DEFAULT_FOG}\",\"fogType\": 1}" 2> /dev/null 1>&2 - echo "${DEFAULT_FOG}" - - echo -n 'Retrieving UUID of default fog... ' - FOG_UUID=$(curl --request GET --url "${CONTROLLER_HOST}/iofog-list" \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' 2> /dev/null \ - | jq -r ".fogs[] | select(.name == \"${DEFAULT_FOG}\") | .uuid") - echo "${FOG_UUID}" -} - -function configureAgent() { - echo "Configuring Agent..." - docker exec iofog-agent iofog-agent config -idc off > /dev/null - docker exec iofog-agent iofog-agent config -a "${CONTROLLER_HOST}" > /dev/null -} - -function configureController() { - echo "Configuring Controller..." - CONNECTOR_IP=$(getent hosts iofog-connector | awk '{ print $1 }') - # TODO this is the only "docker exec" for controller - needs to be replaced with REST API - docker exec iofog-controller \ - iofog-controller connector add -n iofog-connector -d "${CONNECTOR_IP}" -i "${CONNECTOR_IP}" -H -} - -function provisionAgent() { - echo -n "Retrieving provisioning key for default fog... " - PROVISION_KEY=$(curl --request GET --url "${CONTROLLER_HOST}/iofog/${FOG_UUID}/provisioning-key" \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' 2> /dev/null \ - | jq -r .key) - echo "${PROVISION_KEY}" - - docker exec iofog-agent iofog-agent provision "${PROVISION_KEY}" -} - -function createDefaultFlow() { - echo -n "Creating default flow... " - curl --request POST --url "${CONTROLLER_HOST}/flow" \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data "{\"name\": \"${DEFAULT_FLOW}\",\"isActivated\":true}" 2> /dev/null 1>&2 - - # Retrieve just created flow's id - FLOW_ID=$(curl --request GET --url "${CONTROLLER_HOST}/flow" \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' 2> /dev/null \ - | jq -r ".flows[] | select(.name == \"${DEFAULT_FLOW}\") | .id") - echo "${FLOW_ID}" -} - -echo "Initializing ioFog stack. This may take a minute or two." - -docker --version # Check if docker is available. Needs docker socket mapped in order to talk to the Agent -CONTROLLER_HOST="http://iofog-controller:51121/api/v3" -CONNECTOR_HOST="http://iofog-connector:8080/api/v2" -DEFAULT_FOG="ioFog Agent" -DEFAULT_FLOW="Default Flow" - -waitForConnector -waitForController -waitForAgent -configureController -createUser -login -createDefaultFog -configureAgent -provisionAgent -createDefaultFlow - -echo "Successfully initialized ioFog stack." diff --git a/init/tutorial/Dockerfile b/init/tutorial/Dockerfile deleted file mode 100644 index 9449a73..0000000 --- a/init/tutorial/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM docker:dind - -RUN apk add --no-cache curl jq - -ADD ./provision.sh / - -CMD ["sh", "-c", "/provision.sh"] diff --git a/init/tutorial/config.yaml b/init/tutorial/config.yaml new file mode 100644 index 0000000..a21540f --- /dev/null +++ b/init/tutorial/config.yaml @@ -0,0 +1,44 @@ +--- +apiVersion: iofog.org/v1 +kind: Application +metadata: + name: tutorial +spec: + microservices: + - name: Sensors + agent: + name: local-agent + config: {} + images: + x86: iofog/sensors:latest + registry: remote + volumes: [] + ports: [] + env: [] + - name: Rest API + agent: + name: local-agent + config: {} + images: + x86: iofog/freeboard-api:latest + registry: remote + volumes: [] + ports: + - internal: 80 + external: 10101 + env: [] + - name: Freeboard + agent: + name: local-agent + config: {} + images: + x86: iofog/freeboard:latest + registry: remote + volumes: [] + ports: + - internal: 80 + external: 10102 + env: [] + routes: + - from: Sensors + to: Rest API \ No newline at end of file diff --git a/init/tutorial/provision.sh b/init/tutorial/provision.sh deleted file mode 100755 index 54d22e6..0000000 --- a/init/tutorial/provision.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env sh - -# TODO finish tutorial setup -# TODO split --data into multiple lines - -set -o errexit -o noclobber -o nounset -cd "$(dirname "$0")" - -function waitForController() { - while true; do - local STATUS=$(curl --request GET --url "${CONTROLLER_HOST}/status" 2>/dev/null | jq -r ".status") - [[ "${STATUS}" == "online" ]] && break || echo "Waiting for Controller..." - sleep 2 - done -} - -function login() { - echo -n "Logging in as user user@domain.com... " - TOKEN=$(curl --request POST --url "${CONTROLLER_HOST}/user/login" \ - --header 'Content-Type: application/json' \ - --data '{"email":"user@domain.com","password":"#Bugs4Fun"}' 2>/dev/null \ - | jq -r '.accessToken') - echo "${TOKEN}" -} - -function getDemoFogId() { - echo -n "Looking up default fog... " - FOG_ID=$(curl --request GET --url "${CONTROLLER_HOST}/iofog-list" \ - --header "Authorization: ${TOKEN}" \ - --header 'Content-Type: application/json' 2>/dev/null \ - | jq -r ".fogs[] | select(.name == \"${DEFAULT_FOG}\") | .uuid") - echo "${FOG_ID}" -} - -function getDemoFlowId() { - echo -n "Looking up default flow... " - FLOW_ID=$(curl --request GET --url "${CONTROLLER_HOST}/flow" \ - --header "Authorization: ${TOKEN}" \ - --header 'Content-Type: application/json' 2>/dev/null \ - | jq -r ".flows[] | select(.name == \"${DEFAULT_FLOW}\") | .id") - echo "${FLOW_ID}" -} - -function startMicroserviceSensors() { - echo -n 'Registering Sensor microservice in the catalog... ' - SENSORS_CATALOG_ID=$(curl --request POST --url $CONTROLLER_HOST/catalog/microservices \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data '{"name":"Sensors","category": "DEMO","publisher":"Edgeworx","registryId":1,"images":[{"containerImage":"iofog/sensors:latest","fogTypeId":1}]}' \ - 2> /dev/null | jq -r .id) - echo "${SENSORS_CATALOG_ID}" - - echo -n 'Creating Sensor microservice... ' - SENSORS_UUID=$(curl --request POST --url $CONTROLLER_HOST/microservices \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data '{"name":"Sensors","config":"{}","catalogItemId":'"${SENSORS_CATALOG_ID}"',"flowId":'"${FLOW_ID}"',"iofogUuid":"'"${FOG_ID}"'","rootHostAccess":false,"logSize":5,"volumeMappings":[],"ports":[],"routes":[]}' \ - 2> /dev/null | jq -r .uuid) - echo "${SENSORS_UUID}" -} - -function startMicroserviceRestApi() { - echo -n 'Registering REST API microservice in the catalog... ' - RESTAPI_CATALOG_ID=$(curl --request POST --url $CONTROLLER_HOST/catalog/microservices \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data '{"name":"Rest API","category": "DEMO","publisher":"Edgeworx","registryId":1,"images":[{"containerImage":"iofog/freeboard-api:latest","fogTypeId":1}]}' \ - 2> /dev/null | jq -r .id) - echo "${RESTAPI_CATALOG_ID}" - - echo -n 'Creating REST API microservice... ' - RESTAPI_UUID=$(curl --request POST --url $CONTROLLER_HOST/microservices \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data '{"name":"Rest API","config":"{}","catalogItemId":'"${RESTAPI_CATALOG_ID}"',"flowId":'"${FLOW_ID}"',"iofogUuid":"'"${FOG_ID}"'","rootHostAccess":false,"logSize":5,"volumeMappings":[],"ports":[{"internal":80,"external":10101,"publicMode":false}],"routes":[]}' \ - 2> /dev/null | jq -r .uuid) - echo "${RESTAPI_UUID}" -} - -function startMicroserviceFreeboard() { - echo -n 'Registering Freeboard microservice in the catalog... ' - FREEBOARD_CATALOG_ID=$(curl --request POST --url $CONTROLLER_HOST/catalog/microservices \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data '{"name":"freeboard","category": "DEMO","publisher":"Edgeworx","registryId":1,"images":[{"containerImage":"iofog/freeboard:latest","fogTypeId":1}]}' \ - 2> /dev/null | jq -r .id) - echo "${FREEBOARD_CATALOG_ID}" - - echo -n 'Creating Freeboard microservice... ' - FREEBOARD_UUID=$(curl --request POST --url $CONTROLLER_HOST/microservices \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' \ - --data '{"name":"Freeboard","config":"{}","catalogItemId":'"${FREEBOARD_CATALOG_ID}"',"flowId":'"${FLOW_ID}"',"iofogUuid":"'"${FOG_ID}"'","rootHostAccess":false,"logSize":5,"volumeMappings":[],"ports":[{"internal":80,"external":10102,"publicMode":false}],"routes":[]}' \ - 2> /dev/null | jq -r .uuid) - echo "${FREEBOARD_UUID}" -} - -function routeSensorsToApi() { - echo 'Creating route between Sensors and REST API microservices...' - curl --request POST --url "${CONTROLLER_HOST}/microservices/${SENSORS_UUID}/routes/${RESTAPI_UUID}" \ - --header "Authorization: ${TOKEN}" --header 'Content-Type: application/json' 2> /dev/null -} - -function waitForService() { - local IMAGE="$1" - echo -n "Waiting service $IMAGE..." - while true; do - local STATUS=$(docker inspect -f {{.State.Running}} $(docker ps -q --filter "ancestor=$IMAGE") 2>/dev/null) - [[ "${STATUS}" == "true" ]] && break || echo -n "." - sleep 2 - done - echo " OK" -} - -function waitForAllServices() { - waitForService "iofog/sensors:latest" - waitForService "iofog/freeboard-api:latest" - waitForService "iofog/freeboard:latest" -} - -echo "Initializing tutorial. This may take a minute or two." - -CONTROLLER_HOST="http://iofog-controller:51121/api/v3" -DEFAULT_FOG="ioFog Agent" -DEFAULT_FLOW="Default Flow" - -waitForController -login -getDemoFogId -getDemoFlowId -startMicroserviceSensors -startMicroserviceRestApi -startMicroserviceFreeboard -routeSensorsToApi -waitForAllServices - -echo "Successfully initialized tutorial." - - - - diff --git a/services/iofog/iofog-agent/.gitignore b/services/iofog/iofog-agent/.gitignore deleted file mode 100644 index cc6078c..0000000 --- a/services/iofog/iofog-agent/.gitignore +++ /dev/null @@ -1 +0,0 @@ -id_ecdsa.pub diff --git a/services/iofog/iofog-agent/Dockerfile b/services/iofog/iofog-agent/Dockerfile deleted file mode 100644 index 1cc3b83..0000000 --- a/services/iofog/iofog-agent/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM iofog/ubuntu-16.04-java8 - -ARG LOCAL_AGENT_PACKAGE -# Copy install script and local package if there is one (No conditional copy in docker) -COPY ./install.sh ${LOCAL_AGENT_PACKAGE} /opt/iofog-agent/ - -# Install our deps -RUN apt-get update -qq && apt-get install -qqy \ - sudo \ - curl \ - software-properties-common \ - openssh-server \ - supervisor \ - && rm -rf /var/lib/apt/lists/* - -# Install iofog-agent (script requires sudo, curl and software-properties-common) -RUN /opt/iofog-agent/install.sh ${LOCAL_AGENT_PACKAGE} -RUN rm /opt/iofog-agent/install.sh - -# SSH Magic -# Allows the test's container "test-runner" access to iofog-agent, due to the agent's lack of REST API -COPY id_ecdsa.pub / -RUN mkdir -p /root/.ssh -RUN cat /id_ecdsa.pub > /root/.ssh/authorized_keys -RUN mkdir /var/run/sshd -RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd -ENV NOTVISIBLE "in users profile" -RUN echo "export VISIBLE=now" >> /etc/profile -EXPOSE 22 - -# Copy our configs -COPY config.xml /etc/iofog-agent/config.xml -COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf - -CMD ["/usr/bin/supervisord"] diff --git a/services/iofog/iofog-agent/config.xml b/services/iofog/iofog-agent/config.xml deleted file mode 100644 index 5c55bd5..0000000 --- a/services/iofog/iofog-agent/config.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - http://iofog-controller:51121/api/v3/ - - /etc/iofog-agent/cert.crt - - eth0 - - unix:///var/run/docker.sock - - 50 - - /var/lib/iofog-agent/ - - 4096 - - 80.0 - - 10.0 - - /var/log/iofog-agent/ - - 10 - - 30 - - 60 - - 10 - - off - - 60 - - off - - intel_amd - - on - diff --git a/services/iofog/iofog-agent/install.sh b/services/iofog/iofog-agent/install.sh deleted file mode 100755 index 83c98bc..0000000 --- a/services/iofog/iofog-agent/install.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# If local agent provided, install from local package, otherwise go to packagecloud -if [ ! -z "$1" ] && [ ! "$1" = "./install.sh" ]; then - echo "============> Installing local agent" - dpkg -i /opt/iofog-agent/"$1" - rm -f /opt/iofog-agent/"$1" -else - wget -q -O - https://packagecloud.io/install/repositories/iofog/iofog-agent/script.deb.sh | bash - apt-get install iofog-agent -fi \ No newline at end of file diff --git a/services/iofog/iofog-agent/supervisord.conf b/services/iofog/iofog-agent/supervisord.conf deleted file mode 100644 index 5d55f75..0000000 --- a/services/iofog/iofog-agent/supervisord.conf +++ /dev/null @@ -1,12 +0,0 @@ -[supervisord] -nodaemon=true - -[program:sshd] -command=/usr/sbin/sshd -D - -; TODO supervisor expects non-daemonized program, iofog-agent is daemonized -; http://supervisord.org/subprocess.html#nondaemonizing-of-subprocesses -[program:agent] -command=bash -c 'service iofog-agent start && tail -f /dev/null' -stderr_logfile=/var/log/agent.err.log -stdout_logfile=/var/log/agent.out.log diff --git a/services/iofog/iofog-connector/Dockerfile b/services/iofog/iofog-connector/Dockerfile deleted file mode 100644 index 757dbe3..0000000 --- a/services/iofog/iofog-connector/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM iofog/ubuntu-16.04-java8 - -ARG LOCAL_CONNECTOR_PACKAGE -# Copy local package, or default install script (No conditional copy in docker) -COPY ./install.sh ${LOCAL_CONNECTOR_PACKAGE} /opt/iofog-connector/ - -# Install all our deps -RUN apt-get update -qq && apt-get install -qqy \ - sudo \ - curl \ - software-properties-common \ - && rm -rf /var/lib/apt/lists/* - -# Install iofog-connector (script requires sudo, curl and software-properties-common) -RUN /opt/iofog-connector/install.sh ${LOCAL_CONNECTOR_PACKAGE} -RUN rm /opt/iofog-connector/install.sh - -# Copy in the connector configuration -COPY iofog-connector.conf /etc/iofog-connector/iofog-connector.conf - -ENTRYPOINT [ "sh", "-c", "service iofog-connector start && tail -f /dev/null" ] diff --git a/services/iofog/iofog-connector/install.sh b/services/iofog/iofog-connector/install.sh deleted file mode 100755 index 8ac9b94..0000000 --- a/services/iofog/iofog-connector/install.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# If local connector provided, install from local package, otherwise go to packagecloud -if [ ! -z "$1" ] && [ ! "$1" = "./install.sh" ]; then - echo "============> Installing local connector" - dpkg -i /opt/iofog-connector/"$1" - rm -f /opt/iofog-connector/"$1" -else - wget -q -O - https://packagecloud.io/install/repositories/iofog/iofog-connector/script.deb.sh | bash - apt-get install iofog-connector -fi \ No newline at end of file diff --git a/services/iofog/iofog-connector/iofog-connector.conf b/services/iofog/iofog-connector/iofog-connector.conf deleted file mode 100644 index c2d575c..0000000 --- a/services/iofog/iofog-connector/iofog-connector.conf +++ /dev/null @@ -1,10 +0,0 @@ -{ - "ports": [ - "6000-9999", - "30000-49999" - ], - "exclude": [], - "broker": 12345, - "address": "127.0.0.1", - "dev": true -} diff --git a/services/iofog/iofog-controller/Dockerfile b/services/iofog/iofog-controller/Dockerfile deleted file mode 100644 index 2a8dab1..0000000 --- a/services/iofog/iofog-controller/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM node:8.16.0-alpine - -ARG LOCAL_CONTROLLER_PACKAGE -# Copy local package, or default install script (No conditional copy in docker) -COPY ./install.sh ${LOCAL_CONTROLLER_PACKAGE} /opt/iofog-controller/ - -# Install iofog-controller -RUN /opt/iofog-controller/install.sh ${LOCAL_CONTROLLER_PACKAGE} -RUN rm /opt/iofog-controller/install.sh - -ENTRYPOINT [ "sh", "-c", "iofog-controller start && tail -f /dev/null" ] diff --git a/services/iofog/iofog-controller/install.sh b/services/iofog/iofog-controller/install.sh deleted file mode 100755 index 6840c42..0000000 --- a/services/iofog/iofog-controller/install.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# If local controller provided, install from local package, otherwise go to npm repository -if [ ! -z "$1" ] && [ ! "$1" = "./install.sh" ]; then - echo "============> Installing local controller" - npm install --unsafe-perm -g /opt/iofog-controller/"$1" - rm -f /opt/iofog-controller/"$1" -else - npm i -g iofogcontroller@1.2 --unsafe-perm -fi \ No newline at end of file diff --git a/start.sh b/start.sh index 718ec52..5dd4156 100755 --- a/start.sh +++ b/start.sh @@ -19,98 +19,103 @@ printHelp() { echo "" echo "Options:" echo " -h, --help print this help / usage" - echo " -a, --agent specify a local agent package" - echo " -ct, --controller specify a local controller package" - echo " -cn, --connector specify a local connector package" - echo " --no-cache prevent the usage of cache during the build step" + echo " -a, --agent specify a local agent image" + echo " -ct, --controller specify a local controller image" + echo " -cn, --connector specify a local connector image" echo "" echo "Arguments:" echo " [environment] setup demo application, optional, default: iofog" echo " supported values: iofog, tutorial" } -checkForComposeFile() { - local ENVIRONMENT="$1" - local COMPOSE_FILE="docker-compose-${ENVIRONMENT}.yml" - if [[ ! -f "${COMPOSE_FILE}" ]]; then - echoError "Environment configuration for \"${ENVIRONMENT}\" does not exist!" - exit 2 +startIofog() { + # If stack is running, skip + local CONTROLLER_CONTAINER_ID=$(docker ps -q --filter="name=iofog-controller") + if ! [[ -z "${CONTROLLER_CONTAINER_ID}" ]]; then + return fi + + echo "--- +apiVersion: iofog.org/v1 +kind: ControlPlane +metadata: + name: local-ecn +spec: + iofogUser: + name: test + surname: local + email: user@domain.com + password: '#Bugs4Fun' + controllers: + - name: local-controller + host: localhost + container: + image: $CONTROLLER_IMAGE +--- +apiVersion: iofog.org/v1 +kind: Connector +metadata: + name: local-connector +spec: + host: localhost + container: + image: $CONNECTOR_IMAGE +--- +apiVersion: iofog.org/v1 +kind: Agent +metadata: + name: local-agent +spec: + host: localhost + container: + image: $AGENT_IMAGE +" >| init/iofog/local-stack.yaml + + echoInfo "Deploying containers for ioFog stack..." + iofogctl deploy -f init/iofog/local-stack.yaml } -startIofog() { - echoInfo "Building containers for ioFog stack..." - local BUILD_ARGS="--build-arg LOCAL_CONTROLLER_PACKAGE=${CONTROLLER_PACKAGE} --build-arg LOCAL_CONNECTOR_PACKAGE=${CONNECTOR_PACKAGE} --build-arg LOCAL_AGENT_PACKAGE=${AGENT_PACKAGE}" - local COMPOSE_BUILD_ARGS="${IOFOG_BUILD_NO_CACHE} ${BUILD_ARGS:=""}" - local SERVICE_LIST="iofog-connector iofog-controller iofog-agent iofog-init" - docker-compose -f "docker-compose-iofog.yml" build ${COMPOSE_BUILD_ARGS} ${SERVICE_LIST} > /dev/null - - echoInfo "Spinning up containers for ioFog stack..." - docker-compose -f "docker-compose-iofog.yml" up --detach --no-recreate - - echoInfo "Initializing iofog stack..." - docker logs -f "iofog-init" # wait for the ioFog stack initialization - RET=$(docker wait "iofog-init") - if [[ "$RET" != "0" ]]; then - echoError "Failed to initialize ioFog stack!" - exit 3 +checkProvisioning() { + AGENT_UUID=$(docker exec iofog-agent iofog-agent info | grep 'UUID' | awk '{print $4}') + + if [ "$AGENT_UUID" == "not" ]; then + echoError "Failed to provision the agent" + return 1 fi - echoInfo "Successfully initialized ioFog stack." } startEnvironment() { local ENVIRONMENT="$1" - local COMPOSE_PARAM="-f docker-compose-${ENVIRONMENT}.yml" - - echoInfo "Building containers for ${ENVIRONMENT} environment..." - docker-compose -f "docker-compose-iofog.yml" -f "docker-compose-${ENVIRONMENT}.yml" \ - build "${ENVIRONMENT}-init" > /dev/null - - echoInfo "Spinning up containers for ${ENVIRONMENT} environment..." - docker-compose -f "docker-compose-iofog.yml" -f "docker-compose-${ENVIRONMENT}.yml" \ - up --detach --no-recreate "${ENVIRONMENT}-init" - - echoInfo "Initializing ${ENVIRONMENT} environment..." - docker logs -f "${ENVIRONMENT}-init" # wait for the ioFog stack initialization - RET=$(docker wait "${ENVIRONMENT}-init") - if [[ "$RET" != "0" ]]; then - echoError "Failed to initialize ${ENVIRONMENT} environment!" - exit 3 - fi - echoInfo "Successfully setup ${ENVIRONMENT} environment." + + echoInfo "Deploying ${ENVIRONMENT} application..." + iofogctl deploy application -f "init/${ENVIRONMENT}/config.yaml" echoInfo "It may take a while before ioFog stack creates all ${ENVIRONMENT} microservices." + echo "" } ENVIRONMENT='' IOFOG_BUILD_NO_CACHE='' -AGENT_PACKAGE='' -CONTROLLER_PACKAGE='' -CONNECTOR_PACKAGE='' +AGENT_IMAGE='docker.io/iofog/agent:1.3.0' +CONTROLLER_IMAGE='docker.io/iofog/controller:1.3.1' +CONNECTOR_IMAGE='docker.io/iofog/connector:1.3.0' while [[ "$#" -ge 1 ]]; do case "$1" in -h|--help) printHelp exit 0 ;; - --no-cache) - IOFOG_BUILD_NO_CACHE="--no-cache" - shift - ;; -a|--agent) - AGENT_PACKAGE="local-agent-package.deb" - cp -i "$2" "./services/iofog/iofog-agent/$AGENT_PACKAGE" || true + AGENT_IMAGE=${2:-$AGENT_IMAGE} shift shift ;; -ct|--controller) - CONTROLLER_PACKAGE="local-controller-package.tgz" - cp -i "$2" "./services/iofog/iofog-controller/$CONTROLLER_PACKAGE" || true + CONTROLLER_IMAGE=${2:-$CONTROLLER_IMAGE} shift shift ;; -cn|--connector) - CONNECTOR_PACKAGE="local-connector-package.deb" - cp -i "$2" "./services/iofog/iofog-connector/$CONNECTOR_PACKAGE" || true + CONNECTOR_IMAGE=${2:-$CONNECTOR_IMAGE} shift shift ;; @@ -131,21 +136,11 @@ prettyHeader "Starting ioFog Demo" # Figure out which environment we are going to be starting. By default, setup only the ioFog stack ENVIRONMENT=${ENVIRONMENT:="iofog"} -checkForComposeFile "iofog" - -if [[ "${ENVIRONMENT}" != "iofog" ]]; then checkForComposeFile "${ENVIRONMENT}"; fi - echoInfo "Starting \"${ENVIRONMENT}\" demo environment..." -# Create a new ssh key -echoInfo "Creating new ssh key for tests..." -rm -f test/conf/id_ecdsa* -ssh-keygen -t ecdsa -N "" -f test/conf/id_ecdsa -q -cp -f test/conf/id_ecdsa.pub services/iofog/iofog-agent/ - # Start ioFog stack -# TODO check if this environment is up or not startIofog +checkProvisioning # Optionally start another environment if [[ "${ENVIRONMENT}" != "iofog" ]]; then @@ -157,5 +152,5 @@ fi ./status.sh if [[ "${ENVIRONMENT}" == "tutorial" ]]; then - echoSuccess "## Visit https://iofog.org/docs/1.0.0/tutorial/introduction.html to continue with the ioFog tutorial." + echoSuccess "## Visit https://iofog.org/docs/1.3.0/tutorial/introduction.html to continue with the ioFog tutorial." fi diff --git a/status.sh b/status.sh index 82f725d..5b25976 100755 --- a/status.sh +++ b/status.sh @@ -16,10 +16,14 @@ prettyTitle "ioFog Demo Environment Status" echoInfo " $(docker ps --filter 'name=iofog')" echo +prettyTitle "ioFog Demo Edge Cloud Network Status" +echoInfo " $(iofogctl get all)" +echo + CONTROLLER_PORT="$(docker port iofog-controller | awk '{print $1}' | cut -b 1-5)" -if [ ! -z ${CONTROLLER_PORT} ]; then - echoSuccess "## iofog-controller is running at http://localhost:${CONTROLLER_PORT}" +if ! [[ -z ${CONTROLLER_PORT} ]]; then + echoSuccess "## iofog-controller is running at http://localhost:51121" else echoError "No iofog-controller container was found" fi diff --git a/stop.sh b/stop.sh index b27f875..5bd2812 100755 --- a/stop.sh +++ b/stop.sh @@ -38,14 +38,8 @@ prettyHeader "Stopping ioFog Demo..." # Stop ioFog stack echoInfo "Stopping all containers..." -docker-compose -f "docker-compose-iofog.yml" -f "docker-compose-tutorial.yml" down -v -# TODO stopping the ioFog stack leaves its microservices running - fix this properly -REMAINING_MSVC=`docker ps -q --filter 'name=iofog*'` - -if [ ! -z "${REMAINING_MSVC}" ]; then - docker rm -f ${REMAINING_MSVC} -fi +iofogctl delete all || iofogctl disconnect # Remove generated files find test/conf -type f -not -name ".gitignore" -exec rm -f {} \; diff --git a/test.sh b/test.sh index dec4cc1..a073ee0 100755 --- a/test.sh +++ b/test.sh @@ -31,21 +31,63 @@ IOFOG_RUNNING=$(docker inspect -f '{{.State.Running}}' iofog-agent iofog-connect if [[ "${IOFOG_RUNNING}" == "truetruetrue" ]]; then echoInfo "ioFog stack is running" else - echoError 'ioFog stack is not running! Please run `./start.sh iofog` first' + echoError 'ioFog stack is not running! Please run `./start.sh` first' exit 2 fi -echoInfo "Retrieving endpoints for ioFog stack" -AGENT_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' iofog-agent) -CONTROLLER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' iofog-controller) -CONNECTOR_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' iofog-connector) +# Create a new ssh key +echoInfo "Creating new ssh key for tests..." +rm -f test/conf/id_ecdsa* +ssh-keygen -t ecdsa -N "" -f test/conf/id_ecdsa -q + +# SSH Magic +# Allows the test's container "test-runner" access to iofog-agent, due to the agent's lack of REST API +AGENT_CONTAINER_ID=$(docker ps -q --filter="name=iofog-agent") + +# Configuring ssh on the agent +echoInfo "Configuring ssh on the Agent" +# Init log file +CONFIGURE_SSH_LOG_FILE=/tmp/configure_ssh.log +if [[ -f "${CONFIGURE_SSH_LOG_FILE}" ]]; then + rm "${CONFIGURE_SSH_LOG_FILE}" +fi +echo '' > "${CONFIGURE_SSH_LOG_FILE}" +{ + echo 'Removing /var/lib/apt/lists/lock' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent sudo rm /var/lib/apt/lists/lock >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Updating apt-get' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent apt-get update -y >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Installing Openssh-server' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent apt-get install -y --fix-missing openssh-server >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Running apt-get install -fy' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent apt-get install -fy >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Creating ~/.ssh' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent mkdir -p /root/.ssh >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + docker exec iofog-agent chmod 700 /root/.ssh >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Copying public key to ~/.ssh/authorized_keys' >> "${CONFIGURE_SSH_LOG_FILE}" + docker cp test/conf/id_ecdsa.pub "$AGENT_CONTAINER_ID:/root/.ssh/authorized_keys" >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + docker exec iofog-agent chmod 644 /root/.ssh/authorized_keys >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + docker exec iofog-agent chown root:root /root/.ssh/authorized_keys >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Creating /var/run/.sshd' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent mkdir -p /var/run/sshd >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Updating /etc/pam.d/sshd' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent sudo sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Updating /etc/ssh/sshd_config' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent sudo sed 's@#AuthorizedKeysFile %h/.ssh/authorized_keys@AuthorizedKeysFile %h/.ssh/authorized_keys@g' -i /etc/ssh/sshd_config >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 + echo 'Restarting ssh service' >> "${CONFIGURE_SSH_LOG_FILE}" + docker exec iofog-agent /bin/bash -c 'service ssh restart' >> "${CONFIGURE_SSH_LOG_FILE}" 2>&1 +} || { + echoError "Failed to configure ssh on agent container" + cat "${CONFIGURE_SSH_LOG_FILE}" + exit 1 +} echoInfo "Running Test Runner..." -docker run --rm --name test-runner --network bridge \ +docker run --rm --name test-runner --network local-iofog-network \ -v "$(pwd)/test/conf/id_ecdsa:/root/.ssh/id_ecdsa" \ - -e CONTROLLER="${CONTROLLER_IP}:51121" \ - -e CONNECTOR="${CONNECTOR_IP}:8080" \ - -e AGENTS="root@${AGENT_IP}:22" \ - iofog/test-runner:1.2 + -e CONTROLLER="iofog-controller:51121" \ + -e CONNECTOR="iofog-connector:8080" \ + -e AGENTS="root@iofog-agent:22" \ + iofog/test-runner:1.3 echoNotify "## Test Runner Tests complete" diff --git a/utils.sh b/utils.sh index a58b17d..b3be816 100755 --- a/utils.sh +++ b/utils.sh @@ -101,6 +101,22 @@ checkOSPlatform() { export ID D_NUM } +versionCompare() { + test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; +} + +checkIofogctl() { + IOFOGCTL_MINIMAL_VERSION="1.3.0" + if [[ -z "$(command -v iofogctl)" ]] ; then + echoError "iofogctl not found!" + exit 1; + fi + IOFOGCTL_VERSION=$(iofogctl version | sed -n 's/version: \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p') + if versionCompare "${IOFOGCTL_MINIMAL_VERSION}" "${IOFOGCTL_VERSION}"; then + echoError "iofogctl version not sufficient!" + exit 1; + fi +} # # The following are a bunch or pretty printing echo methods # @@ -139,3 +155,4 @@ echoError() { # Are we in debug mode? checkForDebug +checkIofogctl