diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b20eb2b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* +.vscode + +data-cube-manager/node_modules/ +deploy/dist/ +data-cube-manager/src/assets/env.js \ No newline at end of file diff --git a/CHANGES.md b/CHANGES.md index 8d3b5bf..57e6153 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,19 @@ # Changes +## Version 1.0.0 (2023-05-29) + +- Fix cube creation and start cube when dealing with combined collections +- Improvements on details cube - edit cube band info +- Display repository version on page +- Review compatibility table for multiple stac versions +- Add way create data cube for local folder [`#125`](https://github.com/brazil-data-cube/dc-manager/issues/125) +- Add way to customize bands on data cube creation +- Fix bug related misspelled ``Cyclic`` and ``Continuous`` temporal composition +- Improve check cube merges +- Add support to customize base url at runtime [`#146`](https://github.com/brazil-data-cube/dc-manager/issues/146) + + ## Version 1.0.0a2 (2023-01-30) - Fix cube creation and start cube when dealing with combined collections diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 9937f07..fbbdcfb 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -2,6 +2,12 @@ The `Data Cube Manager` supports a number of [cube-builder] and [bdc-stac] releases. +## NodeJS + +- **node** - >=13,<=16+. For versions 17+, make sure to use the following variable in order to launch application: ``NODE_OPTIONS=--openssl-legacy-provider``. +- **npm** - 8+. + + ## Services supported The versions of web services compatible to be run with the `Data Cube Manager` are: diff --git a/data-cube-manager/package-lock.json b/data-cube-manager/package-lock.json index ac1353e..d13499a 100644 --- a/data-cube-manager/package-lock.json +++ b/data-cube-manager/package-lock.json @@ -1,6 +1,6 @@ { "name": "data-cube-manager", - "version": "1.0.0a2", + "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/data-cube-manager/package.json b/data-cube-manager/package.json index 3859e7d..91681d6 100644 --- a/data-cube-manager/package.json +++ b/data-cube-manager/package.json @@ -1,6 +1,6 @@ { "name": "data-cube-manager", - "version": "1.0.0a2", + "version": "1.0.0", "license": "GPLv3", "scripts": { "ng": "ng", diff --git a/data-cube-manager/src/app/admin/components/reprocess-dialog/reprocess-dialog.component.ts b/data-cube-manager/src/app/admin/components/reprocess-dialog/reprocess-dialog.component.ts index 7380912..49d0ef1 100644 --- a/data-cube-manager/src/app/admin/components/reprocess-dialog/reprocess-dialog.component.ts +++ b/data-cube-manager/src/app/admin/components/reprocess-dialog/reprocess-dialog.component.ts @@ -111,7 +111,7 @@ export class ReprocessDialogComponent implements OnInit { data.collections = !Array.isArray(collections) ? collections.split(',') : collections; } - data.datacube = data.datacube; + data.datacube = `${data.datacube}-${this.data.datacube_version}`; data.force = !!this.data.force; await this.service.start(data); diff --git a/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts b/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts index 87f4de9..b4d06f2 100644 --- a/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts +++ b/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts @@ -84,8 +84,8 @@ export class CheckCubeComponent implements OnInit { if (this.cube.temporal_composition_schema) { const data = { - start_date: this.cube.start_date, - last_date: this.cube.end_date, + start_date: moment(this.cube.start_date).format(), + last_date: moment(this.cube.end_date).format(), ...this.cube.temporal_composition_schema } const respTimeline = await this.cbs.getTimeline(data); diff --git a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html index e3dcab8..b40a36f 100644 --- a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html +++ b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html @@ -34,9 +34,10 @@ <h4 class="card-title">{{ cube.title }}</h4> <tr style="border-bottom: 1px dotted #CCC; padding: 10px"> <td class="text-success">Bands Quicklook:</td> <td> - <mat-chip-list> - <mat-chip *ngFor="let band of cube.quicklook"> - {{ band }}</mat-chip> + <mat-chip-list *ngIf="cube.quicklook"> + <mat-chip style="background-color: rgb(255, 114, 114);">{{ cube.quicklook[0] }}</mat-chip> + <mat-chip style="background-color: rgb(32, 200, 32);">{{ cube.quicklook[1] }}</mat-chip> + <mat-chip style="background-color: rgb(118, 159, 255);">{{ cube.quicklook[2] }}</mat-chip> </mat-chip-list> </td> </tr> diff --git a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts index c7ca364..11a8d51 100644 --- a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts +++ b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts @@ -174,7 +174,7 @@ export class DetailsCubeComponent implements OnInit { cloneCubeObject['metadata'] = cloneCubeObject._metadata; delete cloneCubeObject._metadata; - this.removeProperty(cloneCubeObject, ['grid_ref_sys_id', 'composite_function_id']) + this.removeProperty(cloneCubeObject, ['grid_ref_sys_id', 'composite_function_id', 'summary']) for (let band of cloneCubeObject.bands) { this.removeProperty(band, ['_metadata', 'id', 'collection_id']); diff --git a/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.html b/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.html index 387e65c..305013a 100644 --- a/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.html +++ b/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.html @@ -6,6 +6,41 @@ message="You have no cubes created. Create your first now!"></app-alert> <div class="row"> + <div class="col-md-12"> + <form [formGroup]="form" *ngIf="filterSupported"> + <div class="search-box"> + <div class="row"> + <div class="col-lg-3 col-md-3 col-sm-6"> + <mat-form-field appearance="outline"> + <mat-label>Search</mat-label> + <input matInput formControlName="cubeName" placeholder="Filter data cube by name" (change)="filterCubes()"> + <button mat-icon-button matSuffix> + <mat-icon>search</mat-icon> + </button> + </mat-form-field> + </div> + + <div class="col-lg-3 col-md-3 col-sm-6"> + <mat-form-field appearance="fill"> + <mat-label>Type</mat-label> + <select matNativeControl formControlName="collectionType" (change)="filterCubes()"> + <option value="all">All</option> + <option value="cube">Cube</option> + <option value="mosaic">Mosaic</option> + </select> + </mat-form-field> + </div> + <div class="col-lg-2 col-md-2 col-sm-4"> + <section style="padding-top: 15px"> + <mat-checkbox formControlName="isPublic" (click)="filterCubes()">Public</mat-checkbox> + </section> + </div> + </div> + </div> + <hr /> + </form> + </div> + <div class="col-md-3" *ngFor="let cube of cubes"> <a [routerLink]="['/details-cube', getCubeFullName(cube)]"> @@ -20,7 +55,10 @@ <h4 class="card-title text-center">{{ cube.name }}-{{ cube.version }}</h4> </div> <div class="card-footer"> <div class="stats"> - <i class="material-icons">search</i> click here for more information + <i class="material-icons">search</i> + <mat-chip-list> + <mat-chip class="clickable">{{ cube.collection_type }}</mat-chip> + </mat-chip-list> </div> </div> </div> diff --git a/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.scss b/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.scss index 7df794a..4a571d6 100644 --- a/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.scss +++ b/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.scss @@ -3,4 +3,21 @@ margin: 10px auto; font-size: 1.5em; padding: 15px 20px!important; +} + +.search-box { + padding: 20px 10px 0 10px; + display: flex; + justify-content: space-between; + align-items: center; + + .row { + margin: 0; + width: 100%; + } + + button { + margin-top: -20px; + margin-right: 10px; + } } \ No newline at end of file diff --git a/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.ts b/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.ts index 53186e8..10d0edd 100644 --- a/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.ts +++ b/data-cube-manager/src/app/admin/pages/list-cubes/list-cubes.component.ts @@ -3,6 +3,9 @@ import { showLoading, closeLoading } from 'app/app.action'; import { Store } from '@ngrx/store'; import { AppState } from 'app/app.state'; import { CubeBuilderService } from 'app/services/cube-builder'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +import { environment } from '../../../../environments/environment' @Component({ @@ -12,14 +15,29 @@ import { CubeBuilderService } from 'app/services/cube-builder'; }) export class ListCubesComponent implements OnInit { public cubes; + public form: FormGroup; + public filterSupported: boolean = false; constructor( private cbs: CubeBuilderService, - private store: Store<AppState>) { } + private store: Store<AppState>, + private fb: FormBuilder) {} ngOnInit() { this.cubes = []; + this.form = this.fb.group({ + cubeName: [''], + collectionType: ['all'], + isPublic: [true] + }) this.getCubes(); + this.cbs.getBuilderVersion() + .then((version) => { + const [major, minor, patch] = version.split("."); + if (major && parseInt(major) > 0) { + this.filterSupported = true; + } + }) } async getCubes() { @@ -51,4 +69,21 @@ export class ListCubesComponent implements OnInit { return `${cube.name}-${cube.version}:${cube.id}` } + public async filterCubes() { + const { cubeName, collectionType, isPublic } = this.form.value; + + try { + this.store.dispatch(showLoading()); + const response = await this.cbs.getCubes(null, { collection_type: collectionType, public: isPublic, name: cubeName }); + this.cubes = response.map(c => { + return { ...c, status: c.status.toLowerCase() === 'error' ? 'danger' : c.status } + }) + + } catch (err) { + this.cubes = []; + } finally { + this.store.dispatch(closeLoading()); + } + } + } diff --git a/data-cube-manager/src/app/services/cube-builder.ts b/data-cube-manager/src/app/services/cube-builder.ts index 247aabe..c861318 100644 --- a/data-cube-manager/src/app/services/cube-builder.ts +++ b/data-cube-manager/src/app/services/cube-builder.ts @@ -1,6 +1,12 @@ import { Injectable } from '@angular/core'; import api from "./main"; +interface ICubesFilter { + name?: string; + public?: boolean; + collection_type?: 'all' | 'cube' | 'mosaic' +} + @Injectable({ providedIn: 'root' }) export class CubeBuilderService { @@ -26,12 +32,16 @@ export class CubeBuilderService { /** * get cube metadata */ - public async getCubes(id = null): Promise<any> { + public async getCubes(id = null, params: ICubesFilter = null): Promise<any> { let urlSuffix = '/cubes' if (id) { urlSuffix += `/${id}` } - const { data } = await api.get(`${this.urlCubeBuilder}${urlSuffix}`); + if (params === null) { + params = {} + } + + const { data } = await api.get(`${this.urlCubeBuilder}${urlSuffix}`, { params }); return data; } @@ -209,4 +219,10 @@ export class CubeBuilderService { const { data } = await api.post(`${this.urlCubeBuilder}${urlSuffix}`, infos); return data; } + + public async getBuilderVersion() { + const urlSuffix = `/`; + const { data } = await api.get(`${this.urlCubeBuilder}${urlSuffix}`); + return data.version; + } } diff --git a/data-cube-manager/src/env.txt b/data-cube-manager/src/env.txt index ea25794..86edca0 100644 --- a/data-cube-manager/src/env.txt +++ b/data-cube-manager/src/env.txt @@ -2,12 +2,12 @@ window.__env = window.__env || {}; // Environment Version (allow: 'cloud' or 'local') - window.__env.environmentVersion = ENVIRONMENT_VERSION; + window.__env.environmentVersion = DC_MANAGER_MODE; // Item prefix to be in merge scene - window.__env.itemPrefix = ITEM_PREFIX; + window.__env.itemPrefix = DC_MANAGER_ITEM_PREFIX; // Item base URL - window.__env.itemBaseUrl = ITEM_BASE_URL; + window.__env.itemBaseUrl = DC_MANAGER_ITEM_BASE_URL; }(this)); \ No newline at end of file diff --git a/data-cube-manager/src/index.html b/data-cube-manager/src/index.html index 9262671..092f0aa 100644 --- a/data-cube-manager/src/index.html +++ b/data-cube-manager/src/index.html @@ -24,7 +24,7 @@ <link href='https://fonts.googleapis.com/css?family=Roboto:400,700,300|Material+Icons' rel='stylesheet' type='text/css'> <base href="/"> - <link rel="shortcut icon" href="assets/images/icons/favicon.png" /> + <link rel="shortcut icon" href="assets/img/favicon.png" /> <script src="assets/env.js"></script> diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 00698a9..b154bff 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -1,12 +1,62 @@ -FROM golang:1.15 +# +# This file is part of Data Cube Manager. +# Copyright (C) 2023 INPE. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>. +# -RUN mkdir /usr/src/app +ARG GIT_COMMIT +ARG BASE_IMAGE=node:16-bullseye +FROM ${BASE_IMAGE} AS node -COPY dist /usr/src/app/dist -COPY server.go /usr/src/app/ +LABEL "org.repo.maintainer"="Brazil Data Cube <brazildatacube@inpe.br>" +LABEL "org.repo.title"="Docker image for Data Cube Builder GUI" +LABEL "org.repo.description"="Docker image for Data Cube Builder Graphical User Interface." +LABEL "org.repo.git_commit"="${GIT_COMMIT}" + +# Build arguments +## Base URL for image. Defaults to "/" +ARG DC_MANAGER_BASE_URL=/ + +# Add sources into container and build +COPY ./data-cube-manager /build/data-cube-manager + +WORKDIR /build/data-cube-manager + +RUN npm install && \ + npm run build -- --prod --base-href ${DC_MANAGER_BASE_URL} --deploy-url ${DC_MANAGER_BASE_URL} + + +# Final small image +FROM python:3.11-alpine + +# Build arguments +ARG DC_MANAGER_VERSION="1.0.0" +ARG DC_MANAGER_INSTALL_PATH="/opt/dc-manager/${DC_MANAGER_VERSION}" +ENV DC_MANAGER_BASE_URL="/" +ENV DC_MANAGER_VERSION=${DC_MANAGER_VERSION} +ENV DC_MANAGER_INSTALL_PATH=${DC_MANAGER_INSTALL_PATH} +# Defaults to local mode (on-premise services). Use "cloud" for AWS setup. +ENV DC_MANAGER_MODE=local + +COPY --from=node /build/deploy/dist ${DC_MANAGER_INSTALL_PATH} +COPY ./deploy/app.py ${DC_MANAGER_INSTALL_PATH} + +WORKDIR ${DC_MANAGER_INSTALL_PATH} + +RUN pip install flask gunicorn beautifulsoup4 --no-cache-dir -WORKDIR /usr/src/app EXPOSE 8080 -RUN go build -o main . -CMD ["./main"] \ No newline at end of file +CMD ["gunicorn", "-w4", "--bind", "0.0.0.0:8080", "app:app", "--max-requests=256"] \ No newline at end of file diff --git a/deploy/README.md b/deploy/README.md index 9fe7e68..10797f8 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,21 +1,53 @@ -# Web Portal - Deploy +# Deploying + +This section explains how to get the Data Cube Manager GUI up and running with Docker and Docker Compose. +If you do not have Docker installed, take a look at [this tutorial on how to install it in your system](https://docs.docker.com/install/) +See also the [`tutorial on how to install Docker Compose`](https://docs.docker.com/compose/install/) + ## Installation ### Requirements Make sure you have the following libraries installed: -- [`Node.js >= 8.x`](https://nodejs.org/en/) +- [`Node.js >= 8.x,<17`](https://nodejs.org/en/) - [`Angular CLI >= 7`](https://angular.io/) + +## Build and Running + +Use the following command to build docker image ``brazil-data-cube/dc-manager:1.0.0``: + +```bash +docker build --tag brazil-data-cube/dc-manager:1.0.0 \ + --build-arg DC_MANAGER_VERSION=1.0.0 \ + -f deploy/Dockerfile . ``` -cd ../data-cube-manager && npm install + +If the above command runs successfully, you will be able to list the docker image: + +```bash +brazil-data-cube/dc-manager 1.0.0 c1a745bfd47e 11 minutes ago 74.7MB ``` -## Running +In order to launch docker image, you may pass the following command: +```bash +docker run --interactive \ + --tty \ + --name dc-manager \ + --env DC_MANAGER_MODE=local \ + --env DC_MANAGER_ITEM_PREFIX=/cubes \ + --env DC_MANAGER_ITEM_BASE_URL=https://brazildatacube.dpi.inpe.br \ + --publish 8080:8080 \ + --env DC_MANAGER_BASE_URL=/ \ + brazil-data-cube/dc-manager:1.0.0 ``` -cd ../data-cube-manager && npm run build -cd ../deploy -docker build -t brazildatacube/data-cube-manager:0.0.1 -``` \ No newline at end of file + +You may need to replace the definition of some environment variables: + +- ``DC_MANAGER_MODE="local"``: used to tell Data Cube Manager to use context mode of ``local`` (on-premise services). You may also set to ``cloud`` if your application is running with AWS set up support. + +- ``DC_MANAGER_ITEM_PREFIX="/cubes"``: prefix used for data cube items in database. See [``Cube Builder Config``](https://cube-builder.readthedocs.io/en/latest/configuration.html#cube_builder.config.Config.ITEM_PREFIX). + +- ``DC_MANAGER_ITEM_BASE_URL="https://brazildatacube.dpi.inpe.br"``: base url prefix of HTTP served used to serve data cubes images. diff --git a/deploy/app.py b/deploy/app.py new file mode 100644 index 0000000..79a59cb --- /dev/null +++ b/deploy/app.py @@ -0,0 +1,118 @@ +# This file is part of Data Cube Manager. +# Copyright (C) 2023 INPE. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>. +# + +# This file represents a basic HTTP server for Angular app. +# It deals with base url internal in angular to avoid rebuild app in runtime. +# Make sure you have the following variables set +# - DC_MANAGER_VERSION: Version of current Data Cube Manager +# - DC_MANAGER_INSTALL_PATH: Path to the dist compiled files +# +# This file also generates "env.js" file in DC_MANAGER_INSTALL_PATH. You may pass this values using prefix "DC_MANAGER_": +# - DC_MANAGER_ITEM_PREFIX: Prefix for items in database +# - DC_MANAGER_ITEM_BASE_URL: Base HTTP url where files are served. +# - DC_MANAGER_MODE: Set context for DC-manager ("local" for on-premise services and "cloud" for AWS set up) + +import os +from pathlib import Path + +import bs4 +from flask import Flask, send_file + + +app = Flask(__name__) +PACKAGE_DIR = os.getenv("DC_MANAGER_INSTALL_PATH") +BASE_URL = os.getenv("DC_MANAGER_BASE_URL", "/") +INDEX_HTML_PATH = Path(PACKAGE_DIR, "index.html") + +if PACKAGE_DIR is None: + raise RuntimeError("The variable 'DC_MANAGER_INSTALL_PATH' must be set, got None.") + +if not INDEX_HTML_PATH.exists(): + raise IOError("Could not locate index.html in 'DC_MANAGER_INSTALL_PATH'. " + "Make sure to set 'DC_MANAGER_INSTALL_PATH' to the compiled module folder (dist).") + + +@app.route("/", defaults={"path": ""}) +@app.route("/<path:path>") +def index(path): + entry = Path(path) + + if entry.is_relative_to(BASE_URL): + entry = entry.relative_to(BASE_URL) + elif entry.is_relative_to(BASE_URL[1:]): + entry = entry.relative_to(BASE_URL[1:]) + + absolute = Path(PACKAGE_DIR) / entry + + if not absolute.exists() or not absolute.is_file(): + absolute = INDEX_HTML_PATH + + app.logger.debug(f"Path {path}, relative {str(entry)}, absolute {str(absolute)}") + + return send_file(str(absolute)) + + +def setup_html(): + with open(INDEX_HTML_PATH) as fd: + CONTENT = fd.read() + + + soup = bs4.BeautifulSoup(CONTENT, 'html.parser') + changed = False + + for link in soup.find_all(["base", "link", "script"]): + href = link.get("href") + if href and href.startswith("/") and not href.startswith(BASE_URL): + link["href"] = f"{BASE_URL}{href[1:]}" + changed = True + continue + + src = link.get("src") + if src and src.startswith("/") and not src.startswith(BASE_URL): + link["src"] = f"{BASE_URL}{src[1:]}" + changed = True + + if changed: + print(f"Configuring HTML base URL to {BASE_URL}") + with open(INDEX_HTML_PATH, "w") as fd: + fd.write(str(soup)) + + +def setup_env_file(base_dir: Path): + source_env_file = base_dir / "env.txt" + env_file = base_dir / "assets/env.js" + + with source_env_file.open(): + env_txt = source_env_file.read_text() + + for key, value in os.environ.items(): + if key.startswith("DC_MANAGER_"): + env_txt = env_txt.replace(key, f'"{value}"') + + with env_file.open(mode="w"): + env_file.write_text(env_txt) + + +def setup_app(): + setup_html() + setup_env_file(Path(PACKAGE_DIR)) + +# Configure Application Context +setup_app() + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=8080) diff --git a/deploy/server.go b/deploy/server.go deleted file mode 100644 index 5065613..0000000 --- a/deploy/server.go +++ /dev/null @@ -1,51 +0,0 @@ -package main - -import ( - "io/ioutil" - "log" - "net/http" - "os" - "strings" -) - -func Log(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !strings.HasPrefix(r.URL.Path, "/static/") { - log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL) - } - handler.ServeHTTP(w, r) - }) -} - -func rootHandler(w http.ResponseWriter, r *http.Request) { - if _, err := os.Stat("dist/" + r.URL.Path); os.IsNotExist(err) { - http.ServeFile(w, r, "dist/index.html") - } else { - http.ServeFile(w, r, "dist/"+r.URL.Path) - } -} - -func main() { - file_url := "/usr/src/app/dist/" - - // open and recreate file with env variables - data, err := ioutil.ReadFile(file_url + "env.txt") - if err != nil { - log.Fatal(err) - } - - new_content := strings.ReplaceAll(string(data), "URL_CUBE_BUILDER", "'"+os.Getenv("URL_CUBE_BUILDER")+"'") - new_content = strings.ReplaceAll(new_content, "ENVIRONMENT_VERSION", "'"+os.Getenv("ENVIRONMENT_VERSION")+"'") - new_content = strings.ReplaceAll(new_content, "ITEM_PREFIX", "'"+os.Getenv("ITEM_PREFIX")+"'") - new_content = strings.ReplaceAll(new_content, "ITEM_BASE_URL", "'"+os.Getenv("ITEM_BASE_URL")+"'") - err = ioutil.WriteFile(file_url+"assets/env.js", []byte(new_content), 0644) - if err != nil { - log.Fatalln(err) - } - - // start web app - http.HandleFunc("/", rootHandler) - - log.Println("Aplicação iniciada com sucesso") - http.ListenAndServe(":8080", Log(http.DefaultServeMux)) -} diff --git a/docker-compose.yml b/docker-compose.yml index 174bdc4..60d590b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,11 +2,10 @@ version: "3" services: datacube-manager: - image: registry.dpi.inpe.br/brazildatacube/data-cube-manager:1.0.0a1 + image: registry.dpi.inpe.br/brazil-data-cube/dc-manager:1.0.0 ports: - "8080:8080" environment: - - URL_CUBE_BUILDER=http://localhost:5000 - - ENVIRONMENT_VERSION=local - - ITEM_PREFIX=/cubes - - ITEM_BASE_URL=https://brazildatacube.dpi.inpe.br + - DC_MANAGER_MODE=local + - DC_MANAGER_ITEM_PREFIX=/cubes + - DC_MANAGER_ITEM_BASE_URL=https://brazildatacube.dpi.inpe.br