Build volume test images on Windows

* Adds Windows dockerfile for volume-ownership image
  * Build volume-copy-up on Windows
  * Adds a helper tool that fetches the owner username and SID of
a file or folder
  * Adds README
  * Remove 2004 from Windows versions
  * Add ltsc2022 to Windows versions

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2021-11-16 17:37:48 +02:00
parent 0a284fcdbc
commit 1698d061c3
6 changed files with 361 additions and 56 deletions

View File

@ -0,0 +1,127 @@
# Test image overview
Test images for Linux can be built as usual using buildx.
While it is possible to build Windows docker images on Linux (if we avoid the ```RUN``` or ```WORKDIR``` options), the ```volume-ownership``` and ```volume-copy-up``` images need to be built on Windows for the tests to be relevant. The reason for this is that when building images on Linux, Windows specific security info (DACL and ownership) does not get attached to the test files and folders inside the image. The ```TestVolumeCopyUp``` and ```TestVolumeOwnership``` tests will not be relevant, as owners of the files will always be ```ContainerAdministrator```.
Building images on Windows nodes also allows us to potentially add new users inside the images or enable new testing scenarios that require different services or applications to run inside the container.
This document describes the needed bits to build the Windows container images on a remote Windows node.
## Setting up the Windows build node
We can build images for all relevant Windows versions on a single Windows node as long as that Windows node is a version greater or equal to the image versions we're trying to build. For example, on a Windows Server 2022 node, we can build images for 1809, 2004, 20H2 and ltsc2022, while if we were running on Windows server 2019 machine, we would only be able to generate images for 1809. To build images for different versions of Windows, we need to enable the ```Hyper-V``` role, and use ```--isolation=hyperv``` as an argument to docker build.
Note, this will also work if nested hyperv is enabled. This means that the images can be built on Azure (nested Hyper-V is enabled by default), or on any modern linux machine using KVM and libvirt.
Note, at the time of this writing, the recommended version to build on is Windows Server 2022 (ltsc2022).
### Enabling nested VMX on Libvirt
To enable nested Hyper-V on libvirt, simply install Windows Server 2022 as usual, then shutdown the guest and edit it's config:
```bash
# replace win2k22 with the name of your Windows VM
virsh edit win2k22
```
and add/edit the CPU section to look like this:
```xml
<cpu mode='custom' match='exact' check='partial'>
<model fallback='allow'>Broadwell</model>
<feature policy='require' name='vmx'/>
</cpu>
```
Hyper-V should now work inside your KVM machine. It's not terribly fast, but it should suffice for building images.
### Enable necessary roles
Install the needed roles and tools:
```powershell
# Enable Hyper-V and management tools
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V,Microsoft-Hyper-V-Management-Clients,Microsoft-Hyper-V-Management-PowerShell -All -NoRestart
# Enable SSH (this can be skipped if you don't need it)
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# Install Docker
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$false
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force -Confirm:$false
Install-Package -Name docker -ProviderName DockerMsftProvider -Force -Confirm:$false
```
At this point we can reboot for the changes to take effect:
```powershell
Restart-Computer -Force
```
### Configure needed services
Start sshd and enable it to run on startup:
```powershell
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'
```
Open Firewall port for ssh:
```powershell
New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
```
These following steps are taken from the [k8s windows image builder helper page](https://github.com/kubernetes/kubernetes/blob/master/test/images/windows/README.md).
Enable TLS authentication for docker and enable remote access:
```powershell
# Replace YOUR_SERVER_IP_GOES_HERE with the IP addresses you'll use to access
# this node. This will be the private IP and VIP/Floating IP of the server.
docker run --isolation=hyperv --user=ContainerAdministrator --rm `
-e SERVER_NAME=$(hostname) `
-e IP_ADDRESSES=127.0.0.1,YOUR_SERVER_IP_GOES_HERE `
-v "c:\programdata\docker:c:\programdata\docker" `
-v "$env:USERPROFILE\.docker:c:\users\containeradministrator\.docker" stefanscherer/dockertls-windows:2.5.5
```
Restart Docker:
```powershell
Stop-Service docker
Start-Service docker
```
After this, the files (```ca.pem```, ```cert.pem``` and ```key.pem```) needed to authenticate to docker will be present in ```$env:USERPROFILE\.docker``` on the Windows machine. You will need to copy those files to your linux machine in ```$HOME/.docker```. They are needed in order to authenticate against the Windows docker daemon during our image build process.
Open Firewall port for docker:
```powershell
New-NetFirewallRule -Name 'Docker-TLS-In-TCP' -DisplayName 'Docker (TLS)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 2376
```
Note, if you're running in a cloud, make sure you also open the port in your NSG/Security group.
## Building the images
With the above mentioned files copied to ```$HOME/.docker``` we can now start building the images:
```bash
git clone https://github.com/containerd/containerd
cd containerd/integration/images/volume-copy-up
make setup-buildx
make configure-docker
# 192.168.122.107 corresponds to the IP address of your windows build node.
# This builds the images and pushes them to the registry specified by PROJ
# The Windows images will be built on the Windows node and pushed from there.
# You will need to make sure that docker is configured and able to push to the
# project you want to push to.
make build-registry PROJ=docker.example.com REMOTE_DOCKER_URL=192.168.122.107:2376
# Create a manifest and update it with all supported operating systems and architectures.
make push-manifest PROJ=docker.samfira.com REMOTE_DOCKER_URL=192.168.122.107:2376
```

View File

@ -1,11 +1,11 @@
# Copyright The containerd Authors. # Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -13,30 +13,22 @@
# limitations under the License. # limitations under the License.
ARG BASE ARG BASE
FROM --platform=linux/amd64 busybox as prep
# Similar to: https://github.com/kubernetes/kubernetes/blob/7ad7c0757ac7fa37dfae9c7cdc628cf04e35e5cb/test/images/busybox/Dockerfile_windows
# Available busybox functions retrieved by running busybox.exe --list
ENV BUSYBOX_EXES="[ [[ ar arch ash awk base64 basename bash bunzip2 bzcat bzip2 cal cat chmod cksum clear cmp comm cp cpio cut date dc dd df diff dirname dos2unix dpkg-deb du echo ed egrep env expand expr factor false fgrep find fold fsync ftpget ftpput getopt grep groups gunzip gzip hd head hexdump id ipcalc kill killall less link ln logname ls lzcat lzma lzop lzopcat man md5sum mkdir mktemp mv nl od paste patch pgrep pidof pipe_progress pkill printenv printf ps pwd rev rm rmdir rpm rpm2cpio sed seq sh sha1sum sha256sum sha3sum sha512sum shred shuf sleep sort split ssl_client stat strings sum tac tail tar tee test timeout touch tr true truncate ttysize uname uncompress unexpand uniq unix2dos unlink unlzma unlzop unxz unzip usleep uudecode uuencode vi watch wc wget which whoami whois xargs xxd xz xzcat yes zcat"
ADD https://github.com/kubernetes-sigs/windows-testing/raw/master/images/busybox/busybox.exe /busybox-dir/busybox.exe
# NOTE(claudiub): We're creating symlinks for each of the busybox binaries and after that we're copying
# # them over to Windows. Unfortunately, docker buildx has some issues copying over Windows symlinks.
# # "Files/" is always prepended to the symlink target. The symlinks themselves are relative paths,
# # so, in order to make use of them, we can simply add a busybox binary to Files\busybox.exe.
RUN cd /busybox-dir/ && \
for busybox_binary in $BUSYBOX_EXES; do ln -s busybox.exe $busybox_binary.exe; done && \
mkdir Files && \
cp busybox.exe Files/busybox.exe
RUN sh -c "mkdir /test_dir; echo test_content > /test_dir/test_file"
FROM $BASE FROM $BASE
COPY --from=prep /busybox-dir /bin ADD https://github.com/kubernetes-sigs/windows-testing/raw/3fea3d48ea8337b2aaca755c1d719e34b45f46b9/images/busybox/busybox.exe /bin/busybox.exe
COPY --from=prep /test_dir /test_dir
ENV BUSYBOX_EXES="[ [[ ar arch ash awk base64 basename bash bunzip2 bzcat bzip2 cal cat chmod cksum clear cmp comm cp cpio cut date dc dd df diff dirname dos2unix dpkg-deb du echo ed egrep env expand e xpr factor false fgrep find fold fsync ftpget ftpput getopt grep groups gunzip gzip hd head hexdump id ipcalc kill killall less link ln logname ls lzcat lzma lzop lzopcat man md5sum mkdir mktemp mv nl od paste patch pgrep pidof pipe_progress pkill printenv printf ps pwd rev rm rmdir rpm rpm2cpio sed seq sh sha1sum sha256sum sha3sum sha512sum shred shuf sleep sort split ssl_client stat strings sum ta c tail tar tee test timeout touch tr true truncate ttysize uname uncompress unexpand uniq unix2dos unlink unlzma unlzop unxz unzip usleep uudecode uuencode vi watch wc wget which whoami whois xargs xxd xz xzcat yes zcat"
USER ContainerAdministrator
WORKDIR C:/bin
RUN cmd.exe /c "@echo off && FOR %i in (%BUSYBOX_EXES%) do (mklink %i.exe busybox.exe)"
USER ContainerUser
RUN cmd.exe /c mkdir C:\test_dir
RUN /bin/sh.exe -c "echo test_content > /test_dir/test_file"
ENV PATH="C:\bin;C:\Windows\System32;C:\Windows;" ENV PATH="C:\bin;C:\Windows\System32;C:\Windows;"
VOLUME "/test_dir" VOLUME "C:/test_dir"

View File

@ -17,33 +17,50 @@ all: build
PROJ=gcr.io/k8s-cri-containerd PROJ=gcr.io/k8s-cri-containerd
VERSION=2.1 VERSION=2.1
IMAGE=$(PROJ)/volume-copy-up:$(VERSION) IMAGE=$(PROJ)/volume-copy-up:$(VERSION)
DOCKER_CERT_PATH ?= "$(HOME)/.docker"
REMOTE_DOCKER_URL ?=
DOCKER_REMOTE_ARGS ?=
ifneq ($(REMOTE_DOCKER_URL),)
DOCKER_REMOTE_ARGS = --tlsverify --tlscacert "$(DOCKER_CERT_PATH)/ca.pem" \
--tlscert "$(DOCKER_CERT_PATH)/cert.pem" \
--tlskey "$(DOCKER_CERT_PATH)/key.pem" \
-H "$(REMOTE_DOCKER_URL)"
endif
# Operating systems supported: linux, windows # Operating systems supported: linux, windows
OS ?= linux OS ?= linux
# Architectures supported: amd64, arm64 # Architectures supported: amd64, arm64
ARCH ?= amd64 ARCH ?= amd64
# OS Version for the Windows images: 1809, 2004, 20H2 # OS Version for the Windows images: 1809, 20H2, ltsc2022
OSVERSION ?= 1809 OSVERSION ?= 1809
# The output type could either be docker (local), or registry. # The output type could either be docker (local), or registry.
# If it is registry, it will also allow us to push the Windows images. # If it is registry, it will also allow us to push the Windows images.
OUTPUT_TYPE ?= docker OUTPUT_TYPE ?= docker
ALL_OS = linux windows ALL_OS = linux
ALL_ARCH.linux = amd64 arm64 ALL_ARCH.linux = amd64 arm64
ALL_OS_ARCH.linux = $(foreach arch, ${ALL_ARCH.linux}, linux-$(arch)) ALL_OS_ARCH.linux = $(foreach arch, ${ALL_ARCH.linux}, linux-$(arch))
ALL_OSVERSIONS.windows := 1809 2004 20H2
ifneq ($(REMOTE_DOCKER_URL),)
ALL_OS += windows
ALL_OSVERSIONS.windows := 1809 20H2 ltsc2022
ALL_OS_ARCH.windows = $(foreach osversion, ${ALL_OSVERSIONS.windows}, windows-amd64-${osversion}) ALL_OS_ARCH.windows = $(foreach osversion, ${ALL_OSVERSIONS.windows}, windows-amd64-${osversion})
ALL_OS_ARCH = $(foreach os, $(ALL_OS), ${ALL_OS_ARCH.${os}}) BASE.windows := mcr.microsoft.com/windows/nanoserver
endif
BASE.linux.amd64 := busybox BASE.linux.amd64 := busybox
BASE.linux.arm64 := arm64v8/busybox BASE.linux.arm64 := arm64v8/busybox
BASE.linux := ${BASE.linux.${ARCH}} BASE.linux := ${BASE.linux.${ARCH}}
BASE.windows := mcr.microsoft.com/windows/nanoserver
BASE := ${BASE.${OS}} BASE := ${BASE.${OS}}
ALL_OS_ARCH = $(foreach os, $(ALL_OS), ${ALL_OS_ARCH.${os}})
configure-docker: configure-docker:
gcloud auth configure-docker gcloud auth configure-docker --quiet
gcloud auth configure-docker --quiet $(shell echo $(PROJ) | cut -f 1 -d "/") || true
setup-buildx: setup-buildx:
docker buildx use img-builder || docker buildx create --name img-builder --use docker buildx use img-builder || docker buildx create --name img-builder --use
@ -67,9 +84,10 @@ container: .container-${OS}-$(ARCH)
-t $(IMAGE)-${OS}-${ARCH} --build-arg BASE=${BASE} . -t $(IMAGE)-${OS}-${ARCH} --build-arg BASE=${BASE} .
.container-windows-$(ARCH): .container-windows-$(ARCH):
docker buildx build --pull --output=type=${OUTPUT_TYPE} --platform ${OS}/${ARCH} \ docker $(DOCKER_REMOTE_ARGS) build --isolation=hyperv --no-cache --pull \
-t $(IMAGE)-${OS}-${ARCH}-${OSVERSION} --build-arg BASE=${BASE}:${OSVERSION} \ -t $(IMAGE)-${OS}-${ARCH}-${OSVERSION} --build-arg BASE=${BASE}:${OSVERSION} \
-f Dockerfile_windows . -f Dockerfile_windows .
docker $(DOCKER_REMOTE_ARGS) push $(IMAGE)-${OS}-${ARCH}-${OSVERSION}
# For Windows images, we also need to include the "os.version" in the manifest list images, # For Windows images, we also need to include the "os.version" in the manifest list images,
# so the Windows node can pull the proper image it needs. # so the Windows node can pull the proper image it needs.
@ -80,7 +98,8 @@ push-manifest:
set -x; \ set -x; \
for osversion in ${ALL_OSVERSIONS.windows}; do \ for osversion in ${ALL_OSVERSIONS.windows}; do \
full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \ full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \
docker manifest annotate --os windows --arch amd64 --os-version $${full_version} ${IMAGE} ${IMAGE}-windows-amd64-$${osversion}; \ docker manifest annotate --os windows --arch amd64 --os-version $${full_version} \
${IMAGE} ${IMAGE}-windows-amd64-$${osversion}; \
done done
docker manifest push --purge ${IMAGE} docker manifest push --purge ${IMAGE}

View File

@ -0,0 +1,36 @@
# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
ARG BASE
FROM $BASE
ADD https://github.com/kubernetes-sigs/windows-testing/raw/3fea3d48ea8337b2aaca755c1d719e34b45f46b9/images/busybox/busybox.exe /bin/busybox.exe
ENV BUSYBOX_EXES="[ [[ ar arch ash awk base64 basename bash bunzip2 bzcat bzip2 cal cat chmod cksum clear cmp comm cp cpio cut date dc dd df diff dirname dos2unix dpkg-deb du echo ed egrep env expand e xpr factor false fgrep find fold fsync ftpget ftpput getopt grep groups gunzip gzip hd head hexdump id ipcalc kill killall less link ln logname ls lzcat lzma lzop lzopcat man md5sum mkdir mktemp mv nl od paste patch pgrep pidof pipe_progress pkill printenv printf ps pwd rev rm rmdir rpm rpm2cpio sed seq sh sha1sum sha256sum sha3sum sha512sum shred shuf sleep sort split ssl_client stat strings sum ta c tail tar tee test timeout touch tr true truncate ttysize uname uncompress unexpand uniq unix2dos unlink unlzma unlzop unxz unzip usleep uudecode uuencode vi watch wc wget which whoami whois xargs xxd xz xzcat yes zcat"
USER ContainerAdministrator
WORKDIR C:/bin
ADD tools/get_owner_windows.exe C:/bin/get_owner.exe
RUN cmd.exe /c "@echo off && FOR %i in (%BUSYBOX_EXES%) do (mklink %i.exe busybox.exe)"
RUN cmd.exe /c mkdir C:\volumes
USER ContainerUser
RUN mkdir C:\volumes\test_dir
RUN /bin/sh.exe -c "echo test_content > /volumes/test_dir/test_file"
ENV PATH="C:\bin;C:\Windows\System32;C:\Windows;"
VOLUME "C:/volumes/test_dir"

View File

@ -15,20 +15,98 @@
all: build all: build
PROJ=gcr.io/k8s-cri-containerd PROJ=gcr.io/k8s-cri-containerd
VERSION=2.0 VERSION=2.1
IMAGE=$(PROJ)/volume-ownership:$(VERSION) IMAGE=$(PROJ)/volume-ownership:$(VERSION)
PLATFORMS?=linux/amd64,linux/arm64 DOCKER_CERT_PATH ?= "$(HOME)/.docker"
REMOTE_DOCKER_URL ?=
DOCKER_REMOTE_ARGS ?=
ifneq ($(REMOTE_DOCKER_URL),)
DOCKER_REMOTE_ARGS = --tlsverify --tlscacert "$(DOCKER_CERT_PATH)/ca.pem" \
--tlscert "$(DOCKER_CERT_PATH)/cert.pem" \
--tlskey "$(DOCKER_CERT_PATH)/key.pem" \
-H "$(REMOTE_DOCKER_URL)"
endif
# Operating systems supported: linux, windows
OS ?= linux
# Architectures supported: amd64, arm64
ARCH ?= amd64
# OS Version for the Windows images: 1809, 20H2, ltsc2022
OSVERSION ?= 1809
# The output type could either be docker (local), or registry.
# If it is registry, it will also allow us to push the Windows images.
OUTPUT_TYPE ?= docker
ALL_OS = linux
ALL_ARCH.linux = amd64 arm64
ALL_OS_ARCH.linux = $(foreach arch, ${ALL_ARCH.linux}, linux-$(arch))
ifneq ($(REMOTE_DOCKER_URL),)
ALL_OS += windows
ALL_OSVERSIONS.windows := 1809 20H2 ltsc2022
ALL_OS_ARCH.windows = $(foreach osversion, ${ALL_OSVERSIONS.windows}, windows-amd64-${osversion})
BASE.windows := mcr.microsoft.com/windows/nanoserver
endif
BASE.linux.amd64 := busybox
BASE.linux.arm64 := arm64v8/busybox
BASE.linux := ${BASE.linux.${ARCH}}
BASE := ${BASE.${OS}}
ALL_OS_ARCH = $(foreach os, $(ALL_OS), ${ALL_OS_ARCH.${os}})
configure-docker: configure-docker:
gcloud auth configure-docker gcloud auth configure-docker --quiet
gcloud auth configure-docker --quiet $(shell echo $(PROJ) | cut -f 1 -d "/") || true
build: setup-buildx:
docker buildx build \ docker buildx use img-builder || docker buildx create --name img-builder --use
$(OUTPUT) \
--platform=${PLATFORMS} \
--tag $(IMAGE) .
push: OUTPUT=--push build: setup-buildx build-local
push: configure-docker build
.PHONY: configure-docker build push push: configure-docker setup-buildx build-registry push-manifest
build-local: $(addprefix sub-container-docker-,$(ALL_OS_ARCH.linux))
build-tools:
GOOS=windows go build -mod=vendor -o tools/get_owner_windows.exe tools/get_owner_windows.go
clean-tools:
rm -f tools/get_owner_windows.exe || true
build-registry: build-tools $(addprefix sub-container-registry-,$(ALL_OS_ARCH)) clean-tools
# split words on hyphen, access by 1-index
word-hyphen = $(word $2,$(subst -, ,$1))
sub-container-%:
$(MAKE) OUTPUT_TYPE=$(call word-hyphen,$*,1) OS=$(call word-hyphen,$*,2) ARCH=$(call word-hyphen,$*,3) OSVERSION=$(call word-hyphen,$*,4) container
container: .container-${OS}-$(ARCH)
.container-linux-$(ARCH):
docker buildx build --pull --output=type=${OUTPUT_TYPE} --platform ${OS}/${ARCH} \
-t $(IMAGE)-${OS}-${ARCH} --build-arg BASE=${BASE} .
.container-windows-$(ARCH):
docker $(DOCKER_REMOTE_ARGS) build --isolation=hyperv --no-cache --pull \
-t $(IMAGE)-${OS}-${ARCH}-${OSVERSION} --build-arg BASE=${BASE}:${OSVERSION} \
-f Dockerfile_windows .
docker $(DOCKER_REMOTE_ARGS) push $(IMAGE)-${OS}-${ARCH}-${OSVERSION}
# For Windows images, we also need to include the "os.version" in the manifest list images,
# so the Windows node can pull the proper image it needs.
push-manifest:
docker manifest create --amend $(IMAGE) $(shell echo $(ALL_OS_ARCH) | sed -e "s~[^ ]*~$(IMAGE)\-&~g")
set -x; for arch in $(ALL_ARCH.linux); do docker manifest annotate --os linux --arch $${arch} ${IMAGE} ${IMAGE}-linux-$${arch}; done
# we use awk to also trim the quotes around the OS version string.
set -x; \
for osversion in ${ALL_OSVERSIONS.windows}; do \
full_version=`docker manifest inspect ${BASE.windows}:$${osversion} | grep "os.version" | head -n 1 | awk -F\" '{print $$4}'` || true; \
docker manifest annotate --os windows --arch amd64 --os-version $${full_version} \
${IMAGE} ${IMAGE}-windows-amd64-$${osversion}; \
done
docker manifest push --purge ${IMAGE}
.PHONY: configure-docker setup-buildx build push build-local build-registry container push-manifest clean-tools

View File

@ -0,0 +1,53 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"log"
"os"
"golang.org/x/sys/windows"
)
func main() {
if len(os.Args) != 2 {
fmt.Printf("Usage: %s file_or_directory\n", os.Args[0])
os.Exit(1)
}
if _, err := os.Stat(os.Args[1]); err != nil {
log.Fatal(err)
}
secInfo, err := windows.GetNamedSecurityInfo(
os.Args[1], windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION)
if err != nil {
log.Fatal(err)
}
sid, _, err := secInfo.Owner()
if err != nil {
log.Fatal(err)
}
acct, _, _, err := sid.LookupAccount(".")
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s:%s", acct, sid)
}