Skip to content

fix(Invoke): Fixed Windows Issue by shipping pre-built binaries for platforms #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/build-push-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3

- name: Download binaries
run: bash downloadBinaries.sh

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

Expand Down
8 changes: 7 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.17-alpine AS builder
FROM golang:1.21-alpine AS builder
ENV CGO_ENABLED=0
WORKDIR /backend
COPY vm/go.* .
Expand Down Expand Up @@ -55,6 +55,7 @@ LABEL org.opencontainers.image.title="LocalStack" \
com.docker.extension.changelog="https://github.com/localstack/localstack-docker-extension/blob/main/CHANGELOG.md"

COPY --from=builder /backend/bin/service /

COPY docker-compose.yaml .
COPY metadata.json .
COPY localstack.svg .
Expand All @@ -63,5 +64,10 @@ COPY --chmod=0755 scripts/windows/checkWSLOS.cmd /windows/checkWSLOS.cmd
COPY --chmod=0755 scripts/windows/checkUser.cmd /windows/checkUser.cmd
COPY --chmod=0755 scripts/darwin/checkUser.sh /darwin/checkUser.sh
COPY --chmod=0755 scripts/linux/checkUser.sh /linux/checkUser.sh
COPY --chmod=0755 binaries/windows/localstack-windows-amd.exe /windows/localstack-windows-amd.exe
COPY --chmod=0755 binaries/darwin/localstack-darwin-amd /darwin/localstack-darwin-amd
COPY --chmod=0755 binaries/darwin/localstack-darwin-arm /darwin/localstack-darwin-arm
COPY --chmod=0755 binaries/linux/localstack-linux-arm /linux/localstack-linux-arm
COPY --chmod=0755 binaries/linux/localstack-linux-amd /linux/localstack-linux-amd

CMD /service -socket /run/guest-services/extension-LocalStack.sock
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
IMAGE?=localstack/localstack-docker-desktop
TAG?=0.5.2
TAG?=0.5.3

BUILDER=buildx-multi-arch

INFO_COLOR = \033[0;36m
NO_COLOR = \033[m

build-extension: ## Build service image to be deployed as a desktop extension
docker build --tag=$(IMAGE):$(TAG) .
ls binaries/linux/localstack-* > /dev/null 2>&1 || ./downloadBinaries.sh
docker build --tag=$(IMAGE):$(TAG) .

install-extension: build-extension ## Install the extension
docker extension install $(IMAGE):$(TAG)
Expand Down
Empty file added binaries/.gitkeep
Empty file.
22 changes: 22 additions & 0 deletions downloadBinaries.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

latest_version=$(curl -s https://api.github.com/repos/localstack/localstack-cli/releases/latest | grep "tag_name" | cut -d'"' -f4)
version_number=$(echo "$latest_version" | grep -oP 'v(\d+\.\d+\.\d+)' | sed 's/v//')

wget "https://github.com/localstack/localstack-cli/releases/latest/download/localstack-cli-${version_number}-linux-amd64-onefile.tar.gz" -O localstack-cli-linux-amd64-onefile.tar.gz
wget "https://github.com/localstack/localstack-cli/releases/latest/download/localstack-cli-${version_number}-linux-arm64-onefile.tar.gz" -O localstack-cli-linux-arm64-onefile.tar.gz
wget "https://github.com/localstack/localstack-cli/releases/latest/download/localstack-cli-${version_number}-darwin-amd64-onefile.tar.gz" -O localstack-cli-darwin-amd64-onefile.tar.gz
wget "https://github.com/localstack/localstack-cli/releases/latest/download/localstack-cli-${version_number}-darwin-arm64-onefile.tar.gz" -O localstack-cli-darwin-arm64-onefile.tar.gz
wget "https://github.com/localstack/localstack-cli/releases/latest/download/localstack-cli-${version_number}-windows-amd64-onefile.zip" -O localstack-cli-windows-amd64-onefile.zip

mkdir ./binaries/linux
tar -xzvf localstack-cli-linux-amd64-onefile.tar.gz -C ./binaries/linux && mv ./binaries/linux/localstack ./binaries/linux/localstack-linux-amd && rm localstack-cli-linux-amd64-onefile.tar.gz
tar -xzvf localstack-cli-linux-arm64-onefile.tar.gz -C ./binaries/linux && mv ./binaries/linux/localstack ./binaries/linux/localstack-linux-arm && rm localstack-cli-linux-arm64-onefile.tar.gz

mkdir ./binaries/darwin
tar -xzvf localstack-cli-darwin-amd64-onefile.tar.gz -C ./binaries/darwin && mv ./binaries/darwin/localstack ./binaries/darwin/localstack-darwin-amd && rm localstack-cli-darwin-amd64-onefile.tar.gz
tar -xzvf localstack-cli-darwin-arm64-onefile.tar.gz -C ./binaries/darwin && mv ./binaries/darwin/localstack ./binaries/darwin/localstack-darwin-arm && rm localstack-cli-darwin-arm64-onefile.tar.gz

mkdir ./binaries/windows
unzip localstack-cli-windows-amd64-onefile.zip -d ./binaries/windows && mv ./binaries/windows/localstack.exe ./binaries/windows/localstack-windows-amd.exe && rm localstack-cli-windows-amd64-onefile.zip

15 changes: 15 additions & 0 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,23 @@
"darwin": [
{
"path": "/darwin/checkUser.sh"
},
{
"path": "/darwin/localstack-darwin-amd"
},
{
"path": "/darwin/localstack-darwin-arm"
}
],
"linux": [
{
"path": "/linux/checkUser.sh"
},
{
"path": "/linux/localstack-linux-amd"
},
{
"path": "/linux/localstack-linux-arm"
}
],
"windows": [
Expand All @@ -35,6 +47,9 @@
},
{
"path": "/windows/checkUser.cmd"
},
{
"path": "/windows/localstack-windows-amd.exe"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface DownloadProgressProps {

export const DownloadProgress = ({ callback, imageName }: DownloadProgressProps): ReactElement => {

const ddClient = useDDClient();
const { client: ddClient } = useDDClient();
const [statusMap, setStatusMap] = useState<Map<string, string>>(new Map());
const [isDone, setIsDone] = useState<boolean>(false);
const percentage = Array.from(statusMap.entries())
Expand Down
59 changes: 28 additions & 31 deletions ui/src/components/Header/Controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ import {
} from '../../services';
import {
DEFAULT_CONFIGURATION_ID,
FLAGS,
PRO_IMAGE,
COMMUNITY_IMAGE,
FLAGS_AS_STRING,
} from '../../constants';
import { LongMenu } from './Menu';
import { DockerContainer, DockerImage } from '../../types';
import { DownloadProgressDialog } from '../Feedback/DownloadProgressDialog';
import { ProgressButton } from '../Feedback';
import { generateCLIArgs } from '../../services/util/cli';

const EXCLUDED_ERROR_TOAST = ['INFO', 'WARN', 'DEBUG'];

Expand All @@ -31,7 +30,7 @@ export const Controller = (): ReactElement => {
const [downloadProps, setDownloadProps] = useState({ open: false, image: COMMUNITY_IMAGE });
const [isStarting, setIsStarting] = useState<boolean>(false);
const [isStopping, setIsStopping] = useState<boolean>(false);
const ddClient = useDDClient();
const { client: ddClient, getBinary } = useDDClient();
const isRunning = data && data.State === 'running';
const isUnhealthy = data && data.Status.includes('unhealthy');
const tooltipLabel = isUnhealthy ? 'Unhealthy' : 'Healthy';
Expand All @@ -48,52 +47,44 @@ export const Controller = (): ReactElement => {
}
}, [isLoading]);

const buildHostArgs = () => {
let location = 'LOCALSTACK_VOLUME_DIR=/tmp/localstack/volume';
let homeDir = `HOME=/home/${user}`;
const buildHostArgs = (): NodeJS.ProcessEnv => {
let location = '/tmp/localstack/volume';

if (!hasSkippedConfiguration) {
switch (ddClient.host.platform) {
case 'win32':
location = `LOCALSTACK_VOLUME_DIR=\\\\wsl$\\${os}\\home\\${user}\\.cache\\localstack\\volume`;
homeDir = `HOME=\\\\wsl$\\${os}\\home\\${user}`;
location = `\\\\wsl$\\${os}\\home\\${user}\\.cache\\localstack\\volume`;
break;
case 'darwin':
location = `LOCALSTACK_VOLUME_DIR=/Users/${user}/Library/Caches/localstack/volume`;
homeDir = `HOME=/Users/${user}`;
location = `/Users/${user}/Library/Caches/localstack/volume`;
break;
default:
location = `LOCALSTACK_VOLUME_DIR=/home/${user}/.cache/localstack/volume`;
homeDir = `HOME=/home/${user}`;
location = `/home/${user}/.cache/localstack/volume`;
}
}
return ['-e', location, '-e', homeDir];
return { LOCALSTACK_VOLUME_DIR: location };
};

const normalizeArguments = async () => {
const extendedFlag = FLAGS.map(x => x); // clone
let isPro = false;
const normalizeArguments = (): NodeJS.ProcessEnv => {
const addedArgs = configData.configs.find(config => config.id === runningConfig)
.vars.map(item => {
if (item.variable === 'DOCKER_FLAGS') {
extendedFlag[1] = FLAGS.at(1).slice(0, -1).concat(` ${item.value}'`);
}
if (item.variable === 'LOCALSTACK_AUTH_TOKEN') {
isPro = true;
return { [item.variable]: `${FLAGS_AS_STRING} ${item.value}` };
}

return ['-e', `${item.variable}=${item.value}`];
}).flat();
return { [item.variable]: item.value };
});

return [
...extendedFlag,
...buildHostArgs(),
...addedArgs,
...generateCLIArgs({ call: 'start', pro: isPro }),
];
return [...addedArgs, buildHostArgs()].reduce((acc, obj) => {
const [key, value] = Object.entries(obj)[0];
acc[key] = value;
return acc;
}, {} as NodeJS.ProcessEnv);
};

const start = async () => {
setIsStarting(true);

const images = await ddClient.docker.listImages() as [DockerImage];

const isPro = configData.configs.find(config => config.id === runningConfig)
Expand All @@ -112,10 +103,16 @@ export const Controller = (): ReactElement => {
return;
}

const args = await normalizeArguments();
const args = normalizeArguments();

const binary = getBinary();
if (!binary) {
setIsStarting(false);
return;
}

setIsStarting(true);
ddClient.docker.cli.exec('run', args, {
ddClient.extension.host?.cli.exec(binary, ['start', '--no-banner', '-d'], {
env: args,
stream: {
onOutput(data): void {
const shouldDisplayError = !EXCLUDED_ERROR_TOAST.some(item => data.stderr?.includes(item)) && data.stderr;
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useDDClient } from '../../services';
import { Controller } from './Controller';

export const Header = (): ReactElement => {
const ddClient = useDDClient();
const { client: ddClient } = useDDClient();

return (
<AppBar
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/Header/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const LongMenu = () => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [openModal, setOpenModal] = useState<boolean>(false);
const [images, setImages] = useState<string[]>(['Loading...']);
const ddClient = useDDClient();
const { client: ddClient } = useDDClient();

const open = Boolean(anchorEl);

Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/Views/Configs/SettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const SettingsForm = ({ initialState }: MountPointFormProps): ReactElemen
const [activeStep, setActiveStep] = useState(initialState);

const { setMountPointData, user, os } = useMountPoint();
const ddClient = useDDClient();
const { client: ddClient } = useDDClient();

const steps = ['Enable Docker Desktop option', 'Launching pro container', 'Set mount point'];

Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/Views/Logs/LogsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useDDClient, useLocalStack } from '../../../services';

export const LogsPage = (): ReactElement => {
const [logs, setLogs] = useState<string[]>([]);
const ddClient = useDDClient();
const { client: ddClient } = useDDClient();
const { data } = useLocalStack();

useEffect(() => {
Expand Down
11 changes: 7 additions & 4 deletions ui/src/components/Views/Update/UpdateDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from '@mui/material';
import React, { ReactElement, useEffect, useState } from 'react';
import { useDDClient } from '../../../services';
import { generateCLIArgs } from '../../../services/util/cli';

type Props = {
open: boolean,
Expand All @@ -16,19 +15,23 @@ type Props = {

export const UpdateDialog = ({ open, onClose }: Props): ReactElement => {
const [logs, setLogs] = useState<string[]>([]);
const ddClient = useDDClient();
const { client: ddClient, getBinary } = useDDClient();
const [isUpdating, setIsUpdating] = useState<boolean>(true);

useEffect(() => {
const listener = ddClient.docker.cli.exec('run', generateCLIArgs({ call: 'update' }), {
const binary = getBinary();
if (!binary) {
return;
}
const listener = ddClient.extension.host?.cli.exec(binary, ['update', 'docker-images'], {
stream: {
onOutput(data): void {
let resultStr = data.stdout
.replaceAll('─', '')
.replaceAll('✔', '✅')
.replaceAll('✖', '❌');

if (data.stdout.includes('Updating docker images')) {
if (resultStr.includes('Updating docker images')) {
resultStr = 'Updating Docker images';
}

Expand Down
38 changes: 2 additions & 36 deletions ui/src/constants/docker.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,2 @@
import { PRO_IMAGE, COMMUNITY_IMAGE } from './common';

export const COMMON_ARGS = [
'--label',
'cloud.localstack.spawner=true',
'--rm',
'-i',
'--entrypoint=',
'-v',
'/var/run/docker.sock:/var/run/docker.sock',
];

export const PRO_CLI = [
PRO_IMAGE,
'./.venv/bin/python3',
'-m',
'localstack.cli.main',
];

export const COMMUNITY_CLI = [COMMUNITY_IMAGE, 'bin/localstack'];

export const START_ARGS = [
'start',
'-d',
];

export const UPDATE_ARGS = [
'update',
'docker-images',
];

export const FLAGS = [
'-e',
// eslint-disable-next-line max-len
'DOCKER_FLAGS=--label com.docker.compose.project=localstack_localstack-docker-desktop-desktop-extension --label com.docker.desktop.extension=true --label com.docker.compose.project.config_files',
];
// eslint-disable-next-line max-len
export const FLAGS_AS_STRING = '--label com.docker.compose.project=localstack_localstack-docker-desktop-desktop-extension --label com.docker.desktop.extension=true --label com.docker.compose.project.config_files';
6 changes: 3 additions & 3 deletions ui/src/services/hooks/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const adaptVersionData = (data: HTTPMessageBody, error: Error) => {

export const useRunConfigs = (): useRunConfigsReturn => {
const cacheKey = STORAGE_KEY_ENVVARS;
const ddClient = useDDClient();
const { client: ddClient } = useDDClient();
const { data, mutate, isValidating, error } = useSWR(
cacheKey,
() => (ddClient.extension.vm.service.get('/configs') as Promise<HTTPMessageBody>),
Expand Down Expand Up @@ -78,7 +78,7 @@ interface useMountPointReturn {
}

export const useMountPoint = (): useMountPointReturn => {
const ddClient = useDDClient();
const { client: ddClient } = useDDClient();
const cacheKey = STORAGE_KEY_MOUNT;

const { data, mutate, isValidating, error } = useSWR(
Expand Down Expand Up @@ -111,7 +111,7 @@ interface useLocalStackReturn {
}

export const useLocalStack = (): useLocalStackReturn => {
const ddClient = useDDClient();
const { client: ddClient } = useDDClient();
const cacheKey = STORAGE_KEY_LOCALSTACK;

const { data, mutate } = useSWR(
Expand Down
Loading